Primitives
Collapsible
Accessible disclosure primitive with measured open and close motion.
Composition
The preferred shape for composing the installed primitive from its exported parts.
Parts
Exported compound parts from the installed source.
Collapsible├── CollapsibleTrigger└── CollapsibleContentThe refined source installs this primitive from src/registry/sources/refined/ui/collapsible.tsx. It installs with the chat registry, so Refined UI files keep a stable import path.
npx shadcn@latest add http://127.0.0.1:3000/r/refined/chat.jsonRaw code
Primary installed primitive source
Base UI Collapsible slot
src/registry/sources/refined/ui/collapsible.tsx
"use client";import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible";import { mergeProps } from "@base-ui/react/merge-props";import { cloneElement, isValidElement } from "react";import type { CollapsibleContentProps, CollapsibleProps, CollapsibleTriggerProps } from "@/components/refined-ui/contracts";import { cn } from "@/components/refined-ui/lib/cn";import { skinSlot } from "@/components/refined-ui/skin";// Emits skin-stable data-ui/data-slot/data-state hooks so consumers never style on Base UI's private attributes.export function Collapsible({ className, ...props }: CollapsibleProps) { return ( <CollapsiblePrimitive.Root className={className} render={(renderProps, state) => ( <div data-ui="agent" data-slot="collapsible" {...renderProps} data-state={state.open ? "open" : "closed"} className={cn(renderProps.className, skinSlot("collapsible", { state: state.open ? "open" : "closed" }))} /> )} {...props} /> );}export function CollapsibleTrigger({ asChild = false, className, children, ...props }: CollapsibleTriggerProps) { return ( <CollapsiblePrimitive.Trigger className={cn( "cursor-pointer outline-none transition-colors duration-[var(--duration-fast)] ease-[var(--ease-standard)] focus-visible:ring-2 focus-visible:ring-foreground/20", "[&>svg]:transition-transform [&>svg]:duration-[var(--duration-base)] [&>svg]:ease-[var(--ease-standard)] [&[data-state=open]>svg]:rotate-90", className, )} {...props} render={(renderProps, state) => { const stateAttrs = { "data-ui": "agent", "data-slot": "collapsible-trigger", "data-state": state.open ? "open" : "closed", }; const skinClasses = skinSlot("collapsible-trigger", { state: state.open ? "open" : "closed" }); // asChild: mergeProps chains handlers + concatenates className instead of overwriting consumer's own props. if (asChild && isValidElement<{ className?: string }>(children)) { const merged = mergeProps(renderProps, children.props); return cloneElement(children, { ...merged, ...stateAttrs, className: cn(merged.className, skinClasses), }); } return ( <button type="button" {...renderProps} {...stateAttrs} className={cn(renderProps.className, skinClasses)}> {children} </button> ); }} /> );}export function CollapsibleContent({ className, children, ...props }: CollapsibleContentProps) { return ( <CollapsiblePrimitive.Panel className={cn( "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height,opacity] duration-[var(--duration-base)] ease-[var(--ease-emphasized)]", "data-[starting-style]:h-0 data-[starting-style]:opacity-0 data-[ending-style]:h-0 data-[ending-style]:opacity-0", )} {...props} render={(renderProps, state) => ( <div {...renderProps} data-ui="agent" data-slot="collapsible-content" data-state={state.open ? "open" : "closed"} className={cn(renderProps.className, skinSlot("collapsible-content", { state: state.open ? "open" : "closed" }))} /> )} > <div className={className}>{children}</div> </CollapsiblePrimitive.Panel> );}