Skip to main content
Gremorie

Accordion

Vertical stack of expandable sections. Single or multiple open at once, with built-in keyboard navigation.

Overview

Accordion is the coordinated-disclosure primitive: a vertical stack of sections where readers expand and collapse to reveal content in place. Built on Radix Accordion, it ships two modes via type: "single" (one open at a time, optionally with collapsible so the open item can also close) and "multiple" (any number open simultaneously).

Reach for Accordion when siblings should remain visible - the vertical context is preserved, so readers can scan headings without losing their place. When you want full context swaps, use Tabs instead. Don't nest more than two levels deep; depth past that becomes a scavenger hunt.

For a single, isolated "show more" toggle, prefer Collapsible - it's the building block Accordion is composed on.

Preview

The registry is the single source of truth for Gremorie primitives. Each item lists its files, dependencies, and peers so an agent can install it deterministically.

Installation

bash npx gremorie@latest add rx-accordion
bash pnpm dlx gremorie@latest add rx-accordion
bash yarn dlx gremorie@latest add rx-accordion
bash bunx --bun gremorie@latest add rx-accordion

Usage

import {
  Accordion,
  AccordionItem,
  AccordionTrigger,
  AccordionContent,
} from "@gremorie/rx-display";

export function Example() {
  return (
    <Accordion type="single" collapsible defaultValue="item-1">
      <AccordionItem value="item-1">
        <AccordionTrigger>What is the registry?</AccordionTrigger>
        <AccordionContent>
          The single source of truth for Gremorie primitives.
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-2">
        <AccordionTrigger>What does the MCP server do?</AccordionTrigger>
        <AccordionContent>
          Exposes the registry as MCP tools.
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  );
}

Angular edition planned for Phase 5h. Star the repo to track progress.

API

<Accordion>

Wraps Radix Accordion.Root.

PropTypeDefaultDescription
type"single" | "multiple"-Required. "single" lets one item open at a time; "multiple" lets any number open.
collapsiblebooleanfalseOnly with type="single". When true, clicking the open item closes it.
valuestring | string[]-Controlled value(s) of the open item(s). string for single, string[] for multiple.
defaultValuestring | string[]-Uncontrolled default.
onValueChange(value: string | string[]) => void-Fires when an item opens or closes.
disabledbooleanfalseDisables all items.
orientation"vertical" | "horizontal""vertical"Affects keyboard navigation (Arrow keys).
dir"ltr" | "rtl""ltr"Reading direction.

<AccordionItem>

A single section. Wraps Radix Accordion.Item.

PropTypeDefaultDescription
valuestring-Required. Unique identifier - this is what value / defaultValue on Root references.
disabledbooleanfalseDisables this specific item.

Renders with border-b last:border-b-0 for clean stacking.

<AccordionTrigger>

The clickable header. Wraps Radix Accordion.Trigger inside an Accordion.Header for proper semantics. Includes a ChevronDown icon that rotates 180 degrees when the item opens ([&[data-state=open]>svg]:rotate-180).

PropTypeDefaultDescription
classNamestring-Extra classes merged via cn.

<AccordionContent>

The collapsible content panel. Animates open and closed using data-[state=closed]:animate-accordion-up and data-[state=open]:animate-accordion-down. Wraps content in an inner div with pt-0 pb-4.

Composition

  1. <Accordion> owns the state (type, controlled value or uncontrolled defaultValue).
  2. One or more <AccordionItem> with unique value props.
  3. Inside each item: an <AccordionTrigger> (the header) followed by <AccordionContent> (the body).

The Trigger renders inside an internal Accordion.Header so the heading semantics are correct - you do not need to wrap the trigger in your own <h3>.

Variations

Single-open FAQ

<Accordion type="single" collapsible>
  <AccordionItem value="q1">
    <AccordionTrigger>Is it accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. Built on Radix Accordion with full WAI-ARIA support.
    </AccordionContent>
  </AccordionItem>
  <AccordionItem value="q2">
    <AccordionTrigger>Is it animated?</AccordionTrigger>
    <AccordionContent>
      Yes, height-aware open and close animations.
    </AccordionContent>
  </AccordionItem>
</Accordion>

Multiple sections open

57 primitives across 8 packages.

Added Message, Prompt, Response.

<Accordion type="multiple" defaultValue={['release-1', 'release-2']}>
  <AccordionItem value="release-1">
    <AccordionTrigger>v1.0 - Initial release</AccordionTrigger>
    <AccordionContent>57 primitives across 8 packages.</AccordionContent>
  </AccordionItem>
  <AccordionItem value="release-2">
    <AccordionTrigger>v1.1 - AI primitives</AccordionTrigger>
    <AccordionContent>Added Message, Prompt, Response.</AccordionContent>
  </AccordionItem>
</Accordion>

Controlled value

const [open, setOpen] = useState<string>('billing');

<Accordion type="single" collapsible value={open} onValueChange={setOpen}>
  <AccordionItem value="account">
    <AccordionTrigger>Account</AccordionTrigger>
    <AccordionContent>...</AccordionContent>
  </AccordionItem>
  <AccordionItem value="billing">
    <AccordionTrigger>Billing</AccordionTrigger>
    <AccordionContent>...</AccordionContent>
  </AccordionItem>
</Accordion>;

Accessibility

  • WAI-ARIA Accordion pattern: Radix sets role="region" on each content panel with aria-labelledby pointing at its trigger; the trigger gets aria-expanded and aria-controls.
  • Keyboard: Tab moves between triggers; Space or Enter toggles the focused trigger; ArrowDown / ArrowUp navigate between triggers (loops at the ends). Home and End jump to first and last.
  • Headings: each trigger is wrapped in an internal Accordion.Header (renders as a <h3> by default) so screen readers announce the section as a heading.
  • Disabled items: render with aria-disabled="true" and are skipped during arrow-key navigation.
  • Reduced motion: animations use data-[state] selectors with prefers-reduced-motion queries inherited from the keyframes config.
  • Collapsible - the single-section building block Accordion is composed on.
  • Tabs - use when readers should context-swap rather than browse siblings.
  • Card - common host for an Accordion inside a settings panel.

On this page