LOKE Design System
Components

Collapsible

An expandable/collapsible container for showing and hiding content.

Collapsible

The Collapsible component provides a way to show and hide content on demand. It's useful for FAQs, expandable sections, and progressive disclosure patterns where you want to reduce visual clutter.

For a more structured expand/collapse pattern with multiple items, consider using the Accordion component.


Features

  • Controlled and uncontrolled modes
  • Animated expand/collapse transitions
  • Accessible trigger and content pairing
  • Composable API with separate trigger and content components
  • Supports custom trigger elements via asChild

Usage

import {
  Collapsible,
  CollapsibleTrigger,
  CollapsibleContent,
} from '@loke/design-system/collapsible';

export default function Example() {
  return (
    <Collapsible>
      <CollapsibleTrigger>Toggle content</CollapsibleTrigger>
      <CollapsibleContent>
        <p>This content can be shown or hidden.</p>
      </CollapsibleContent>
    </Collapsible>
  );
}

Tips:

  • Use asChild on CollapsibleTrigger to use your own button component.
  • The open and onOpenChange props enable controlled behavior.
  • Content is removed from the DOM when collapsed for performance.

Props

Collapsible

Prop

Type

CollapsibleTrigger

Prop

Type

CollapsibleContent

Prop

Type


Examples

Basic collapsible

@peduarte starred 3 repositories

@radix-ui/primitives
<Collapsible className="w-[350px] space-y-2">
  <div className="flex items-center justify-between space-x-4">
    <h4 className="text-sm font-semibold">
      @peduarte starred 3 repositories
    </h4>
    <CollapsibleTrigger asChild>
      <Button variant="ghost" size="sm">
        <ChevronsUpDown className="h-4 w-4" />
      </Button>
    </CollapsibleTrigger>
  </div>
  <div className="rounded-md border px-4 py-3 font-mono text-sm">
    @radix-ui/primitives
  </div>
  <CollapsibleContent className="space-y-2">
    <div className="rounded-md border px-4 py-3 font-mono text-sm">
      @radix-ui/colors
    </div>
    <div className="rounded-md border px-4 py-3 font-mono text-sm">
      @stitches/react
    </div>
  </CollapsibleContent>
</Collapsible>

Controlled collapsible

State: Closed

const [isOpen, setIsOpen] = useState(false);

<Collapsible open={isOpen} onOpenChange={setIsOpen}>
  <CollapsibleTrigger asChild>
    <Button variant="outline">
      {isOpen ? 'Hide' : 'Show'} content
    </Button>
  </CollapsibleTrigger>
  <CollapsibleContent>
    <p className="mt-4">This content is controlled externally.</p>
  </CollapsibleContent>
</Collapsible>

Collapsible with animation

Expandable section
<Collapsible>
  <CollapsibleTrigger asChild>
    <Button variant="ghost" size="sm">
      <ChevronsUpDown className="h-4 w-4" />
    </Button>
  </CollapsibleTrigger>
  <CollapsibleContent className="overflow-hidden data-[state=closed]:animate-collapse-up data-[state=open]:animate-collapse-down">
    <p>Animated content</p>
  </CollapsibleContent>
</Collapsible>

Accessibility

  • Trigger has aria-expanded to indicate open/closed state.
  • Content is associated with trigger via aria-controls.
  • Supports keyboard activation via Enter and Space keys.
  • Content is hidden from screen readers when collapsed.
  • Disabled state prevents interaction and is properly announced.

Best practices

  • Use clear trigger text that indicates what will be revealed.
  • Consider starting in an expanded state for critical content.
  • Keep collapsed content relatively short to avoid jarring transitions.
  • Use forceMount when you need to measure content or animate with CSS.
  • Don't nest collapsibles too deeply — consider restructuring the UI.
  • For multiple collapsible sections, consider using Accordion instead.