Collapsible
An interactive component that expands and collapses to show or hide content.
veritheme.js
JS init: automatic
Default
A basic collapsible with a trigger button and expandable content area.
@peduarte starred 3 repositories
<div class="vt-w-full vt-max-w-sm" data-collapsible="">
<div class="vt-flex vt-items-center vt-justify-between">
<h4 class="vt-text-sm vt-font-semibold">@peduarte starred 3 repositories</h4>
<button data-collapsible-trigger="" class="vt-inline-flex vt-items-center vt-justify-center vt-rounded-lg vt-border vt-border-border-default vt-bg-surface-card vt-h-8 vt-w-8 vt-hover:bg-surface-subtle vt-transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" data-collapsible-icon="true" class="lucide lucide-chevron-down vt-w-4 vt-h-4 vt-transition-transform vt-duration-200">
<path d="m6 9 6 6 6-6"></path>
</svg>
</button>
</div>
<div class="vt-rounded-lg vt-border vt-border-border-default vt-px-4 vt-py-2 vt-text-sm vt-font-mono vt-mt-3">
@radix-ui/primitives
</div>
<div data-collapsible-content="" class="vt-hidden">
<div class="vt-rounded-lg vt-border vt-border-border-default vt-px-4 vt-py-2 vt-text-sm vt-font-mono vt-mt-2">
@radix-ui/colors
</div>
<div class="vt-rounded-lg vt-border vt-border-border-default vt-px-4 vt-py-2 vt-text-sm vt-font-mono vt-mt-2">
@stitches/react
</div>
</div>
</div>
With Animation
Content expands and collapses with a smooth height transition.
@peduarte starred 3 repositories
<div class="vt-w-full vt-max-w-sm" data-collapsible="" data-collapsible-animated="">
<div class="vt-flex vt-items-center vt-justify-between">
<h4 class="vt-text-sm vt-font-semibold">@peduarte starred 3 repositories</h4>
<button data-collapsible-trigger="" class="vt-inline-flex vt-items-center vt-justify-center vt-rounded-lg vt-border vt-border-border-default vt-bg-surface-card vt-h-8 vt-w-8 vt-hover:bg-surface-subtle vt-transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" data-collapsible-icon="true" class="lucide lucide-chevron-down vt-w-4 vt-h-4 vt-transition-transform vt-duration-200">
<path d="m6 9 6 6 6-6"></path>
</svg>
</button>
</div>
<div class="vt-rounded-lg vt-border vt-border-border-default vt-px-4 vt-py-2 vt-text-sm vt-font-mono vt-mt-3">
@radix-ui/primitives
</div>
<div data-collapsible-content="" class="vt-overflow-hidden vt-transition-all vt-duration-300 vt-ease-in-out vt-inline-e54a108cdd">
<div class="vt-rounded-lg vt-border vt-border-border-default vt-px-4 vt-py-2 vt-text-sm vt-font-mono vt-mt-2">
@radix-ui/colors
</div>
<div class="vt-rounded-lg vt-border vt-border-border-default vt-px-4 vt-py-2 vt-text-sm vt-font-mono vt-mt-2">
@stitches/react
</div>
</div>
</div>
Nested
A collapsible inside another collapsible for hierarchical content like file trees.
<div class="vt-w-full vt-max-w-sm" data-collapsible="">
<div class="vt-flex vt-items-center vt-gap-2">
<button data-collapsible-trigger="" class="vt-inline-flex vt-items-center vt-justify-center vt-rounded-lg vt-border vt-border-border-default vt-bg-surface-card vt-h-8 vt-w-8 vt-hover:bg-surface-subtle vt-transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" data-collapsible-icon="true" class="lucide lucide-chevron-down vt-w-4 vt-h-4 vt-transition-transform vt-duration-200">
<path d="m6 9 6 6 6-6"></path>
</svg>
</button>
<div class="vt-flex vt-items-center vt-gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path>
</svg>
<span class="vt-text-sm vt-font-semibold">Project Files</span>
</div>
</div>
<div data-collapsible-content="" class="vt-hidden">
<div class="vt-ml-10 vt-mt-1 vt-flex vt-flex-col vt-gap-1">
<!-- Nested collapsible: src/ -->
<div data-collapsible="">
<div class="vt-flex vt-items-center vt-gap-2">
<button data-collapsible-trigger="" class="vt-inline-flex vt-items-center vt-justify-center vt-rounded-lg vt-border vt-border-border-default vt-bg-surface-card vt-h-7 vt-w-7 vt-hover:bg-surface-subtle vt-transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" data-collapsible-icon="true" class="lucide lucide-chevron-down vt-w-3 vt-h-3 vt-transition-transform vt-duration-200">
<path d="m6 9 6 6 6-6"></path>
</svg>
</button>
<div class="vt-flex vt-items-center vt-gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path>
</svg>
<span class="vt-text-sm vt-font-medium">src/</span>
</div>
</div>
<div data-collapsible-content="" class="vt-hidden">
<div class="vt-ml-10 vt-mt-1 vt-flex vt-flex-col vt-gap-1">
<div class="vt-flex vt-items-center vt-gap-2 vt-py-1">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
</svg>
<span class="vt-text-sm vt-text-foreground-muted">index.ts</span>
</div>
<div class="vt-flex vt-items-center vt-gap-2 vt-py-1">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
</svg>
<span class="vt-text-sm vt-text-foreground-muted">utils.ts</span>
</div>
<div class="vt-flex vt-items-center vt-gap-2 vt-py-1">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
</svg>
<span class="vt-text-sm vt-text-foreground-muted">styles.css</span>
</div>
</div>
</div>
</div>
<!-- Static files -->
<div class="vt-flex vt-items-center vt-gap-2 vt-py-1 vt-ml-10">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
</svg>
<span class="vt-text-sm vt-text-foreground-muted">package.json</span>
</div>
<div class="vt-flex vt-items-center vt-gap-2 vt-py-1 vt-ml-10">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-text-foreground-muted">
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
</svg>
<span class="vt-text-sm vt-text-foreground-muted">tsconfig.json</span>
</div>
</div>
</div>
</div>
Controlled
Collapsibles with text-based triggers that toggle between "Show more" and "Show less".
Collapsible components are useful for toggling the visibility of content. They can be used to create expandable sections, FAQs, and more.
This pattern is commonly used in settings panels, sidebars, and content-heavy pages where you want to reduce visual clutter while keeping information accessible.
You can also use collapsible components to progressively disclose information to users as they need it.
Progressive disclosure helps reduce cognitive load by showing only the most essential information upfront, with additional details available on demand.
<div class="vt-flex vt-flex-col vt-gap-8 vt-w-full vt-max-w-sm">
<!-- Expanded by default -->
<div data-collapsible="" data-collapsible-open="">
<p class="vt-text-sm vt-text-foreground-primary">
Collapsible components are useful for toggling the visibility of content. They can be used to create expandable sections, FAQs, and more.
</p>
<div data-collapsible-content="">
<p class="vt-text-sm vt-text-foreground-muted vt-mt-2">
This pattern is commonly used in settings panels, sidebars, and content-heavy pages where you want to reduce visual clutter while keeping information accessible.
</p>
</div>
<button data-collapsible-trigger="" class="vt-text-sm vt-text-info-fill vt-font-medium vt-cursor-pointer vt-mt-2 vt-hover:underline">
<span data-collapsible-label-collapse="">Show less</span>
<span data-collapsible-label-expand="" class="vt-hidden">Show more</span>
</button>
</div>
<!-- Collapsed by default -->
<div data-collapsible="">
<p class="vt-text-sm vt-text-foreground-primary">
You can also use collapsible components to progressively disclose information to users as they need it.
</p>
<div data-collapsible-content="" class="vt-hidden">
<p class="vt-text-sm vt-text-foreground-muted vt-mt-2">
Progressive disclosure helps reduce cognitive load by showing only the most essential information upfront, with additional details available on demand.
</p>
</div>
<button data-collapsible-trigger="" class="vt-text-sm vt-text-info-fill vt-font-medium vt-cursor-pointer vt-mt-2 vt-hover:underline">
<span data-collapsible-label-collapse="" class="vt-hidden">Show less</span>
<span data-collapsible-label-expand="">Show more</span>
</button>
</div>
</div>
Guidelines
Progressively disclose secondary content behind a trigger; keep essential information always visible.
Progressive disclosure keeps the interface tidy.
Extra detail appears only when the reader asks for it.
Account
Payment failed — action required
API Reference
All CSS classes and data attributes.
| Class | Type | Description |
|---|---|---|
data-collapsible |
Data | Root hook — the JS bundle wires trigger and content |
data-collapsible-trigger |
Data | Click target that toggles the section |
data-collapsible-content |
Data | Collapsible region — height animates open/closed |
data-collapsible-open |
State | Present on the root while expanded |
data-collapsible-icon |
Data | Chevron that rotates with the open state |
Accessibility
Keyboard and screen reader support.
| Feature | Details |
|---|---|
| Trigger | The trigger is a button with aria-expanded reflecting the open state |
| Region | Content is referenced via aria-controls and hidden from the tab order when closed |
| Keyboard | Enter and Space toggle; focus stays on the trigger |