Accordion updated

This commit is contained in:
Jonathan Summers-Muir committed 2023-05-21 21:11:38 +08:00
1 parent 980ca5d536
commit 34794e3565
5 files changed
+584 -309

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ const config: StorybookConfig = {
// // TODO: Temporally Import one by one story and fix build issue.
// // After all stories are cleaned, revert to wildcard import.
stories: [
// '../src/components/Accordion/Accordion.stories.tsx',
'../src/components/Accordion/Accordion.stories.tsx',
// '../src/components/Alert/Alert.stories.tsx',
// '../src/components/Avatar/Avatar.stories.tsx',
'../src/components/Button/Button.stories.tsx',
@@ -0,0 +1,166 @@
import React from 'react'
import Accordion, { AccordionProps } from './Accordion'
import { Badge } from '../Badge'
export default {
title: 'Displays/Accordion',
component: Accordion,
}
export const OneItem = (args: AccordionProps) => (
<Accordion {...args} justified={false}>
<Accordion.Item
header={
<>
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
<Badge>Test badge</Badge>
</>
}
id="first"
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
</Accordion>
)
export const MultipleItems = (args: AccordionProps) => (
<Accordion {...args} openBehaviour="multiple">
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'1'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'2'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'3'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'4'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
</Accordion>
)
export const Bordered = (args: AccordionProps) => (
<Accordion {...args}>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'1'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'2'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'3'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
}
id={'4'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
</Accordion>
)
Bordered.args = {
type: 'bordered',
}
export const LeftAlignedChevron = (args: AccordionProps) => (
<Accordion {...args} justified={false} chevronAlign="left">
<Accordion.Item
header={
<>
<span className="text-scale-900 group-hover:text-scale-1200">First item</span>
<Badge>Test badge</Badge>
</>
}
id="first"
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<>
<span className="text-scale-900 group-hover:text-scale-1200">Second item</span>
</>
}
id="second"
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</span>
</Accordion.Item>
</Accordion>
)
// export const withDefaultActive = Multiple.bind({})
// withDefaultActive.args = {
// defaultActiveId: [1],
// }
// export const withIconLeft = Multiple.bind({})
// withIconLeft.args = {
// iconPosition: 'left',
// }
// export const withCustomIcon = Multiple.bind({})
// withCustomIcon.args = {
// icon: <IconArrowUp />,
// }
@@ -0,0 +1,137 @@
import React, { createContext, useContext, useState } from 'react'
import styleHandler from '../../lib/theme/styleHandler'
import * as RadixAccordion from '@radix-ui/react-accordion'
import { IconChevronDown } from '../Icon/icons/IconChevronDown'
import { IconChevronUp } from '../Icon/icons/IconChevronUp'
type Type = 'default' | 'bordered'
type Size = 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
type Align = 'left' | 'right'
interface ContextValue {
bordered?: boolean
type: Type
justified: Boolean
chevronAlign: Align
}
const AccordionContext = createContext<ContextValue>({
chevronAlign: 'left',
justified: true,
type: 'default',
})
export interface AccordionProps {
children?: React.ReactNode
className?: string
onChange?: (item: string | string[]) => void
openBehaviour: 'single' | 'multiple'
type?: Type
defaultValue?: string | string[] | undefined
justified?: Boolean
chevronAlign?: Align
}
function Accordion({
children,
className,
onChange,
openBehaviour = 'multiple',
type = 'default',
defaultValue = undefined,
justified = false,
chevronAlign = 'left',
}: AccordionProps) {
const __styles = styleHandler('accordion')
let containerClasses = [__styles.variants[type].base]
if (className) {
containerClasses.push(className)
}
const contextValue = {
chevronAlign,
justified,
type,
defaultValue,
}
function handleOnChange(e: string | string[]) {
if (onChange) onChange(e)
const value = e == typeof String ? e.split(' ') : e
// setCurrentItems(e)
// console.log('about to change state')
// currentItems = e
// console.log('currentItems', currentItems)
}
return (
<>
<RadixAccordion.Root
type={openBehaviour}
onValueChange={handleOnChange}
defaultValue={defaultValue}
className={containerClasses.join(' ')}
children={
<AccordionContext.Provider value={{ ...contextValue }}>
<div>{children}</div>
</AccordionContext.Provider>
}
></RadixAccordion.Root>
</>
)
}
interface ItemProps {
children?: React.ReactNode
className?: string
header: React.ReactNode
id: string
icon?: React.ReactNode
disabled?: boolean
}
export function Item({ children, className, header, id, disabled }: ItemProps) {
const __styles = styleHandler('accordion')
const [open, setOpen] = useState(false)
const { type, justified, chevronAlign } = useContext(AccordionContext)
let triggerClasses = [__styles.variants[type].trigger]
if (justified) triggerClasses.push(__styles.justified)
if (className) triggerClasses.push(className)
let chevronClasses = [__styles.chevron.base, __styles.chevron.align[chevronAlign]]
if (open && !disabled) {
chevronClasses.unshift('!rotate-180')
}
return (
<RadixAccordion.Item
value={id}
className={__styles.variants[type].container}
disabled={disabled}
onClick={() => {
setOpen(!open)
}}
>
<RadixAccordion.Trigger className={triggerClasses.join(' ')}>
{header}
{!disabled && (
<IconChevronDown aria-hidden className={chevronClasses.join(' ')} strokeWidth={2} />
)}
</RadixAccordion.Trigger>
<RadixAccordion.Content className={__styles.variants[type].content}>
<div className={__styles.variants[type].panel}>{children}</div>
</RadixAccordion.Content>
</RadixAccordion.Item>
)
}
Accordion.Item = Item
export default Accordion
@@ -1,199 +1,79 @@
import React from 'react'
// Button.stories.ts|tsx
import Accordion, { AccordionProps } from './Accordion'
import type { Meta, StoryObj } from '@storybook/react'
import { Accordion, AccordionItem } from './Accordion'
import { Badge } from '../Badge'
export default {
title: 'Displays/Accordion',
const meta: Meta<typeof Accordion> = {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'General/Accordion',
component: Accordion,
}
export const OneItem = (args: AccordionProps) => (
<Accordion {...args} justified={false}>
<Accordion.Item
header={
<>
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
<Badge>Test badge</Badge>
</>
}
id="first"
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
</Accordion>
)
export default meta
export const MultipleItems = (args: AccordionProps) => (
<Accordion {...args} openBehaviour="multiple">
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'1'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'2'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'3'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'4'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
</Accordion>
)
type Story = StoryObj<typeof Accordion>
export const Bordered = (args: AccordionProps) => (
<Accordion {...args}>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'1'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'2'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'3'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<span className="text-scale-900 group-hover:text-scale-1200">
Title of the thing
</span>
}
id={'4'}
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
</Accordion>
)
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/react/api/csf
* to learn how to use render functions.
*/
Bordered.args = {
type: 'bordered',
export const Default = {
args: {
type: 'default',
},
render: ({ children, type }: any) => (
<Accordion type={type} openBehaviour="single" collapsible className="w-full">
<Accordion.Item value="item-1">
<Accordion.Trigger>
<span className="text-scale-900 group-hover:text-scale-1200">Title of the thing</span>
</Accordion.Trigger>
<Accordion.Content>Yes. It adheres to the WAI-ARIA design pattern.</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-2">
<Accordion.Trigger>Is it styled?</Accordion.Trigger>
<Accordion.Content>
Yes. It comes with default styles that matches the other components' aesthetic.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-3">
<Accordion.Trigger>Is it animated?</Accordion.Trigger>
<Accordion.Content>
Yes. It's animated by default, but you can disable it if you prefer.
</Accordion.Content>
</Accordion.Item>
</Accordion>
),
}
export const LeftAlignedChevron = (args: AccordionProps) => (
<Accordion {...args} justified={false} chevronAlign="left">
<Accordion.Item
header={
<>
<span className="text-scale-900 group-hover:text-scale-1200">
First item
</span>
<Badge>Test badge</Badge>
</>
}
id="first"
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
<Accordion.Item
header={
<>
<span className="text-scale-900 group-hover:text-scale-1200">
Second item
</span>
</>
}
id="second"
>
<span className="text-scale-900">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
amet labore.
</span>
</Accordion.Item>
</Accordion>
)
// export const withDefaultActive = Multiple.bind({})
// withDefaultActive.args = {
// defaultActiveId: [1],
// }
// export const withIconLeft = Multiple.bind({})
// withIconLeft.args = {
// iconPosition: 'left',
// }
// export const withCustomIcon = Multiple.bind({})
// withCustomIcon.args = {
// icon: <IconArrowUp />,
// }
export const Bordered = {
args: {
type: 'bordered',
},
render: ({ children, type }: any) => (
<Accordion type={type} openBehaviour="single" collapsible className="w-full">
<Accordion.Item value="item-1">
<Accordion.Trigger>Is it accessible?</Accordion.Trigger>
<Accordion.Content>Yes. It adheres to the WAI-ARIA design pattern.</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-2">
<Accordion.Trigger>Is it styled?</Accordion.Trigger>
<Accordion.Content>
Yes. It comes with default styles that matches the other components' aesthetic.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-3">
<Accordion.Trigger>Is it animated?</Accordion.Trigger>
<Accordion.Content>
Yes. It's animated by default, but you can disable it if you prefer.
</Accordion.Content>
</Accordion.Item>
</Accordion>
),
}
+212 -120
View File
@@ -1,142 +1,234 @@
import * as AccordionPrimitive from '@radix-ui/react-accordion'
import { cn } from '@ui/lib/utils'
import { VariantProps, cva, cx } from 'class-variance-authority'
import { ChevronDown } from 'lucide-react'
import React, { createContext, useContext, useState } from 'react'
import styleHandler from '../../lib/theme/styleHandler'
import * as RadixAccordion from '@radix-ui/react-accordion'
import { IconChevronDown } from '../Icon/icons/IconChevronDown'
import { IconChevronUp } from '../Icon/icons/IconChevronUp'
type Type = 'default' | 'bordered'
type Size = 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
type Align = 'left' | 'right'
interface ContextValue {
bordered?: boolean
type: Type
justified: Boolean
chevronAlign: Align
}
const AccordionContext = createContext<ContextValue>({
chevronAlign: 'left',
justified: true,
type: 'default',
export type AccordionRootVariantsProps = VariantProps<typeof accordionRootVariants>
const accordionRootVariants = cva('flex flex-col', {
variants: {
type: {
default: 'space-y-3',
bordered: '-space-y-px',
},
defaultVariants: {
type: 'default',
},
},
})
export interface AccordionProps {
children?: React.ReactNode
className?: string
defaultActiveId?: (string | number)[]
icon?: React.ReactNode
iconPosition?: Align
onChange?: (item: string | string[]) => void
export type AccordionItemVariantsProps = VariantProps<typeof accordionItemVariants>
const accordionItemVariants = cva(
'group first:rounded-tl-md first:rounded-tr-md last:rounded-bl-md last:rounded-br-md',
{
variants: {
type: {
default: 'overflow-hidden',
bordered: 'border border-scale-700',
},
justified: {
true: 'justify-between',
false: '',
},
},
}
)
const accordionTriggerVariants = cva(
`flex flex-row items-center w-full text-left cursor-pointer focus-visible:ring-1 focus-visible:z-10 ring-scale-1100
justify-between transition-all hover:underline [&[data-state=open]>svg]:rotate-180`,
{
variants: {
type: {
default: 'gap-3',
bordered: `
px-6 py-4
font-medium text-base bg-transparent
transition-colors hover:bg-scale-200
overflow-hidden
group-first:rounded-tl-md group-first:rounded-tr-md
group-last:rounded-bl-md group-last:rounded-br-md`,
},
},
}
)
const accordionContentVariants = cva('pb-4 pt-0', {
variants: {
type: {
default: '',
bordered: 'px-6',
},
},
})
type Type = AccordionRootVariantsProps['type']
type Align = 'left' | 'right' | undefined
interface ContextValue {
chevronAlign: Align
justified: boolean
type: Type
defaultValue: AccordionPrimitive.AccordionImplSingleProps['defaultValue']
}
interface AdditionalProps {
openBehaviour: 'single' | 'multiple'
variant?: Type
// Add other additional props here
onChange?: (item: string | string[]) => void
type?: Type
size?: Size
defaultValue?: string | string[] | undefined
justified?: Boolean
justified?: AccordionItemVariantsProps['justified']
chevronAlign?: Align
}
function Accordion({
children,
className,
onChange,
openBehaviour = 'multiple',
type = 'default',
defaultValue = undefined,
justified = false,
chevronAlign = 'left',
}: AccordionProps) {
const __styles = styleHandler('accordion')
let containerClasses = [__styles.variants[type].base]
if (className) {
containerClasses.push(className)
}
const contextValue = {
chevronAlign,
justified,
type,
defaultValue,
}
function handleOnChange(e: string | string[]) {
if (onChange) onChange(e)
const value = e == typeof String ? e.split(' ') : e
// setCurrentItems(e)
// console.log('about to change state')
// currentItems = e
// console.log('currentItems', currentItems)
}
return (
<>
{/* //
@ts-expect-error */}
<RadixAccordion.Root
type={openBehaviour}
onValueChange={handleOnChange}
defaultValue={defaultValue}
className={containerClasses.join(' ')}
children={
<AccordionContext.Provider value={{ ...contextValue }}>
<div>{children}</div>
</AccordionContext.Provider>
}
></RadixAccordion.Root>
</>
)
interface AccordionComponent
extends React.ForwardRefExoticComponent<
ExtendedAccordionProps & React.RefAttributes<HTMLDivElement>
> {
Item: typeof AccordionItem
Content: typeof AccordionContent
Trigger: typeof AccordionTrigger
}
interface ItemProps {
children?: React.ReactNode
className?: string
header: React.ReactNode
id: string
icon?: React.ReactNode
disabled?: boolean
export interface AccordionSingleProps extends AccordionPrimitive.AccordionImplSingleProps {
openBehaviour: 'single'
value?: string
// Add other props specific to single accordion
}
export function Item({ children, className, header, id, disabled }: ItemProps) {
const __styles = styleHandler('accordion')
export interface AccordionMultipleProps extends AccordionPrimitive.AccordionImplMultipleProps {
openBehaviour: 'multiple'
value?: string[]
// Add other props specific to multiple accordion
}
type ExtendedAccordionProps = (AccordionSingleProps | AccordionMultipleProps) & AdditionalProps
const AccordionContext = createContext<ContextValue>({
chevronAlign: 'left',
justified: false, // Set the default value to false
type: undefined,
defaultValue: undefined,
})
const Accordion: AccordionComponent = React.forwardRef(
({ openBehaviour, type, chevronAlign, justified, defaultValue, ...props }, ref) => {
function handleOnChange(e: string | string[]) {
if (props.onChange) props.onChange(e)
}
const contextValue = {
chevronAlign,
justified: justified || false, // Provide a default value of false
type: type || 'default', // Provide a default value for the type
defaultValue: Array.isArray(defaultValue) ? defaultValue.join('') : defaultValue, // Convert array to string
}
if (openBehaviour === 'single') {
const { value, children, className, ...singleProps } = props as AccordionSingleProps
return (
<AccordionPrimitive.Root
ref={ref}
type="single"
onValueChange={handleOnChange}
value={value}
defaultValue={defaultValue}
className={cn(accordionRootVariants({ type }), className)}
children={
<AccordionContext.Provider value={{ ...contextValue }}>
{children}
</AccordionContext.Provider>
}
{...singleProps}
/>
)
} else {
const { value, children, className, ...multipleProps } = props as AccordionMultipleProps
return (
<AccordionPrimitive.Root
ref={ref}
type="multiple"
onValueChange={handleOnChange}
value={value}
className={cn(accordionRootVariants({ type }), className)}
children={
<AccordionContext.Provider value={{ ...contextValue }}>
<div>{props.children}</div>
</AccordionContext.Provider>
}
{...multipleProps}
/>
)
}
}
) as AccordionComponent
export interface ItemAdditionalProps
extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> {}
export const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => {
const [open, setOpen] = useState(false)
const { type, justified, chevronAlign } = useContext(AccordionContext)
let triggerClasses = [__styles.variants[type].trigger]
if (justified) triggerClasses.push(__styles.justified)
if (className) triggerClasses.push(className)
let chevronClasses = [__styles.chevron.base, __styles.chevron.align[chevronAlign]]
if (open && !disabled) {
chevronClasses.unshift('!rotate-180')
}
let { type, justified } = useContext(AccordionContext)
return (
<RadixAccordion.Item
value={id}
className={__styles.variants[type].container}
disabled={disabled}
<AccordionPrimitive.Item
ref={ref}
className={cn(accordionItemVariants({ type, justified }), className)}
onClick={() => {
setOpen(!open)
}}
>
<RadixAccordion.Trigger className={triggerClasses.join(' ')}>
{header}
{!disabled && (
<IconChevronDown aria-hidden className={chevronClasses.join(' ')} strokeWidth={2} />
)}
</RadixAccordion.Trigger>
<RadixAccordion.Content className={__styles.variants[type].content}>
<div className={__styles.variants[type].panel}>{children}</div>
</RadixAccordion.Content>
</RadixAccordion.Item>
{...props}
/>
)
}
})
AccordionItem.displayName = AccordionPrimitive.Item.displayName
Accordion.Item = Item
export default Accordion
export const AccordionTrigger = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => {
const { type } = useContext(AccordionContext)
return (
<AccordionPrimitive.Header className="flex">
<AccordionPrimitive.Trigger
ref={ref}
className={cn(accordionTriggerVariants({ type }), className)}
{...props}
>
{children}
<ChevronDown className="h-4 w-4 transition-transform duration-200" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
)
})
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
export const AccordionContent = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => {
const { type } = useContext(AccordionContext)
return (
<AccordionPrimitive.Content
ref={ref}
className={cn(
'overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',
className
)}
{...props}
>
<div className={cx(accordionContentVariants({ type }))}>{children}</div>
</AccordionPrimitive.Content>
)
})
AccordionContent.displayName = AccordionPrimitive.Content.displayName
Accordion.Item = AccordionItem
Accordion.Content = AccordionContent
Accordion.Trigger = AccordionTrigger
export { Accordion }