Accordion

Stacked disclosure sections that show one or more panels at a time.

StableSource

You are billed monthly per active seat. Unused seats are credited.

Import

tsx
import { Accordion } from "@merid/react";

Anatomy

tsx
<Accordion.Root type="single">
  <Accordion.Item value="a">
    <Accordion.Trigger />
    <Accordion.Content />
  </Accordion.Item>
</Accordion.Root>
  • Root decides whether one (type="single") or many (type="multiple") items can be open.
  • Item groups a trigger and its content under a unique value.
  • Trigger is a <button> wrapped in a heading (h3 by default) with a plus icon.
  • Content is a role="region" labelled by its trigger. Children only render while open.

Examples

Multiple, controlled

With type="multiple", value and onValueChange use a string[]. headingLevel sets the wrapping heading to fit the page outline.

Orders ship within two business days.

Open: a

Always one open

collapsible={false} on a single accordion prevents closing the open item.

Link your repository.

API reference

Root (single)

Accepts every <div> attribute except defaultValue and onChange.

PropTypeDefaultDescription
typeRequired"single"–One item open at a time.
valuestring–Controlled open item ("" for none).
defaultValuestring–Initially open item when uncontrolled.
onValueChange(value: string) => void–Called with the open item value ("" when all closed).
collapsiblebooleantrueAllow closing the open item.
headingLevel2 | 3 | 4 | 5 | 63Heading level wrapping each trigger.
refRef<HTMLDivElement>–Forwarded ref to the root element.

Root (multiple)

PropTypeDefaultDescription
typeRequired"multiple"–Any number of items open.
valuestring[]–Controlled open items.
defaultValuestring[]–Initially open items when uncontrolled.
onValueChange(value: string[]) => void–Called with the open item values.
headingLevel2 | 3 | 4 | 5 | 63Heading level wrapping each trigger.
refRef<HTMLDivElement>–Forwarded ref to the root element.

Item

Accepts every <div> attribute.

PropTypeDefaultDescription
valueRequiredstring–Unique value of this item.
disabledbooleanfalsePrevent toggling.

Trigger

Accepts every <button> attribute.

PropTypeDefaultDescription
refRef<HTMLButtonElement>–Forwarded ref to the button.

Content

Accepts every <div> attribute.

PropTypeDefaultDescription
refRef<HTMLDivElement>–Forwarded ref to the region.

Styling

ClassElement
.mrd-accordionRoot
.mrd-accordion__itemItem
.mrd-accordion__headingHeading wrapping the trigger
.mrd-accordion__trigger, .mrd-accordion__trigger-textTrigger and its text
.mrd-accordion__iconPlus icon (rotates when open)
.mrd-accordion__contentContent region
AttributeOnValues
data-stateItem, Trigger, Contentopen, closed
aria-expandedTriggertrue, false
aria-disabled="true", data-disabledTriggerwhen the item is disabled

Accessibility

Follows the WAI-ARIA Accordion pattern. Each trigger sits in a heading, carries aria-expanded and aria-controls, and its region is labelled by the trigger. Disabled triggers stay reachable with Tab (with aria-disabled) so they are still announced, but arrow keys, Home and End skip them.

KeyAction
EnterToggle the focused section.
SpaceToggle the focused section.
TabMove to the next focusable element, including inside open content.
ArrowDownNext enabled trigger, wrapping.
ArrowUpPrevious enabled trigger, wrapping.
HomeFirst enabled trigger.
EndLast enabled trigger.

Guidelines

Do

Use an accordion for secondary content people scan by heading — FAQs, settings groups, details.

Avoid

Hide content everyone needs to read, or put a single item in an accordion.

Do

Write triggers as the question or topic, so the page outline reads well.

Avoid

Nest accordions inside accordions.