Collapsible
A collapsible panel controlled by a button.
import type { JSX } from '@solidjs/web';
import { Collapsible } from 'base-ui-solid/collapsible';
import styles from './index.module.css';
export default function ExampleCollapsible() {
return (
<Collapsible.Root class={styles.Collapsible}>
<Collapsible.Trigger class={styles.Trigger}>
Recovery keys
<CaretRightIcon class={styles.Icon} />
</Collapsible.Trigger>
<Collapsible.Panel class={styles.Panel}>
<div class={styles.Content}>
<div>alien-bean-pasta</div>
<div>wild-irish-burrito</div>
<div>horse-battery-staple</div>
</div>
</Collapsible.Panel>
</Collapsible.Root>
);
}
export function CaretRightIcon(props: JSX.IntrinsicElements['svg']) {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="currentColor"
{...props}
style={{ display: 'block' }}
>
<path d="M6 12V4l4.5 4z" />
</svg>
);
}
Anatomy
Import the component and assemble its parts:
import { Collapsible } from 'base-ui-solid/collapsible';
<Collapsible.Root>
<Collapsible.Trigger />
<Collapsible.Panel />
</Collapsible.Root>;
Examples
Hidden until found
The hiddenUntilFound prop hides the closed panel with hidden="until-found" so the browser can search its contents with find-in-page—Ctrl+F (Cmd+F on macOS)—and reveal the panel when a match is found. The closed panel always remains mounted in the DOM, which also makes its contents indexable by search engines.
Older browsers that don’t support hidden="until-found" keep the panel hidden until its trigger opens it, and find-in-page skips over the contents.
<Collapsible.Root>
<Collapsible.Trigger>Shipping details</Collapsible.Trigger>
<Collapsible.Panel hiddenUntilFound>Standard shipping takes 3–5 business days.</Collapsible.Panel>
</Collapsible.Root>
See the Accordion example for an interactive demo.
API reference
Root
Groups all parts of the collapsible.
Renders a <div> element.
defaultOpenbooleanfalse
open prop instead.booleanopenboolean—
defaultOpen prop instead.booleanonOpenChangefunction—
((open: boolean, eventDetails: Collapsible.Root.ChangeEventDetails) => void)disabledbooleanfalse
booleanclassfunction—
JSX.ClassValue | ((state) => JSX.ClassValue)stylefunction—
JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)renderfunction—
keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)Data attributes
data-open-—
-data-closed-—
-data-starting-style-—
-data-ending-style-—
-Attribute | Description | |
|---|---|---|
data-open | Present when the collapsible is open. | |
data-closed | Present when the collapsible is closed. | |
data-starting-style | Present when the collapsible begins animating in. | |
data-ending-style | Present when the collapsible is animating out. | |
Root.State
type CollapsibleRootState = {
/** Whether the collapsible panel is currently open. */
open: boolean;
/** Whether the component should ignore user interaction. */
disabled: boolean;
transitionStatus: TransitionStatus;
};Root.ChangeEventReason
type CollapsibleRootChangeEventReason = 'trigger-press' | 'none';Root.ChangeEventDetails
type CollapsibleRootChangeEventDetails = (
| { reason: 'trigger-press'; event: MouseEvent | PointerEvent | TouchEvent | KeyboardEvent }
| { reason: 'none'; event: Event }
) & {
/** Cancels Base UI from handling the event. */
cancel: () => void;
/** Allows the event to propagate in cases where Base UI will stop the propagation. */
allowPropagation: () => void;
/** Indicates whether the event has been canceled. */
isCanceled: boolean;
/** Indicates whether the event is allowed to propagate. */
isPropagationAllowed: boolean;
/** The element that triggered the event, if applicable. */
trigger: Element | undefined;
};Trigger
A button that opens and closes the collapsible panel.
Renders a <button> element.
nativeButtonbooleantrue
<button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>).booleanclassfunction—
JSX.ClassValue | ((state) => JSX.ClassValue)stylefunction—
JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)renderfunction—
keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)Data attributes
data-panel-open-—
-Attribute | Description | |
|---|---|---|
data-panel-open | Present when the collapsible panel is open. | |
Trigger.State
type CollapsibleTriggerState = {
/** Whether the collapsible panel is currently open. */
open: boolean;
/** Whether the component should ignore user interaction. */
disabled: boolean;
transitionStatus: TransitionStatus;
};Panel
A panel with the collapsible contents.
Renders a <div> element.
hiddenUntilFoundbooleanfalse
keepMounted prop and uses hidden="until-found"
to hide the element without removing it from the DOM.booleanclassfunction—
JSX.ClassValue | ((state) => JSX.ClassValue)stylefunction—
JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)keepMountedbooleanfalse
hiddenUntilFound is used.booleanrenderfunction—
keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)Data attributes
data-open-—
-data-closed-—
-data-starting-style-—
-data-ending-style-—
-Attribute | Description | |
|---|---|---|
data-open | Present when the collapsible panel is open. | |
data-closed | Present when the collapsible panel is closed. | |
data-starting-style | Present when the panel begins animating in. | |
data-ending-style | Present when the panel is animating out. | |
CSS variables
--collapsible-panel-heightnumber—
number--collapsible-panel-widthnumber—
numberCSS Variable | Description | |
|---|---|---|
--collapsible-panel-height | The collapsible panel’s height. | |
--collapsible-panel-width | The collapsible panel’s width. | |
Panel.State
type CollapsiblePanelState = {
/** The transition status of the component. */
transitionStatus: TransitionStatus;
/** Whether the collapsible panel is currently open. */
open: boolean;
/** Whether the component should ignore user interaction. */
disabled: boolean;
};