moduix

Collapsible

A disclosure control that opens and closes a single panel of content.

API Reference

Original primitive API

Behavior, accessibility details, and low-level props are documented by Base UI.

Base UI API

Basic

import {  Collapsible,  CollapsibleTrigger,  CollapsiblePanel,} from "moduix";export function CollapsibleDemo() {  return (    <Collapsible className={styles.root}>      <CollapsibleTrigger>Recovery keys</CollapsibleTrigger>      <CollapsiblePanel>        <ul className={styles.keysList}>          {recoveryKeys.map((key) => (            <li key={key}>{key}</li>          ))}        </ul>      </CollapsiblePanel>    </Collapsible>  );}
.root {  width: 16rem;}.keysList {  display: flex;  flex-direction: column;  gap: var(--spacing-1);  margin: 0;  padding-inline-start: var(--spacing-5);}
const recoveryKeys = ["alien-bean-pasta", "wild-irish-burrito", "horse-battery-staple"];

Full list of component variables available for project-level overrides.

PropertyDefaultDescription
--collapsible-colorvar(--color-foreground)Controls root text color.
--collapsible-disabled-opacityvar(--opacity-disabled)Controls disabled opacity.
--collapsible-focus-ring-colorvar(--color-ring)Controls trigger focus ring color.
--collapsible-focus-ring-offsetvar(--border-width-sm)Controls trigger focus ring offset.
--collapsible-focus-ring-widthvar(--border-width-sm)Controls trigger focus ring width.
--collapsible-icon-open-transformrotate(90deg)Controls icon transform when the panel is open.
--collapsible-icon-size0.75remControls trigger icon size.
--collapsible-icon-transitionvar(--transition-default)Controls icon transition.
--collapsible-panel-colorvar(--color-muted-foreground)Controls panel text color.
--collapsible-panel-font-sizevar(--text-sm)Controls panel font size.
--collapsible-panel-line-heightvar(--line-height-text-sm)Controls panel line height.
--collapsible-panel-transitionvar(--transition-default)Controls panel open and close transition.
--collapsible-trigger-bgtransparentControls trigger background color.
--collapsible-trigger-bg-activevar(--collapsible-trigger-bg-hover)Controls trigger background color while pressed.
--collapsible-trigger-bg-hovervar(--collapsible-trigger-bg)Controls trigger background color on hover.
--collapsible-trigger-colorvar(--collapsible-color)Controls trigger text color.
--collapsible-trigger-font-sizevar(--text-sm)Controls trigger font size.
--collapsible-trigger-gapvar(--spacing-2)Controls trigger content gap.
--collapsible-trigger-line-heightvar(--line-height-text-sm)Controls trigger line height.
--collapsible-trigger-padding-x0Controls trigger horizontal padding.
--collapsible-trigger-padding-y0Controls trigger vertical padding.
--collapsible-trigger-radius0Controls trigger corner radius.
--collapsible-trigger-transitionvar(--transition-default)Controls trigger color and background transition.

Interactive variables scoped for docs preview without changing size scale tokens.

PropertyValueDefaultDescription
--collapsible-colorvar(--color-foreground)Controls root text color.
--collapsible-disabled-opacityvar(--opacity-disabled)Controls disabled opacity.
--collapsible-focus-ring-colorvar(--color-ring)Controls trigger focus ring color.
--collapsible-focus-ring-offsetvar(--border-width-sm)Controls trigger focus ring offset.
--collapsible-focus-ring-widthvar(--border-width-sm)Controls trigger focus ring width.
--collapsible-icon-open-transformrotate(90deg)Controls icon transform when the panel is open.
--collapsible-icon-size0.75remControls trigger icon size.
--collapsible-icon-transitionvar(--transition-default)Controls icon transition.
--collapsible-panel-colorvar(--color-muted-foreground)Controls panel text color.
--collapsible-panel-font-sizevar(--text-sm)Controls panel font size.
--collapsible-panel-line-heightvar(--line-height-text-sm)Controls panel line height.
--collapsible-panel-transitionvar(--transition-default)Controls panel open and close transition.
--collapsible-trigger-bgtransparentControls trigger background color.
--collapsible-trigger-bg-activevar(--collapsible-trigger-bg-hover)Controls trigger background color while pressed.
--collapsible-trigger-bg-hovervar(--collapsible-trigger-bg)Controls trigger background color on hover.
--collapsible-trigger-colorvar(--collapsible-color)Controls trigger text color.
--collapsible-trigger-font-sizevar(--text-sm)Controls trigger font size.
--collapsible-trigger-gapvar(--spacing-2)Controls trigger content gap.
--collapsible-trigger-line-heightvar(--line-height-text-sm)Controls trigger line height.
--collapsible-trigger-padding-x0Controls trigger horizontal padding.
--collapsible-trigger-padding-y0Controls trigger vertical padding.
--collapsible-trigger-radius0Controls trigger corner radius.
--collapsible-trigger-transitionvar(--transition-default)Controls trigger color and background transition.

