Collapsible
A panel that shows and hides with height motion you can reverse mid-way, without jumping the layout.
Used in Pro blocks: Agent Todos, Chat Sidebar, Stack Trace, and 9 more
@preetsuthar17 starred 3 repositories
pnpm dlx shadcn@latest add https://hextaui.com/r/collapsible.jsonAdds the component, the HextaUI theme tokens and any HextaUI components it depends on.
Add the theme tokens to your global CSS, if you haven’t yet.
Install the dependencies.
pnpm add @base-ui/react @tabler/icons-react cnCopy and paste the following code into your project.
components/ui/collapsible.tsx Update the import paths to match your project setup.
defaultOpen starts the panel open without taking over its state.
The panel sits above its trigger. When it closes, the gap in the parent’s flex layout collapses in the same animation, so the button below never jumps.
Pass open and onOpenChange to drive the panel from your own state. Toggling mid-animation reverses from where the panel is.
disabled on the root keeps the panel in its current state and makes the trigger ignore clicks and keys.
Children of <CollapsibleTriggerIcon /> replace the chevron. Style the open state with group-data-panel-open/collapsible-trigger.
Each folder is its own collapsible. Outer panels grow smoothly as inner ones open.
Closed panels stay in the page with hidden=“until-found”, so Cmd/Ctrl+F for “webhook” opens this one.
Set hiddenUntilFound={false} on the content to remove it from the DOM while closed, for heavy panels you don’t want rendered up front.
Unbroken strings wrap inside the panel instead of widening the page.
Chevrons mirror and nested indents follow the reading direction.
| Key | Action |
|---|---|
| EnterSpace | Opens or closes the panel from the trigger. |
| Tab | Moves focus from the trigger into the open panel. Closed panels are skipped. |
- The trigger gets
aria-expandedandaria-controlsautomatically. - Icon-only triggers need an
aria-label.<CollapsibleTriggerIcon />is hidden from assistive tech. - With reduced motion the panel opens and closes without animating its height.
Built on the Base UI collapsible. Every part accepts the props of the primitive it wraps.
| Prop | Type | Default |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="collapsible" | Target the root in CSS. |
data-open | Present when open. |
data-closed | Present when closed. |
| Prop | Type | Default |
|---|---|---|
renderUsually a Button. | ReactElement | (props, state) => ReactElement | <button> |
| Attribute | Description |
|---|---|
data-slot="collapsible-trigger" | Target the trigger in CSS. |
data-panel-open | Present when the panel is open. Style children with group-data-panel-open/collapsible-trigger. |
| Prop | Type | Default |
|---|---|---|
childrenThe default chevron flips when the panel opens. | ReactNode | <IconChevronDown /> |
render | ReactElement | (props, state) => ReactElement | <span> |
| Attribute | Description |
|---|---|
data-slot="collapsible-trigger-icon" | Hidden from assistive tech. Nudges down while the trigger is pressed. |
| Prop | Type | Default |
|---|---|---|
classNameApplied to the inner wrapper, so padding never fights the height animation. | string | – |
hiddenUntilFoundKeeps the closed panel in the DOM so page search can find and open it. | boolean | true |
keepMountedIgnored while hiddenUntilFound is on. | boolean | false |
| Attribute | Description |
|---|---|
data-slot="collapsible-content" | Target the panel in CSS. |
data-open | Present when open. |
data-closed | Present when closed. |
data-starting-style | Present while the panel animates in. |
data-ending-style | Present while the panel animates out. |
--collapsible-panel-height | The panel’s measured height. |
--collapsible-panel-width | The panel’s measured width. |
--collapsible-gap-start | The parent’s gap before the panel, collapsed while closed. |
--collapsible-gap-end | The parent’s gap after the panel, collapsed while closed. |
- AccordionStacked headings that each reveal a panel, with height motion you can reverse mid-way and panels that stay searchable while closed.
- Aspect ratioA box that holds its shape before media loads, shimmers while loading, fades the media in and falls back when it fails.
- CarouselNative scroll-snap slides with momentum on touch, mouse dragging, arrow keys, dots, thumbnails and an autoplay that pauses when it should.
- ResizablePanels you can drag apart, with a quiet divider that wakes up on hover, sizes that glide on reset or collapse, and layouts that persist.
- Scroll areaNative scrolling with a minimal scrollbar, edges that fade only where there’s more to see, and an optional peek that cuts the last item in half.
- SeparatorA hairline that divides content horizontally or vertically, with an optional label and a decorative mode for purely visual lines.
Used in Pro blocks
Blocks that build on Collapsible.
- Agent TodosThe plan an agent keeps while it works, one line per step. Handles steps in progress, failed steps and plan changes mid-run.
- Chat SidebarThe sidebar of a chat app, with pinned chats, projects and recents. Handles rename in place, delete with undo and chats still replying.
- Stack TraceA crash shown the way a developer reads it. Your code comes first, framework frames fold away and every cause is listed in order.
- SubagentsThe runs an agent hands to other agents, one line per run. Handles parallel runs, stop and retry, and a summary once each run is done.
- Test ResultsAn agent’s test run, shown as it happens. Tests stream in and fold into a summary, with every failure left open and its diff in view.
- ThinkingThe thinking view of an AI chat. A live label follows each step, searches and sources fold into a trail, and citations sit beside the answer.
Every block comes with HextaUI Pro, and Prompt Input is free.