{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "radix-accordion", "type": "registry:ui", "title": "Radix Accordion", "description": "A vertically stacked set of interactive headings that each reveal an associated section of content.", "dependencies": [ "motion", "radix-ui" ], "files": [ { "path": "registry/radix/accordion/index.tsx", "content": "'use client';\n\nimport * as React from 'react';\nimport { Accordion as AccordionPrimitive } from 'radix-ui';\nimport { ChevronDown } from 'lucide-react';\nimport {\n motion,\n AnimatePresence,\n type Transition,\n type HTMLMotionProps,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype AccordionItemContextType = {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n};\n\nconst AccordionItemContext = React.createContext<\n AccordionItemContextType | undefined\n>(undefined);\n\nconst useAccordionItem = (): AccordionItemContextType => {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('useAccordionItem must be used within an AccordionItem');\n }\n return context;\n};\n\ntype AccordionProps = React.ComponentProps;\n\nfunction Accordion(props: AccordionProps) {\n return ;\n}\n\ntype AccordionItemProps = React.ComponentProps<\n typeof AccordionPrimitive.Item\n> & {\n children: React.ReactNode;\n};\n\nfunction AccordionItem({ className, children, ...props }: AccordionItemProps) {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n \n \n {children}\n \n \n );\n}\n\ntype AccordionTriggerProps = React.ComponentProps<\n typeof AccordionPrimitive.Trigger\n> & {\n transition?: Transition;\n chevron?: boolean;\n};\n\nfunction AccordionTrigger({\n ref,\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n chevron = true,\n ...props\n}: AccordionTriggerProps) {\n const triggerRef = React.useRef(null);\n React.useImperativeHandle(ref, () => triggerRef.current as HTMLButtonElement);\n const { isOpen, setIsOpen } = useAccordionItem();\n\n React.useEffect(() => {\n const node = triggerRef.current;\n if (!node) return;\n\n const observer = new MutationObserver((mutationsList) => {\n mutationsList.forEach((mutation) => {\n if (mutation.attributeName === 'data-state') {\n const currentState = node.getAttribute('data-state');\n setIsOpen(currentState === 'open');\n }\n });\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-state'],\n });\n const initialState = node.getAttribute('data-state');\n setIsOpen(initialState === 'open');\n return () => {\n observer.disconnect();\n };\n }, [setIsOpen]);\n\n return (\n \n \n {children}\n\n {chevron && (\n \n \n \n )}\n \n \n );\n}\n\ntype AccordionContentProps = React.ComponentProps<\n typeof AccordionPrimitive.Content\n> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction AccordionContent({\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n ...props\n}: AccordionContentProps) {\n const { isOpen } = useAccordionItem();\n\n return (\n \n {isOpen && (\n \n \n
{children}
\n \n
\n )}\n
\n );\n}\n\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n useAccordionItem,\n type AccordionItemContextType,\n type AccordionProps,\n type AccordionItemProps,\n type AccordionTriggerProps,\n type AccordionContentProps,\n};\n", "type": "registry:ui", "target": "components/animate-ui/radix/accordion.tsx" } ] }