Anatomy

Collapsible groups one toggle control and one panel that share the same open state. Keep CollapsibleTrigger and CollapsiblePanel inside the same root so keyboard and accessibility wiring stay connected.

Collapsible
├─ CollapsibleTrigger
│  └─ label
└─ CollapsiblePanel
   └─ content
<Collapsible>
  <CollapsibleTrigger>Recovery keys</CollapsibleTrigger>
  <CollapsiblePanel>
    <div className={styles.panelContent}>Store these keys somewhere safe.</div>
  </CollapsiblePanel>
</Collapsible>
PartRole
CollapsibleRoot state machine. Controls open, defaultOpen, disabled, and onOpenChange.
CollapsibleTriggerInteractive toggle button. Opens or closes the panel, receives open/disabled attributes, and renders an icon.
CollapsibleTriggerIconAdvanced visual state marker. Use directly only when manually composing trigger contents.
CollapsiblePanelCollapsible content region. Put spacing/surface wrappers inside it for cleaner animations.

CollapsibleTrigger renders its icon internally so the common composition stays compact. Use icon, hideIcon, classNames.icon, and slotProps.icon when you need to replace, remove, style, or pass props to that internal slot. CollapsibleTriggerIcon is still exported for advanced manual composition, but most projects do not need it.

Collapsible does not use service slots like portal, backdrop, or viewport. In most cases, keep the default structure and customize visible parts: the root, trigger, icon slot, panel, and content wrapper inside the panel.

Composition

Use Collapsible for root state and behavior props such as open, defaultOpen, onOpenChange, and disabled.

All parts in this component are visible slots. Style Collapsible, CollapsibleTrigger, and CollapsiblePanel directly with className. Use classNames.icon for the icon rendered inside CollapsibleTrigger, or compose CollapsibleTriggerIcon manually when you need full control over trigger children. All Base UI behavior props such as render, nativeButton, keepMounted, and hiddenUntilFound pass through to the matching primitive part.

Examples

Default Open

Use defaultOpen when the panel should be expanded on first render.

  • alien-bean-pasta
  • wild-irish-burrito
  • horse-battery-staple
import {  Collapsible,  CollapsibleTrigger,  CollapsiblePanel,} from "moduix";export function DefaultOpenCollapsibleDemo() {  return (    <Collapsible defaultOpen className={styles.root}>      <CollapsibleTrigger>Recovery keys</CollapsibleTrigger>      <CollapsiblePanel>        <ul className={styles.keysList}>          {recoveryKeys.map((key) => (            <li key={key}>{key}</li>          ))}        </ul>      </CollapsiblePanel>    </Collapsible>  );}
.root {  width: 16rem;}.keysList {  display: flex;  flex-direction: column;  gap: var(--spacing-1);  margin: 0;  padding-inline-start: var(--spacing-5);}
const recoveryKeys = ["alien-bean-pasta", "wild-irish-burrito", "horse-battery-staple"];

Controlled

Control open from React state when the collapsible needs to coordinate with other UI.

Current state: closed
import {  Collapsible,  CollapsibleTrigger,  CollapsiblePanel,} from "moduix";import { useState } from "react";export function ControlledCollapsibleDemo() {  const [open, setOpen] = useState(false);  return (    <Collapsible open={open} onOpenChange={setOpen} className={styles.root}>      <CollapsibleTrigger>Recovery keys</CollapsibleTrigger>      <CollapsiblePanel>        <ul className={styles.keysList}>          {recoveryKeys.map((key) => (            <li key={key}>{key}</li>          ))}        </ul>      </CollapsiblePanel>      <span className={styles.status}>Current state: {open ? "open" : "closed"}</span>    </Collapsible>  );}
.root {  width: 16rem;}.keysList {  display: flex;  flex-direction: column;  gap: var(--spacing-1);  margin: 0;  padding-inline-start: var(--spacing-5);}.status {  margin-top: var(--spacing-2);  color: var(--color-muted-foreground);  font-size: var(--text-xs);  line-height: var(--line-height-text-xs);}
const recoveryKeys = ["alien-bean-pasta", "wild-irish-burrito", "horse-battery-staple"];

