Skip to main content

collapsible

An interactive component which expands/collapses a panel.

Philosophy

Collapsible is the simplest disclosure primitive — it shows and hides content. Unlike Accordion, it doesn't manage a group of items or enforce single-selection. Use it for individual expand/collapse needs like "show more" sections, advanced settings, or code blocks. It's the building block that Accordion is built on.

Installation


npx @gentleduck/cli add collapsible

npx @gentleduck/cli add collapsible

Usage

import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible"
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible"
<Collapsible>
  <CollapsibleTrigger>Can I use this in my project?</CollapsibleTrigger>
  <CollapsibleContent>
    Yes. Free to use for personal and commercial projects. No attribution
    required.
  </CollapsibleContent>
</Collapsible>
<Collapsible>
  <CollapsibleTrigger>Can I use this in my project?</CollapsibleTrigger>
  <CollapsibleContent>
    Yes. Free to use for personal and commercial projects. No attribution
    required.
  </CollapsibleContent>
</Collapsible>

Component Composition

Loading diagram...

API Reference

Collapsible

PropTypeDefaultDescription
openboolean--Controlled open state
onOpenChange(open: boolean) => void--Callback fired when open state changes
defaultOpenbooleanfalseInitial open state when uncontrolled
dir'ltr' | 'rtl'--Text direction override. Resolved via useDirection (dir prop -> DirectionProvider -> 'ltr').
...propsReact.HTMLProps<HTMLDivElement>--Additional props to spread to the content div

CollapsibleTrigger

PropTypeDefaultDescription
variantButtonVariant'ghost'Button variant passed to the underlying Button component
childrenReact.ReactNode--Trigger content
onClickReact.MouseEventHandler--Additional click handler; open/close toggle is handled internally
...propsReact.ComponentPropsWithoutRef<typeof Button>--Additional props inherited from Button.

CollapsibleContent

PropTypeDefaultDescription
forceMountbooleanfalseWhen true, content is always mounted in the DOM regardless of open state
...propsReact.HTMLProps<HTMLElement>--Additional props to spread to the section element

useCollapsible

Hook to access collapsible state from within a Collapsible tree. Throws if used outside a Collapsible.

import { useCollapsible } from "@/components/ui/collapsible"
 
const { open, onOpenChange } = useCollapsible()
import { useCollapsible } from "@/components/ui/collapsible"
 
const { open, onOpenChange } = useCollapsible()
ReturnTypeDescription
openbooleanCurrent open state
onOpenChange(open: boolean) => voidFunction to update open state
wrapperRefReact.RefObject<HTMLDivElement | null>Ref to the root collapsible element
triggerRefReact.RefObject<HTMLButtonElement | null>Ref to the trigger button
contentRefReact.RefObject<HTMLDivElement | null>Ref to the content section
contentIdstringAuto-generated ID linking trigger and content via aria-controls

RTL Support

Direction is resolved through the shared primitives direction module. Use a local dir="rtl" override when the component exposes it, or set DirectionProvider at app/root level for global RTL/LTR behavior.