{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "animated-disclosure",
  "title": "Animated Disclosure",
  "description": "An expandable disclosure panel with vertical and horizontal motion directions.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "registry/corr/components/animated-disclosure.tsx",
      "content": "\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport { ChevronDown } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\n\nexport type AnimatedDisclosureDirection = \"down\" | \"up\" | \"left\" | \"right\"\n\nexport function AnimatedDisclosure({\n  open,\n  onOpenChange,\n  title,\n  children,\n  direction = \"down\",\n  trigger,\n  disabled = false,\n  className,\n  triggerClassName,\n  contentClassName,\n}: {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  title: ReactNode\n  children: ReactNode\n  direction?: AnimatedDisclosureDirection\n  trigger?: ReactNode\n  disabled?: boolean\n  className?: string\n  triggerClassName?: string\n  contentClassName?: string\n}) {\n  const reduceMotion = useReducedMotion()\n  const isHorizontal = direction === \"left\" || direction === \"right\"\n  const label = typeof title === \"string\" ? title : \"Toggle disclosure\"\n\n  if (isHorizontal) {\n    return (\n      <div\n        className={cn(\n          \"inline-flex items-center gap-2\",\n          direction === \"left\" && \"flex-row-reverse\",\n          className\n        )}\n      >\n        <Button\n          type=\"button\"\n          size=\"icon\"\n          aria-expanded={open}\n          aria-label={label}\n          disabled={disabled}\n          onClick={() => onOpenChange(!open)}\n          className={cn(\n            \"size-10 shrink-0 rounded-full shadow-sm\",\n            triggerClassName\n          )}\n        >\n          {trigger ?? <ChevronDown className=\"size-4\" />}\n        </Button>\n        <AnimatePresence initial={false}>\n          {open ? (\n            <motion.div\n              initial={\n                reduceMotion\n                  ? { opacity: 0 }\n                  : {\n                      opacity: 0,\n                      width: 0,\n                      x: direction === \"left\" ? 6 : -6,\n                    }\n              }\n              animate={\n                reduceMotion\n                  ? { opacity: 1 }\n                  : { opacity: 1, width: \"auto\", x: 0 }\n              }\n              exit={\n                reduceMotion\n                  ? { opacity: 0 }\n                  : {\n                      opacity: 0,\n                      width: 0,\n                      x: direction === \"left\" ? 6 : -6,\n                    }\n              }\n              transition={{\n                duration: reduceMotion ? 0 : 0.24,\n                ease: \"easeOut\",\n              }}\n              className=\"overflow-hidden\"\n            >\n              <div\n                className={cn(\n                  \"w-72 rounded-md border bg-card p-4 shadow-sm\",\n                  contentClassName\n                )}\n              >\n                <div className=\"text-sm font-medium\">{title}</div>\n                <div className=\"mt-2 text-sm leading-6 text-muted-foreground\">\n                  {children}\n                </div>\n              </div>\n            </motion.div>\n          ) : null}\n        </AnimatePresence>\n      </div>\n    )\n  }\n\n  const content = (\n    <AnimatePresence initial={false}>\n      {open ? (\n        <motion.div\n          initial={reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n          animate={\n            reduceMotion ? { opacity: 1 } : { height: \"auto\", opacity: 1 }\n          }\n          exit={reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n          transition={{ duration: reduceMotion ? 0 : 0.22, ease: \"easeOut\" }}\n          className=\"overflow-hidden\"\n        >\n          <div\n            className={cn(\n              \"px-4 py-3 text-sm leading-6 text-muted-foreground\",\n              direction === \"up\" ? \"border-b\" : \"border-t\",\n              contentClassName\n            )}\n          >\n            {children}\n          </div>\n        </motion.div>\n      ) : null}\n    </AnimatePresence>\n  )\n\n  return (\n    <div className={cn(\"rounded-md border bg-card\", className)}>\n      {direction === \"up\" ? content : null}\n      <Button\n        type=\"button\"\n        variant=\"ghost\"\n        aria-expanded={open}\n        disabled={disabled}\n        onClick={() => onOpenChange(!open)}\n        className={cn(\n          \"flex h-auto w-full justify-between rounded-none px-4 py-3 text-left\",\n          triggerClassName\n        )}\n      >\n        <span className=\"font-medium\">{title}</span>\n        <motion.span\n          animate={{\n            rotate: direction === \"up\" ? (open ? 0 : 180) : open ? 180 : 0,\n          }}\n          transition={\n            reduceMotion ? { duration: 0 } : { duration: 0.18, ease: \"easeOut\" }\n          }\n        >\n          <ChevronDown className=\"size-4 text-muted-foreground\" />\n        </motion.span>\n      </Button>\n      {direction === \"down\" ? content : null}\n    </div>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}