Skip to content

Early previewhamur is not on npm yet. The components are being built in the open, follow along on GitHub.

DisclosureReact

Collapsible

A collapsible panel controlled by a button.

Rendered by React 19.3.1

Loading React…
import * as React from 'react'
import { Collapsible } from '@hamur/react/collapsible'

export default function CollapsibleExample() {
  const [open, setOpen] = React.useState(false)
  return (
    <div className="stack">
      <Collapsible.Root className="collapsible" onOpenChange={setOpen}>
        <Collapsible.Trigger className="button">
          Recovery keys
        </Collapsible.Trigger>
        <Collapsible.Panel className="collapsible-panel">
          <ul className="keys">
            <li>alien-bean-pasta</li>
            <li>wasp-eagle-engine</li>
            <li>ping-pong-table</li>
          </ul>
        </Collapsible.Panel>
      </Collapsible.Root>
      <p className="muted">Panel is {open ? 'open' : 'closed'}</p>
    </div>
  )
}
177Tests passing in React · 0 failing
9.5 KiBSize
1.10 msOpen
0.50 msClose
15.0 msOpenMutations
8.00 msCloseMutations
0.45 MiBMemory
productdevbook and 18 upstream authors12 commits · last

Installation

npm i @hamur/react

Not on npm yet. The package goes out under the chosen name.

Anatomy

Import the component and assemble its parts:

<Collapsible.Root>
  <Collapsible.Trigger />
  <Collapsible.Panel />
</Collapsible.Root>

Examples

The demo at the top is the one example this component has so far.

API reference

7 props across 3 parts, in React syntax. className, style, render are listed once, under Shared props.

PanelCollapsible.Panel

A panel with the collapsible contents. Renders a <div>.

Panel props
PropTypeDefault
hiddenUntilFoundAllows the browser's built-in page search to find and expand the panel contents.booleanfalse
keepMountedWhether to keep the element in the DOM while the panel is hidden.booleanfalse
Panel data attributes
Data attributeDescription
data-openPresent when the collapsible panel is open.
data-closedPresent when the collapsible panel is closed.
data-starting-stylePresent when the panel begins animating in.
data-ending-stylePresent when the panel is animating out.
Panel CSS variables
CSS variableDescription
--collapsible-panel-heightThe collapsible panel's height.
--collapsible-panel-widthThe collapsible panel's width.

RootCollapsible.Root

Groups all parts of the collapsible. Renders a <div>.

Root props
PropTypeDefault
defaultOpenWhether the collapsible panel is initially open.booleanfalse
openWhether the collapsible panel is currently open.boolean—
onOpenChangeEvent handler called when the panel is opened or closed.((open: boolean, eventDetails: CollapsibleRootChangeEventDetails) => void)—
disabledWhether the component should ignore user interaction.booleanfalse
Root data attributes
Data attributeDescription
data-openPresent when the collapsible is open.
data-closedPresent when the collapsible is closed.
data-starting-stylePresent when the collapsible begins animating in.
data-ending-stylePresent when the collapsible is animating out.

TriggerCollapsible.Trigger

A button that opens and closes the collapsible panel. Renders a <button>.

Trigger props
PropTypeDefault
nativeButtonWhether the component renders a native <button> element when replacing itbooleantrue
Trigger data attributes
Data attributeDescription
data-panel-openPresent when the collapsible panel is open.
data-disabledPresent when the trigger or the collapsible is disabled.

Shared props

Every part that renders an element takes these.

Shared props
PropType
classNameCSS class applied to the element, or a function that returns a class based on the component's state.string | ((state: State) => string | undefined)
styleStyle applied to the element, or a function that returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>

Keyboard and accessibility

Keyboard

Keyboard
KeysDoesPart
EnterSpaceOpens or closes the panelTrigger
EnterSpaceDoes nothing while the collapsible is disabledTrigger

Accessibility

What the parts set
PartSetsSo that
Triggeraria-expanded, aria-controls to the panel while opena screen reader says whether the section is open and where it is
Panelhidden="until-found" with hiddenUntilFoundfind in page reaches text in the closed panel and opens it

Focus order

  1. Trigger is one tab stop.
  2. The content of an open Panel follows; a closed Panel's content is skipped.