Disabled

Set disabled on the root when the trigger should be visible but unavailable for interaction.

import {  Collapsible,  CollapsibleTrigger,  CollapsiblePanel,} from "moduix";export function DisabledCollapsibleDemo() {  return (    <Collapsible disabled className={styles.root}>      <CollapsibleTrigger>Recovery keys</CollapsibleTrigger>      <CollapsiblePanel>        <ul className={styles.keysList}>          {recoveryKeys.map((key) => (            <li key={key}>{key}</li>          ))}        </ul>      </CollapsiblePanel>    </Collapsible>  );}
.root {  width: 16rem;}.keysList {  display: flex;  flex-direction: column;  gap: var(--spacing-1);  margin: 0;  padding-inline-start: var(--spacing-5);}
const recoveryKeys = ["alien-bean-pasta", "wild-irish-burrito", "horse-battery-staple"];

Hidden Until Found

Use hiddenUntilFound when browser page search should be able to find and expand hidden panel content.

import {  Collapsible,  CollapsibleTrigger,  CollapsiblePanel,} from "moduix";export function HiddenUntilFoundCollapsibleDemo() {  return (    <Collapsible className={styles.root}>      <CollapsibleTrigger>Searchable recovery keys</CollapsibleTrigger>      <CollapsiblePanel hiddenUntilFound>        <ul className={styles.keysList}>          {recoveryKeys.map((key) => (            <li key={key}>{key}</li>          ))}        </ul>      </CollapsiblePanel>    </Collapsible>  );}
.root {  width: 16rem;}.keysList {  display: flex;  flex-direction: column;  gap: var(--spacing-1);  margin: 0;  padding-inline-start: var(--spacing-5);}
const recoveryKeys = ["alien-bean-pasta", "wild-irish-burrito", "horse-battery-staple"];

Custom Icon And Styles

Pass icon to replace the default visual marker and style it with classNames.icon. Use className on the root, trigger, and panel slots when styling with CSS Modules, Tailwind CSS, or CSS-in-JS. Put your own wrapper inside the panel when the content needs layout or surface styles.

import {  Collapsible,  CollapsibleTrigger,  CollapsiblePanel,  ChevronDownIcon,} from "moduix";export function CustomStylesCollapsibleDemo() {  return (    <Collapsible className={styles.customRoot}>      <CollapsibleTrigger        className={styles.customTrigger}        icon={<ChevronDownIcon />}        classNames={{ icon: styles.customTriggerIcon }}      >        Styled recovery keys      </CollapsibleTrigger>      <CollapsiblePanel className={styles.customPanel}>        <div className={styles.customPanelContent}>          <ul className={styles.keysList}>            {recoveryKeys.map((key) => (              <li key={key}>{key}</li>            ))}          </ul>        </div>      </CollapsiblePanel>    </Collapsible>  );}
.customRoot {  width: 16rem;  color: var(--color-foreground);}.customTrigger {  padding: var(--spacing-2) var(--spacing-3);  border-radius: var(--radius-md);  background-color: var(--color-muted);  color: var(--color-foreground);}@media (hover: hover) {  .customTrigger:hover {    background-color: var(--color-accent);  }}.customTriggerIcon {  --collapsible-icon-open-transform: rotate(180deg);  color: var(--color-primary);}.customPanel {  color: var(--color-muted-foreground);}.customPanelContent {  margin-top: var(--spacing-1);  padding: var(--spacing-2) var(--spacing-3);  border-radius: var(--radius-md);  background-color: var(--color-muted);}.keysList {  display: flex;  flex-direction: column;  gap: var(--spacing-1);  margin: 0;  padding-inline-start: var(--spacing-5);}
const recoveryKeys = ["alien-bean-pasta", "wild-irish-burrito", "horse-battery-staple"];

On this page