{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "collapsible",
  "title": "Collapsible",
  "author": "andongmin94",
  "description": "An expandable region that reveals or hides related content.",
  "dependencies": [
    "@base-ui/react@^1.6.0"
  ],
  "files": [
    {
      "path": "src/components/ui/collapsible.tsx",
      "content": "\"use client\";\n\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\";\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport * as React from \"react\";\n\ntype RenderProps = React.HTMLAttributes<HTMLElement> & { ref?: React.Ref<HTMLElement> };\ntype CollapsibleContentStyle = React.CSSProperties & {\n  \"--radix-collapsible-content-height\"?: string;\n  \"--radix-collapsible-content-width\"?: string;\n};\n\nconst collapsibleContentCssVariables: CollapsibleContentStyle = {\n  \"--radix-collapsible-content-height\": \"var(--collapsible-panel-height)\",\n  \"--radix-collapsible-content-width\": \"var(--collapsible-panel-width)\",\n};\n\nfunction mergeContentStyle(\n  style: CollapsiblePrimitive.Panel.Props[\"style\"],\n): CollapsiblePrimitive.Panel.Props[\"style\"] {\n  if (typeof style === \"function\") {\n    return (state) => ({ ...collapsibleContentCssVariables, ...style(state) });\n  }\n\n  return { ...collapsibleContentCssVariables, ...style };\n}\n\nfunction mergeRefs(...refs: (React.Ref<HTMLElement> | undefined)[]) {\n  return (element: HTMLElement | null) => {\n    refs.forEach((ref) => {\n      if (typeof ref === \"function\") {\n        ref(element);\n      } else if (ref) {\n        ref.current = element;\n      }\n    });\n  };\n}\n\nfunction preserveRadixEventCancellation(\n  child: React.ReactElement<{ [key: string]: unknown; children?: React.ReactNode }>,\n) {\n  const eventProps: Record<string, unknown> = {};\n\n  for (const [name, handler] of Object.entries(child.props)) {\n    if (/^on[A-Z]/.test(name) && typeof handler === \"function\") {\n      eventProps[name] = (...args: unknown[]) => {\n        (handler as (...handlerArgs: unknown[]) => void)(...args);\n        const event = args[0] as\n          | { defaultPrevented?: boolean; preventBaseUIHandler?: () => void }\n          | undefined;\n        if (event?.defaultPrevented) event.preventBaseUIHandler?.();\n      };\n    }\n  }\n\n  return React.cloneElement(child, eventProps);\n}\n\nfunction renderWithAliases<State>(\n  render:\n    | React.ReactElement\n    | ((props: RenderProps, state: State) => React.ReactElement)\n    | undefined,\n  fallback: React.ReactElement,\n) {\n  return (elementProps: RenderProps, state: State & { disabled: boolean; open: boolean }) => {\n    const aliasedProps = mergeProps(\n      elementProps as React.ComponentPropsWithRef<\"div\">,\n      {\n        \"data-disabled\": state.disabled ? \"\" : undefined,\n        \"data-state\": state.open ? \"open\" : \"closed\",\n      } as React.ComponentPropsWithRef<\"div\">,\n    ) as RenderProps;\n\n    if (typeof render === \"function\") {\n      return render(aliasedProps, state);\n    }\n\n    const element = (render ?? fallback) as React.ReactElement<RenderProps>;\n    const mergedProps = mergeProps(\n      aliasedProps as React.ComponentPropsWithRef<\"div\">,\n      element.props as React.ComponentPropsWithRef<\"div\">,\n    ) as RenderProps;\n    mergedProps.ref = mergeRefs(aliasedProps.ref, element.props.ref);\n    return React.cloneElement(element, mergedProps);\n  };\n}\n\nfunction getChildElement(children: React.ReactNode, componentName: string) {\n  const child = React.Children.toArray(children).find(React.isValidElement);\n  if (child === undefined) {\n    throw new Error(`${componentName} with asChild requires a valid React element child.`);\n  }\n  return preserveRadixEventCancellation(\n    child as React.ReactElement<{ [key: string]: unknown; children?: React.ReactNode }>,\n  );\n}\n\nfunction Collapsible({\n  asChild = false,\n  children,\n  render,\n  ...props\n}: CollapsiblePrimitive.Root.Props & {\n  asChild?: boolean;\n  children?: React.ReactNode;\n}) {\n  const renderElement = asChild ? getChildElement(children, \"Collapsible\") : render;\n\n  return (\n    <CollapsiblePrimitive.Root\n      data-slot=\"collapsible\"\n      render={renderWithAliases<CollapsiblePrimitive.Root.State>(\n        renderElement,\n        React.createElement(\"div\"),\n      )}\n      {...props}\n    >\n      {asChild ? undefined : children}\n    </CollapsiblePrimitive.Root>\n  );\n}\n\nfunction CollapsibleTrigger({\n  asChild = false,\n  children,\n  render,\n  ...props\n}: CollapsiblePrimitive.Trigger.Props & {\n  asChild?: boolean;\n  children?: React.ReactNode;\n}) {\n  const renderElement = asChild ? getChildElement(children, \"CollapsibleTrigger\") : render;\n\n  return (\n    <CollapsiblePrimitive.Trigger\n      data-slot=\"collapsible-trigger\"\n      render={renderWithAliases<CollapsiblePrimitive.Trigger.State>(\n        renderElement,\n        React.createElement(\"button\"),\n      )}\n      {...props}\n    >\n      {asChild ? undefined : children}\n    </CollapsiblePrimitive.Trigger>\n  );\n}\n\nfunction CollapsibleContent({\n  asChild = false,\n  children,\n  forceMount,\n  keepMounted,\n  render,\n  style,\n  ...props\n}: Omit<CollapsiblePrimitive.Panel.Props, \"keepMounted\"> & {\n  asChild?: boolean;\n  children?: React.ReactNode;\n  forceMount?: true;\n  keepMounted?: boolean;\n}) {\n  return (\n    <CollapsiblePrimitive.Panel\n      data-slot=\"collapsible-content\"\n      keepMounted={keepMounted ?? forceMount ?? true}\n      style={mergeContentStyle(style)}\n      render={renderWithAliases<CollapsiblePrimitive.Panel.State>(\n        asChild ? getChildElement(children, \"CollapsibleContent\") : render,\n        React.createElement(\"div\"),\n      )}\n      {...props}\n    >\n      {asChild ? undefined : children}\n    </CollapsiblePrimitive.Panel>\n  );\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "layout",
    "disclosure"
  ],
  "type": "registry:ui"
}