Collapsible
A trigger that shows and hides a panel. Unstyled, so components and applications bring their own look; for a styled one, use Progressive disclosure.
Code
import {KeyboardArrowDownIcon} from '@earendil-works/elanor-icons-react';
import {Collapsible, Text} from '@earendil-works/elanor-react';
import styles from './collapsible.module.css';
export default function CollapsibleDemo() {
return (
<Collapsible.Root>
<Collapsible.Trigger className={styles.trigger}>
<KeyboardArrowDownIcon className={styles.chevron} />
Recovery keys
</Collapsible.Trigger>
<Collapsible.Panel className={styles.panel}>
<Text className={styles.content}>
Store recovery keys somewhere safe. Each key works once.
</Text>
</Collapsible.Panel>
</Collapsible.Root>
);
} .trigger {
display: inline-flex;
align-items: center;
gap: var(--semantic-dimension-space-control-gap-small);
padding: 0;
border: 0;
background: none;
color: var(--semantic-color-text-primary);
font: var(--semantic-typography-ui-primary);
cursor: pointer;
}
.chevron {
transition: rotate var(--semantic-transition-movement-disclosure);
}
.trigger:not([data-panel-open]) .chevron {
rotate: -90deg;
}
.panel {
height: var(--collapsible-panel-height);
overflow: hidden;
transition: height var(--semantic-transition-movement-disclosure);
}
.panel[data-starting-style],
.panel[data-ending-style] {
height: 0;
}
.content {
padding-block-start: var(--semantic-dimension-space-padding-medium);
} Usage
import {Collapsible} from '@earendil-works/elanor-react';
<Collapsible.Root>
<Collapsible.Trigger />
<Collapsible.Panel />
</Collapsible.Root>;
defaultOpen starts the panel open; open and onOpenChange control it. To animate the panel, give it height: var(--collapsible-panel-height), overflow: hidden, and a height transition, and a height of 0 with data-starting-style and data-ending-style, as the demo’s stylesheet does.
Find in page
With hiddenUntilFound, the browser’s find in page searches a closed panel and opens it on a match. Leave the panel closed and search this page for a word in it.
A deploy that fails its checks never replaces the running version.
Code
import {KeyboardArrowDownIcon} from '@earendil-works/elanor-icons-react';
import {Collapsible, Text} from '@earendil-works/elanor-react';
import styles from './collapsible.module.css';
export default function CollapsibleHiddenUntilFoundDemo() {
return (
<Collapsible.Root>
<Collapsible.Trigger className={styles.trigger}>
<KeyboardArrowDownIcon className={styles.chevron} />
Rollbacks
</Collapsible.Trigger>
<Collapsible.Panel hiddenUntilFound className={styles.panel}>
<Text className={styles.content}>
A deploy that fails its checks never replaces the running version.
</Text>
</Collapsible.Panel>
</Collapsible.Root>
);
} .trigger {
display: inline-flex;
align-items: center;
gap: var(--semantic-dimension-space-control-gap-small);
padding: 0;
border: 0;
background: none;
color: var(--semantic-color-text-primary);
font: var(--semantic-typography-ui-primary);
cursor: pointer;
}
.chevron {
transition: rotate var(--semantic-transition-movement-disclosure);
}
.trigger:not([data-panel-open]) .chevron {
rotate: -90deg;
}
.panel {
height: var(--collapsible-panel-height);
overflow: hidden;
transition: height var(--semantic-transition-movement-disclosure);
}
.panel[data-starting-style],
.panel[data-ending-style] {
height: 0;
}
.content {
padding-block-start: var(--semantic-dimension-space-padding-medium);
} Static rendering
On pages rendered on the server without React in the browser, use the static parts. They render the same markup, and the behavior opens and closes the panel with the same states, so the same stylesheet animates it:
<Collapsible.StaticRoot defaultOpen>
<Collapsible.StaticTrigger />
<Collapsible.StaticPanel hiddenUntilFound />
</Collapsible.StaticRoot>
import {createCollapsible, enhance} from '@earendil-works/elanor-react';
enhance({collapsible: createCollapsible});
Without the behavior, closed panels stay hidden.
API
Collapsible.Root
Accepts Base UI Collapsible.Root props.
Collapsible.Trigger
Accepts Base UI Collapsible.Trigger props.
Collapsible.Panel
Accepts Base UI Collapsible.Panel props.
Collapsible.StaticRoot
A collapsible for pages without React in the browser; createCollapsible makes it work.
| Prop | Type | Default | Description |
|---|---|---|---|
data-elanor | string | - | The page's own behaviors for this element, attached after the component's. |
Also accepts Base UI Collapsible.Root props.
Collapsible.StaticTrigger
Renders <button>. Accepts its HTML attributes and ref.
Collapsible.StaticPanel
Accepts Base UI Collapsible.Panel props.