Collapse

Animated show/hide of a region; hidden content leaves the tab order.

import { ... } from '@corndev/ui'

The region animates to its natural height, and leaves the tab order once it is shut.

HTML

No JavaScript required — these classes are the whole component.

<button type="button" aria-expanded="true" aria-controls="details">Details</button>
<div id="details" class="corn-collapse" data-open>
  <div class="corn-collapse-inner">…</div>
</div>

Classes

Class
.corn-collapse
.corn-collapse-inner

Attributes

AttributeValues
data-openpresent or absent

Vanilla JS

Optional. createCollapse only adds and removes the classes and attributes above, so the HTML is equivalent. Reach for it when you need to change options at runtime.

import { createCollapse } from '@corndev/ui';
import '@corndev/ui/theme';

const el = document.querySelector('#target');
const instance = createCollapse(el, { /* options */ });

Options

OptionTypeDefaultDescription
openbooleanfalseWhether the region is shown. Opening animates it to its natural height; closing animates it shut and then hides it from the tab order and assistive technology.

React

Collapse — from @corndev/ui-react.

The props are the same as the options above, plus className.

React usage

const [open, setOpen] = useState(false);

<Button aria-expanded={open} aria-controls="details" onClick={() => setOpen(o => !o)}>Details</Button>
<Collapse open={open} id="details">
  {() => <ExpensiveDetails />}
</Collapse>

A function as children builds the region only when it first opens, so a region that is never opened costs nothing. It stays built afterwards, so closing can animate.

When not to use it

Without an animation, render it conditionally instead — {open && <Details />} is simpler, and the closed region is not in the page at all.

Accessibility

The button that toggles the region owns aria-expanded and aria-controls. Once closed, the region is visibility: hidden, so nothing inside it can take focus or be read out. Reduced motion makes the change instant.