{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"accordion","type":"registry:ui","title":"Accordion","description":"Vertically stacked sections that expand to reveal content.","dependencies":["lucide-react","radix-ui"],"registryDependencies":["https://dashral.com/r/utils.json"],"files":[{"path":"registry/dashral/accordion.tsx","type":"registry:file","target":"components/dashral/accordion.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype AccordionItem = {\n  /** A stable key, used by value / defaultValue; the index is used without one. */\n  value?: string\n  title: React.ReactNode\n  content: React.ReactNode\n  disabled?: boolean\n}\n\ntype AccordionProps = Omit<React.ComponentProps<\"div\">, \"defaultValue\" | \"dir\"> & {\n  items: AccordionItem[]\n  /** Several open at once; otherwise opening one closes the other. */\n  multiple?: boolean\n  /** The open items, controlled. */\n  value?: string[]\n  defaultValue?: string[]\n  onValueChange?: (value: string[]) => void\n  /** default: rows split by lines; separated: each row a card of its own. */\n  variant?: \"default\" | \"separated\"\n  classNames?: { item?: string; trigger?: string; content?: string }\n}\n\n/** Sections that open and close, in one tag: items with a title and content. */\nfunction Accordion({ items, multiple = false, value, defaultValue, onValueChange, variant = \"default\", className, classNames, ...props }: AccordionProps) {\n  const keyOf = (item: AccordionItem, i: number) => item.value ?? String(i)\n  const rows = items.map((item, i) => (\n    <AccordionItemPart\n      key={keyOf(item, i)}\n      value={keyOf(item, i)}\n      disabled={item.disabled}\n      className={cn(variant === \"separated\" && \"rounded-lg border px-4 last:border-b\", classNames?.item)}\n    >\n      <AccordionTrigger className={classNames?.trigger}>{item.title}</AccordionTrigger>\n      <AccordionContent className={classNames?.content}>{item.content}</AccordionContent>\n    </AccordionItemPart>\n  ))\n  const root = cn(variant === \"separated\" && \"grid gap-2\", className)\n  // Radix takes a string for one open item and an array for several; the outside always sees an array.\n  return multiple ? (\n    <AccordionPrimitive.Root data-slot=\"accordion\" type=\"multiple\" value={value} defaultValue={defaultValue} onValueChange={onValueChange} className={root} {...props}>\n      {rows}\n    </AccordionPrimitive.Root>\n  ) : (\n    <AccordionPrimitive.Root\n      data-slot=\"accordion\"\n      type=\"single\"\n      collapsible\n      value={value === undefined ? undefined : (value[0] ?? \"\")}\n      defaultValue={defaultValue?.[0]}\n      onValueChange={onValueChange && ((next: string) => onValueChange(next ? [next] : []))}\n      className={root}\n      {...props}\n    >\n      {rows}\n    </AccordionPrimitive.Root>\n  )\n}\n\nfunction AccordionItemPart({\n  className,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n  return (\n    <AccordionPrimitive.Item\n      data-slot=\"accordion-item\"\n      className={cn(\"border-b last:border-b-0\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AccordionTrigger({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n  return (\n    <AccordionPrimitive.Header className=\"flex\">\n      <AccordionPrimitive.Trigger\n        data-slot=\"accordion-trigger\"\n        className={cn(\n          \"flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-start text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <ChevronDownIcon className=\"pointer-events-none size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-(--duration-standard) ease-spring\" />\n      </AccordionPrimitive.Trigger>\n    </AccordionPrimitive.Header>\n  )\n}\n\nfunction AccordionContent({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n  return (\n    <AccordionPrimitive.Content\n      data-slot=\"accordion-content\"\n      className=\"overflow-hidden text-sm duration-(--duration-standard) ease-standard data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down motion-reduce:animate-none\"\n      {...props}\n    >\n      <div className={cn(\"pt-0 pb-4\", className)}>{children}</div>\n    </AccordionPrimitive.Content>\n  )\n}\n\nexport { Accordion, type AccordionProps, type AccordionItem }\n"}],"cssVars":{"theme":{"ease-standard":"var(--ease-standard)","ease-enter":"var(--ease-enter)","ease-exit":"var(--ease-exit)","ease-spring":"var(--ease-spring)"},"light":{"duration-fast":"160ms","duration-standard":"240ms","duration-considered":"480ms","ease-standard":"cubic-bezier(0.2, 0, 0, 1)","ease-enter":"cubic-bezier(0, 0, 0, 1)","ease-exit":"cubic-bezier(0.3, 0, 1, 1)","ease-spring":"linear(0, 0.071 4%, 0.234 8%, 0.433 12%, 0.626 17%, 0.791 21%, 0.917 25%, 1.004 29%, 1.055 33%, 1.079 38%, 1.083 42%, 1.075 46%, 1.06 50%, 1.043 54%, 1.027 58%, 1.015 62%, 1.005 67%, 0.998 71%, 0.995 75%, 0.993 79%, 0.993 83%, 0.994 88%, 0.995 92%, 0.997 96%, 1)"},"dark":{}}}