Data Display/Collapsible

Collapsible

An interactive component that expands/collapses a panel.

Themed

When to Use

Use Collapsible when you need to:

  • Show or hide a single section of supplementary content
  • Build file-tree or hierarchical navigation structures
  • Create settings panels that reveal advanced options
  • Reduce visual clutter while keeping content accessible on demand
  • Implement a single expandable FAQ or detail row

When Not to Use

  • Multiple stacked collapsible sections - use Accordion for coordinated expand/collapse
  • Full-page or panel-sized sliding content - use Sheet or Drawer
  • Tabbed content switching - use Tabs for mutually exclusive views
  • Contextual information on hover - use Tooltip or Hover Card

Default

A collapsible panel showing starred repositories. Click the toggle button to expand/collapse.

@peduarte starred 3 repositories

@radix-ui/primitives

Basic

Simple text-based collapsible with an inline trigger and CSS-driven chevron rotation.

With Animated Icon

Settings panel with an animated chevron icon that rotates on open/close using controlled state.

Advanced Settings

FAQ Style

Multiple independent collapsible items styled as an FAQ section. Each item operates independently.

Nested

Collapsible items can be nested to create file tree or hierarchical navigation structures.

Project Files

index.tsx
styles.css
utils.ts

UX & Design Guidelines

Visual Hierarchy

The trigger should clearly indicate that content is expandable. Use a chevron icon that rotates between states to communicate interactivity. Pair the icon with a descriptive label so users understand what will be revealed. Keep the trigger visually distinct from the content it controls.

Spacing & Layout

Add gap-2 between the trigger and content for compact layouts, or use pt-4 for more breathing room. When nesting collapsibles, indent child items with pl-6 to convey hierarchy. Use border and rounded-lg to visually group trigger and content together.

Responsive Behavior

Collapsible sections are especially valuable on mobile where screen space is limited. Consider starting sections collapsed on smaller viewports to reduce scrolling. Ensure trigger touch targets meet the minimum 44x44px recommendation. Use w-full on triggers in narrow containers to maximize the tappable area.

Animation & Transitions

Use the data-state attribute to style based on open/closed state. Apply transition-transform duration-200 for smooth icon rotations. CSS grid animations can provide fluid height transitions. Keep animation duration under 300ms to feel responsive without causing motion discomfort.

Accessibility

Keyboard Navigation

  • Tab -- Move focus to the collapsible trigger
  • Enter or Space -- Toggle the collapsible open/closed
  • When nested, Tab moves through each trigger in DOM order
  • Content inside an open collapsible is reachable via Tab in natural reading order

Screen Reader Support

  • Trigger automatically receives aria-expanded reflecting the current state
  • Content is hidden from the accessibility tree when collapsed via aria-hidden
  • When using asChild with an icon-only button, always provide aria-label or a sr-only span
  • Disabled state is communicated via the disabled attribute on the trigger

Focus Management

Focus stays on the trigger after toggling, so users can press Space or Enter again to collapse. Newly revealed content does not steal focus -- users tab into it naturally. Visible focus ring uses focus-visible:ring-[3px] on the trigger for clear keyboard indication.

Motion Preferences

Respect prefers-reduced-motion by using Tailwind's motion-safe: prefix on transition utilities. When reduced motion is preferred, animations should be disabled or replaced with instant state changes.

ARIA Attributes

{/* Uncontrolled collapsible with accessible trigger */}
<Collapsible>
  <CollapsibleTrigger asChild>
    <Button variant="ghost" aria-label="Toggle details">
      <ChevronsUpDown className="h-4 w-4" />
    </Button>
  </CollapsibleTrigger>
  <CollapsibleContent>
    Details content here
  </CollapsibleContent>
</Collapsible>

{/* Controlled collapsible with descriptive label */}
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
  <CollapsibleTrigger asChild>
    <Button variant="outline" aria-expanded={isOpen}>
      {isOpen ? "Hide" : "Show"} Advanced Settings
    </Button>
  </CollapsibleTrigger>
  <CollapsibleContent>
    Settings content here
  </CollapsibleContent>
</Collapsible>

{/* Disabled collapsible */}
<Collapsible disabled>
  <CollapsibleTrigger asChild>
    <Button variant="ghost" disabled>
      Unavailable Section
    </Button>
  </CollapsibleTrigger>
  <CollapsibleContent>
    This content cannot be toggled.
  </CollapsibleContent>
</Collapsible>

API Reference

The Collapsible component is composed of three parts: a root, a trigger, and a content container.

Collapsible

Root component that manages the open/closed state.

PropTypeDefaultDescription
openbooleanfalseThe controlled open state of the collapsible.
defaultOpenbooleanfalseThe default open state when initially rendered (uncontrolled).
onOpenChange(open: boolean) => voidEvent handler called when the open state changes.
disabledbooleanfalseWhen true, prevents user interaction with the trigger.
classNamestringAdditional CSS classes to apply to the root element.

CollapsibleTrigger

The interactive element that toggles the content visibility.

PropTypeDefaultDescription
asChildbooleanfalseMerge props onto the immediate child element instead of rendering a default button.
classNamestringAdditional CSS classes to apply to the trigger element.

CollapsibleContent

The container for the content that is shown or hidden.

PropTypeDefaultDescription
forceMountbooleanfalseForce mounting when more control is needed (useful for entry/exit animations).
classNamestringAdditional CSS classes to apply to the content container.