Disclosure
A disclosure hides one block of content behind a button. It is Headless
UI's Disclosure in a bordered card: the button spans the top, the
chevron turns when open, and the panel unmounts while closed. For a
stack of these where only one is open at a time, use
Accordion.
import Disclosure from '@zuilib/components/disclosure'
Basic
Loading example
Open by default
Headless UI's Disclosure is uncontrolled, so defaultOpen sets the
initial state and the button owns it from there. There is no
open/onChange pair. The current state is readable from
data-state on the root.
Loading example
With form controls
panelClassName is merged onto the panel, which is the usual place for
spacing between fields. title accepts any node.
Loading example
Props
DisclosureProps extends the <div> attributes of the root card
(minus title and children) with:
| Prop | Type | Default | Description |
|---|---|---|---|
titlerequired | ReactNode | — | Contents of the toggle button |
childrenrequired | ReactNode | — | Contents of the panel; unmounted while closed |
defaultOpen | boolean | false | Initial state; the component is uncontrolled |
className | string | — | Merged last onto the root card |
buttonClassName | string | — | Merged last onto the toggle button |
panelClassName | string | — | Merged last onto the panel |
Slots
| Slot | Element | Notes |
|---|---|---|
[data-slot="disclosure"] | div | Root card. data-state="open" | "closed" |
[data-slot="disclosure-button"] | button | The toggle. Headless UI adds data-open, data-hover, data-focus, data-disabled |
[data-slot="disclosure-title"] | span | Wraps title inside the button |
[data-slot="disclosure-icon"] | svg | Chevron; rotated 180° while open |
[data-slot="disclosure-panel"] | div | The content; present only while open |
/* Consumer CSS: flat, borderless disclosures */
[data-slot="disclosure"] {
border: 0;
border-radius: 0;
}
[data-slot="disclosure"][data-state="open"] > [data-slot="disclosure-button"] {
background-color: var(--muted);
}
Tokens
| Token | Used for |
|---|---|
--border, --card | Card border and background |
--foreground, --muted-foreground | Title text and chevron |
--muted | Button hover (at 50%) |
--radius-lg | Card corners |
--ring | Keyboard focus ring (inset) |
--duration-fast, --duration-normal | Hover colour and chevron rotation |
Accessibility
- The toggle is a real
<button>witharia-expandedandaria-controlspointing at the panel (Headless UI). - Enter and Space toggle; the button is in the normal tab order.
- Keyboard focus draws an inset 2px
--ringring so it stays inside the card's rounded border. - The chevron rotation respects
prefers-reduced-motion. - The panel is unmounted while closed, so hidden content is not reachable by assistive technology or tab.