{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "headless-disclosure",
  "type": "registry:ui",
  "title": "Headless Disclosure",
  "description": "A simple, accessible foundation for building custom UIs that show and hide content, like togglable accordion panels.",
  "dependencies": [
    "@headlessui/react",
    "motion"
  ],
  "files": [
    {
      "path": "registry/headless/disclosure/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport {\n  Disclosure as DisclosurePrimitive,\n  DisclosureButton as DisclosureButtonPrimitive,\n  DisclosurePanel as DisclosurePanelPrimitive,\n  type DisclosureProps as DisclosurePrimitiveProps,\n  type DisclosureButtonProps as DisclosureButtonPrimitiveProps,\n  type DisclosurePanelProps as DisclosurePanelPrimitiveProps,\n} from '@headlessui/react';\nimport {\n  AnimatePresence,\n  motion,\n  type HTMLMotionProps,\n  type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype DisclosureContextType = {\n  isOpen: boolean;\n};\n\nconst DisclosureContext = React.createContext<\n  DisclosureContextType | undefined\n>(undefined);\n\nconst useDisclosure = (): DisclosureContextType => {\n  const context = React.useContext(DisclosureContext);\n  if (!context) {\n    throw new Error('useDisclosure must be used within a Disclosure');\n  }\n  return context;\n};\n\ntype DisclosureProps<TTag extends React.ElementType = 'div'> =\n  DisclosurePrimitiveProps<TTag> & {\n    as?: TTag;\n  };\n\nfunction Disclosure<TTag extends React.ElementType = 'div'>({\n  children,\n  ...props\n}: DisclosureProps<TTag>) {\n  return (\n    <DisclosurePrimitive data-slot=\"disclosure\" {...props}>\n      {(bag) => (\n        <DisclosureContext.Provider value={{ isOpen: bag.open }}>\n          {typeof children === 'function' ? children(bag) : children}\n        </DisclosureContext.Provider>\n      )}\n    </DisclosurePrimitive>\n  );\n}\n\ntype DisclosureButtonProps<TTag extends React.ElementType = 'button'> =\n  DisclosureButtonPrimitiveProps<TTag> & {\n    as?: TTag;\n  };\n\nfunction DisclosureButton<TTag extends React.ElementType = 'button'>(\n  props: DisclosureButtonProps<TTag>,\n) {\n  return <DisclosureButtonPrimitive data-slot=\"disclosure-button\" {...props} />;\n}\n\ntype DisclosurePanelProps<TTag extends React.ElementType = typeof motion.div> =\n  Pick<DisclosurePanelPrimitiveProps<TTag>, 'static' | 'unmount' | 'children'> &\n    Omit<HTMLMotionProps<'div'>, 'children'> & {\n      transition?: Transition;\n      as?: TTag;\n    };\n\nfunction DisclosurePanel<TTag extends React.ElementType = typeof motion.div>(\n  props: DisclosurePanelProps<TTag>,\n) {\n  const {\n    className,\n    children,\n    transition = { type: 'spring', stiffness: 150, damping: 22 },\n    as = motion.div,\n    unmount,\n    ...rest\n  } = props;\n  const { isOpen } = useDisclosure();\n\n  return (\n    <AnimatePresence>\n      {isOpen && (\n        <DisclosurePanelPrimitive\n          static\n          as={as as React.ElementType}\n          unmount={unmount}\n        >\n          {(bag) => (\n            <motion.div\n              key=\"disclosure-panel\"\n              data-slot=\"disclosure-panel\"\n              initial={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n              animate={{ height: 'auto', opacity: 1, '--mask-stop': '100%' }}\n              exit={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n              transition={transition}\n              style={{\n                maskImage:\n                  'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n                WebkitMaskImage:\n                  'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n              }}\n              className={cn('overflow-hidden', className)}\n              {...rest}\n            >\n              {typeof children === 'function' ? children(bag) : children}\n            </motion.div>\n          )}\n        </DisclosurePanelPrimitive>\n      )}\n    </AnimatePresence>\n  );\n}\n\nexport {\n  Disclosure,\n  DisclosureButton,\n  DisclosurePanel,\n  useDisclosure,\n  type DisclosureProps,\n  type DisclosureButtonProps,\n  type DisclosurePanelProps,\n};\n",
      "type": "registry:ui",
      "target": "components/animate-ui/headless/disclosure.tsx"
    }
  ]
}