Collapsible
A single expand/collapse section. Composes the `disclosure` family (trigger, panel, content). An accordion is a group of collapsibles with coordination; a collapsible is one section on its own.
npx shadcn@latest add @fragiola/collapsibledata-panel-open.Show code
"use client";
import { ChevronDownIcon } from "lucide-react";
import type { ReactNode } from "react";
import { Collapsible } from "#/ui/collapsible";
// The floor is palette-surface. The collapsible shares the disclosure family
// with the accordion — the trigger, panel and content read roles from the
// floor. Shows: default closed, default open, and disabled.
//
// The root carries a width (see accordion-demo): a widthless root resizes
// with the open panel and the demo jumps.
export default function CollapsibleDemo() {
return (
<div className="palette-surface flex w-full max-w-xl flex-col gap-6 rounded-lg border border-palette-line bg-palette-base p-6">
<Row label="default closed">
<Collapsible.Root>
<Collapsible.Trigger>
Click to expand
<ChevronDownIcon className="size-4 shrink-0 transition-transform duration-200 group-data-panel-open:rotate-180" />
</Collapsible.Trigger>
<Collapsible.Panel>
<Collapsible.Content>
A collapsible is a single expand/collapse section.
An accordion is a group of collapsibles with
coordination. Both share the same trigger, panel and
content from the disclosure family.
</Collapsible.Content>
</Collapsible.Panel>
</Collapsible.Root>
</Row>
<Row label="default open">
<Collapsible.Root defaultOpen>
<Collapsible.Trigger>
Already open
<ChevronDownIcon className="size-4 shrink-0 transition-transform duration-200 group-data-panel-open:rotate-180" />
</Collapsible.Trigger>
<Collapsible.Panel>
<Collapsible.Content>
This section starts open. The chevron is already
rotated because the trigger has{" "}
<code>data-panel-open</code>.
</Collapsible.Content>
</Collapsible.Panel>
</Collapsible.Root>
</Row>
<Row label="disabled">
<Collapsible.Root disabled>
<Collapsible.Trigger>
Disabled
<ChevronDownIcon className="size-4 shrink-0 transition-transform duration-200 group-data-panel-open:rotate-180" />
</Collapsible.Trigger>
<Collapsible.Panel>
<Collapsible.Content>
This collapsible is disabled.
</Collapsible.Content>
</Collapsible.Panel>
</Collapsible.Root>
</Row>
</div>
);
}
function Row({ label, children }: { label: string; children: ReactNode }) {
return (
<div className="flex flex-col gap-2">
<span className="text-xs font-mono text-palette-accent/85">
{label}
</span>
{children}
</div>
);
}
Style families
collapsible and accordion render from the same disclosure source. The only difference is coordination — behaviour from the primitive, not a style variant. The zero-variant rule is preserved.
Parts
| Part | Source |
|---|---|
Root | Base UI Collapsible |
Trigger | disclosure.trigger() |
Panel | disclosure.panel() |
Content | disclosure.content() |
Accordion
A group of expand/collapse items with coordination. Composes the `disclosure` family (trigger, panel, content). The only things this component declares for itself are Root, Item and Header — the coordination points.
Tabs
A strip of triggers where one is current, with an animated indicator. The indicator uses the primitive's CSS variables (`--active-tab-*`), not React measurement — it tracks on resize and under RTL automatically.