fix(accordion): variants for nested accordions (#3291)

* feat(accordion): add data-variant

* fix(theme): revise accordion styles for variants

* feat(changeset): add changeset

* chore(theme): rollback content padding

* chore(accordion): abandon data-group approach

* refactor(theme): pass variant to accordionItem

* refactor(accordion): pass variant to accordionItem

* fix(accordion): revise accordion variants

* refactor(accordion): refine transitionVariants
This commit is contained in:
աӄա 2024-06-22 21:44:19 +08:00 committed by GitHub
parent 773f3004a6
commit e9a6a162e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 31 additions and 12 deletions

View File

@ -0,0 +1,6 @@
---
"@nextui-org/accordion": patch
"@nextui-org/theme": patch
---
Fixed variants for nested accordions (#3285)

View File

@ -1,3 +1,5 @@
import type {Variants} from "framer-motion";
import {forwardRef} from "@nextui-org/system"; import {forwardRef} from "@nextui-org/system";
import {useMemo, ReactNode} from "react"; import {useMemo, ReactNode} from "react";
import {ChevronIcon} from "@nextui-org/shared-icons"; import {ChevronIcon} from "@nextui-org/shared-icons";
@ -53,6 +55,11 @@ const AccordionItem = forwardRef<"button", AccordionItemProps>((props, ref) => {
return <div {...getContentProps()}>{children}</div>; return <div {...getContentProps()}>{children}</div>;
} }
const transitionVariants: Variants = {
exit: {...TRANSITION_VARIANTS.collapse.exit, overflowY: "hidden"},
enter: {...TRANSITION_VARIANTS.collapse.enter, overflowY: "unset"},
};
return keepContentMounted ? ( return keepContentMounted ? (
<LazyMotion features={domAnimation}> <LazyMotion features={domAnimation}>
<m.section <m.section
@ -60,8 +67,8 @@ const AccordionItem = forwardRef<"button", AccordionItemProps>((props, ref) => {
animate={isOpen ? "enter" : "exit"} animate={isOpen ? "enter" : "exit"}
exit="exit" exit="exit"
initial="exit" initial="exit"
style={{overflowY: "hidden", willChange}} style={{willChange}}
variants={TRANSITION_VARIANTS.collapse} variants={transitionVariants}
{...motionProps} {...motionProps}
> >
<div {...getContentProps()}>{children}</div> <div {...getContentProps()}>{children}</div>
@ -76,8 +83,8 @@ const AccordionItem = forwardRef<"button", AccordionItemProps>((props, ref) => {
animate="enter" animate="enter"
exit="exit" exit="exit"
initial="exit" initial="exit"
style={{overflowY: "hidden", willChange}} style={{willChange}}
variants={TRANSITION_VARIANTS.collapse} variants={transitionVariants}
{...motionProps} {...motionProps}
> >
<div {...getContentProps()}>{children}</div> <div {...getContentProps()}>{children}</div>

View File

@ -36,6 +36,7 @@ const AccordionGroup = forwardRef<"div", AccordionProps>((props, ref) => {
<Fragment key={item.key}> <Fragment key={item.key}>
<AccordionItem <AccordionItem
item={item} item={item}
variant={props.variant}
onFocusChange={handleFocusChanged} onFocusChange={handleFocusChanged}
{...values} {...values}
{...item.props} {...item.props}

View File

@ -1,3 +1,5 @@
import type {AccordionItemVariantProps} from "@nextui-org/theme";
import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system"; import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {accordionItem} from "@nextui-org/theme"; import {accordionItem} from "@nextui-org/theme";
@ -36,6 +38,7 @@ export interface Props<T extends object> extends HTMLNextUIProps<"div"> {
} }
export type UseAccordionItemProps<T extends object = {}> = Props<T> & export type UseAccordionItemProps<T extends object = {}> = Props<T> &
AccordionItemVariantProps &
Omit<AccordionItemBaseProps, "onFocusChange">; Omit<AccordionItemBaseProps, "onFocusChange">;
export function useAccordionItem<T extends object = {}>(props: UseAccordionItemProps<T>) { export function useAccordionItem<T extends object = {}>(props: UseAccordionItemProps<T>) {
@ -53,6 +56,7 @@ export function useAccordionItem<T extends object = {}>(props: UseAccordionItemP
startContent, startContent,
motionProps, motionProps,
focusedKey, focusedKey,
variant,
isCompact = false, isCompact = false,
classNames: classNamesProp = {}, classNames: classNamesProp = {},
isDisabled: isDisabledProp = false, isDisabled: isDisabledProp = false,
@ -125,8 +129,9 @@ export function useAccordionItem<T extends object = {}>(props: UseAccordionItemP
hideIndicator, hideIndicator,
disableAnimation, disableAnimation,
disableIndicatorAnimation, disableIndicatorAnimation,
variant,
}), }),
[isCompact, isDisabled, hideIndicator, disableAnimation, disableIndicatorAnimation], [isCompact, isDisabled, hideIndicator, disableAnimation, disableIndicatorAnimation, variant],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);

View File

@ -20,7 +20,7 @@ const accordion = tv({
light: "", light: "",
shadow: "px-4 shadow-medium rounded-medium bg-content1", shadow: "px-4 shadow-medium rounded-medium bg-content1",
bordered: "px-4 border-medium border-divider rounded-medium", bordered: "px-4 border-medium border-divider rounded-medium",
splitted: "group is-splitted flex flex-col gap-2", // the classNames are applied in the accordion-item component splitted: "flex flex-col gap-2",
}, },
fullWidth: { fullWidth: {
true: "w-full", true: "w-full",
@ -56,12 +56,7 @@ const accordion = tv({
*/ */
const accordionItem = tv({ const accordionItem = tv({
slots: { slots: {
base: [ base: "",
"group-[.is-splitted]:px-4",
"group-[.is-splitted]:bg-content1",
"group-[.is-splitted]:shadow-medium",
"group-[.is-splitted]:rounded-medium",
],
heading: "", heading: "",
trigger: [ trigger: [
"flex py-4 w-full h-full gap-3 outline-none items-center tap-highlight-transparent", "flex py-4 w-full h-full gap-3 outline-none items-center tap-highlight-transparent",
@ -76,6 +71,11 @@ const accordionItem = tv({
content: "py-2", content: "py-2",
}, },
variants: { variants: {
variant: {
splitted: {
base: "px-4 bg-content1 shadow-medium rounded-medium",
},
},
isCompact: { isCompact: {
true: { true: {
trigger: "py-2", trigger: "py-2",