{"$schema":"https:\/\/ui.particle.academy\/schema\/registry-item.json","name":"accordion","type":"registry:ui","title":"Accordion","description":"Accordion from react-fancy","package":"react-fancy","dependencies":["lucide-react"],"registryDependencies":[],"files":[{"path":"components\/fancy\/accordion\/Accordion.context.ts","content":"import { createContext, useContext } from \"react\";\r\nimport type { AccordionContextValue } from \".\/Accordion.types\";\r\n\r\nexport const AccordionContext = createContext<AccordionContextValue | null>(\r\n  null,\r\n);\r\n\r\nexport function useAccordion(): AccordionContextValue {\r\n  const ctx = useContext(AccordionContext);\r\n  if (!ctx) {\r\n    throw new Error(\r\n      \"Accordion compound components must be used within <Accordion>\",\r\n    );\r\n  }\r\n  return ctx;\r\n}\r\n\r\nexport const AccordionItemContext = createContext<string>(\"\");\r\n\r\nexport function useAccordionItem(): string {\r\n  return useContext(AccordionItemContext);\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/Accordion.context.ts"},{"path":"components\/fancy\/accordion\/Accordion.tsx","content":"import { useCallback, useMemo, useState } from \"react\";\r\nimport { cn } from \"..\/..\/utils\/cn\";\r\nimport { AccordionContext } from \".\/Accordion.context\";\r\nimport { AccordionItem } from \".\/AccordionItem\";\r\nimport { AccordionTrigger } from \".\/AccordionTrigger\";\r\nimport { AccordionContent } from \".\/AccordionContent\";\r\nimport type { AccordionProps } from \".\/Accordion.types\";\r\n\r\nfunction AccordionRoot({\r\n  children,\r\n  type = \"single\",\r\n  defaultOpen = [],\r\n  className,\r\n}: AccordionProps) {\r\n  const [openItems, setOpenItems] = useState<string[]>(defaultOpen);\r\n  const multiple = type === \"multiple\";\r\n\r\n  const toggle = useCallback(\r\n    (value: string) => {\r\n      setOpenItems((prev) => {\r\n        if (prev.includes(value)) {\r\n          return prev.filter((v) => v !== value);\r\n        }\r\n        return multiple ? [...prev, value] : [value];\r\n      });\r\n    },\r\n    [multiple],\r\n  );\r\n\r\n  const ctx = useMemo(\r\n    () => ({ openItems, toggle, multiple }),\r\n    [openItems, toggle, multiple],\r\n  );\r\n\r\n  return (\r\n    <AccordionContext.Provider value={ctx}>\r\n      <div data-react-fancy-accordion=\"\" className={cn(className)}>{children}<\/div>\r\n    <\/AccordionContext.Provider>\r\n  );\r\n}\r\n\r\nexport const Accordion = Object.assign(AccordionRoot, {\r\n  Item: AccordionItem,\r\n  Trigger: AccordionTrigger,\r\n  Content: AccordionContent,\r\n});\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/Accordion.tsx"},{"path":"components\/fancy\/accordion\/Accordion.types.ts","content":"import type { ReactNode } from \"react\";\r\n\r\nexport interface AccordionContextValue {\r\n  openItems: string[];\r\n  toggle: (value: string) => void;\r\n  multiple: boolean;\r\n}\r\n\r\nexport interface AccordionProps {\r\n  children: ReactNode;\r\n  type?: \"single\" | \"multiple\";\r\n  defaultOpen?: string[];\r\n  className?: string;\r\n}\r\n\r\nexport interface AccordionItemProps {\r\n  children: ReactNode;\r\n  value: string;\r\n  className?: string;\r\n}\r\n\r\nexport interface AccordionTriggerProps {\r\n  children: ReactNode;\r\n  className?: string;\r\n}\r\n\r\nexport interface AccordionContentProps {\r\n  children: ReactNode;\r\n  className?: string;\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/Accordion.types.ts"},{"path":"components\/fancy\/accordion\/AccordionContent.tsx","content":"import { cn } from \"..\/..\/utils\/cn\";\r\nimport { useAccordion, useAccordionItem } from \".\/Accordion.context\";\r\nimport type { AccordionContentProps } from \".\/Accordion.types\";\r\n\r\nexport function AccordionContent({\r\n  children,\r\n  className,\r\n}: AccordionContentProps) {\r\n  const { openItems } = useAccordion();\r\n  const value = useAccordionItem();\r\n  const isOpen = openItems.includes(value);\r\n\r\n  return (\r\n    <div\r\n      data-react-fancy-accordion-content=\"\"\r\n      className={cn(\r\n        \"grid transition-all duration-200\",\r\n        isOpen ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\r\n      )}\r\n    >\r\n      <div className=\"overflow-hidden\">\r\n        <div className={cn(\"pb-4 text-sm text-zinc-600 dark:text-zinc-400\", className)}>\r\n          {children}\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  );\r\n}\r\n\r\nAccordionContent.displayName = \"AccordionContent\";\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/AccordionContent.tsx"},{"path":"components\/fancy\/accordion\/AccordionItem.tsx","content":"import { cn } from \"..\/..\/utils\/cn\";\r\nimport { AccordionItemContext } from \".\/Accordion.context\";\r\nimport type { AccordionItemProps } from \".\/Accordion.types\";\r\n\r\nexport function AccordionItem({\r\n  children,\r\n  value,\r\n  className,\r\n}: AccordionItemProps) {\r\n  return (\r\n    <AccordionItemContext.Provider value={value}>\r\n      <div\r\n        data-react-fancy-accordion-item=\"\"\r\n        className={cn(\r\n          \"border-b border-zinc-200 dark:border-zinc-700\",\r\n          className,\r\n        )}\r\n      >\r\n        {children}\r\n      <\/div>\r\n    <\/AccordionItemContext.Provider>\r\n  );\r\n}\r\n\r\nAccordionItem.displayName = \"AccordionItem\";\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/AccordionItem.tsx"},{"path":"components\/fancy\/accordion\/AccordionTrigger.tsx","content":"import { ChevronDown } from \"lucide-react\";\r\nimport { cn } from \"..\/..\/utils\/cn\";\r\nimport { useAccordion, useAccordionItem } from \".\/Accordion.context\";\r\nimport type { AccordionTriggerProps } from \".\/Accordion.types\";\r\n\r\nexport function AccordionTrigger({\r\n  children,\r\n  className,\r\n}: AccordionTriggerProps) {\r\n  const { openItems, toggle } = useAccordion();\r\n  const value = useAccordionItem();\r\n  const isOpen = openItems.includes(value);\r\n\r\n  return (\r\n    <button\r\n      data-react-fancy-accordion-trigger=\"\"\r\n      type=\"button\"\r\n      onClick={() => toggle(value)}\r\n      aria-expanded={isOpen}\r\n      className={cn(\r\n        \"flex w-full items-center justify-between py-4 text-left text-sm font-medium transition-colors hover:text-zinc-600 dark:hover:text-zinc-300\",\r\n        className,\r\n      )}\r\n    >\r\n      {children}\r\n      <ChevronDown size={16} className={cn(\"shrink-0 transition-transform duration-200\", isOpen && \"rotate-180\")} \/>\r\n    <\/button>\r\n  );\r\n}\r\n\r\nAccordionTrigger.displayName = \"AccordionTrigger\";\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/AccordionTrigger.tsx"},{"path":"components\/fancy\/accordion\/index.ts","content":"export { Accordion } from \".\/Accordion\";\r\nexport { useAccordion } from \".\/Accordion.context\";\r\nexport type {\r\n  AccordionProps,\r\n  AccordionItemProps,\r\n  AccordionTriggerProps,\r\n  AccordionContentProps,\r\n  AccordionContextValue,\r\n} from \".\/Accordion.types\";\r\n","type":"registry:ui","target":"components\/fancy\/accordion\/index.ts"}]}