Home

Collapsible

One trigger that shows or hides one panel below it, its height animated.

ui.collapsiblecomponents/ui/collapsible.tsx

Use case

For the AI

Use it to tuck away one block that most people skip: the archived projects under a client's list, the advanced options under a short form, the full address under a summary. The trigger has no style of its own, so it is drawn as the showcase draws it: a full-width row with a chevron that turns when the panel is open.

Use it when

  • A single block of secondary content
  • An archived or "more" group at the foot of a list
  • Advanced options under a short form

Use something else when

  • Several sections in a stack, such as questions and answers: Accordion
  • Content floating over the page rather than pushing it down: Popover
  • Switching between views in the same place: Tabs

Examples

Code

Import

import { ChevronDownIcon } from "@/components/icons"
import { Collapsible, CollapsiblePanel, CollapsibleTrigger } from "@/components/ui/collapsible"

Usage

<Collapsible className="w-full max-w-sm">
  <CollapsibleTrigger className="group/c flex h-10 w-full cursor-pointer items-center justify-between rounded-[12px] px-3 text-[14px] font-medium outline-none hover:bg-background focus-visible:shadow-(--focus-ring)">
    Three archived projects
    <ChevronDownIcon className="size-4 text-ink-4 transition-transform duration-(--dur-slide) ease-glide group-data-panel-open/c:rotate-180" />
  </CollapsibleTrigger>
  <CollapsiblePanel>
    <ul className="grid gap-1 px-3 pt-1 pb-2 text-[13px] text-ink-3">
      <li>Website 2024</li>
      <li>Price list</li>
      <li>Old portal</li>
    </ul>
  </CollapsiblePanel>
</Collapsible>

Rules

  • The trigger says what is inside and how much ("Three archived projects"), in sentence case.
  • `CollapsibleTrigger` comes unstyled: give it a row's shape, a hover and the focus ring (`focus-visible:shadow-(--focus-ring)`).
  • Turn the chevron from the trigger's open state (`group-data-panel-open/c:rotate-180` on a named group), never from state of your own.
  • Start it open with `defaultOpen`, or control it with `open` and `onOpenChange`.
  • The panel opens and shuts on the glide in --dur-glide, from its top: never a fixed height.