Accordion
The Accordion component renders collapsible sections with rich content. Item content is written in Markdown and processed server-side to HTML via markdownToHtml().
Import
import Accordion from '@mdx/Accordion.astro';
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | Array<{title, subtitle?, content}> | — | Array of accordion items. content accepts Markdown. |
mode | 'single-closed' | 'single-open' | 'always-one' | 'multi' | — | Preset that controls the open/close behaviour. Overrides the three legacy props below. Preferred API. |
defaultOpen | number | null | null | (Legacy.) Index of initially open item |
allowCloseAll | boolean | Auto-derived | (Legacy.) Whether an open item can be collapsed. Defaults to true when defaultOpen is null. |
allowMultiple | boolean | false | (Legacy.) Allow multiple items open simultaneously |
width | string | "100%" | CSS width of the accordion container |
Mode presets
mode | defaultOpen | allowCloseAll | allowMultiple | Behaviour |
|---|---|---|---|---|
single-closed | null | true | false | All start closed; clicking one closes any other; can close all. |
single-open | 0 | true | false | First starts open; only one open at a time; can close all. |
always-one | 0 | false | false | First starts open; only one open at a time; cannot close all (always exactly one open). |
multi | null | true | true | All start closed; multiple can be open simultaneously. |
The legacy props are kept on the Astro component for backwards compatibility with hand-authored MDX, but the Keystatic schema only exposes mode. New content should use mode exclusively.
Live Examples
Default (all closed)
Content of the first section with Markdown support.
Content with a link and inline code.
- List item one
- List item two
- List item three
With default open and subtitle
Subtitle text
This item starts open.
This item starts closed.
Implementation Notes
Markdown processing: Each item’s content string is processed at build time via markdownToHtml() from src/utils/markdown.ts. This uses the unified/remark/rehype pipeline with GitHub Flavored Markdown support (tables, strikethrough, task lists). Raw HTML is allowed but sanitized via rehype-sanitize — <script>, inline event handlers, and javascript: URLs are stripped before render.
Alpine.js state:
activeIndex— tracks the single open item (single mode)openIndices— array of open item indices (multiple mode)_reducedMotion— checksprefers-reduced-motionand skips animation if set
Animation:
- Open: 250ms ease-out height transition
- Close: 200ms ease-in height transition
- After opening, height is set to
auto(via 260ms timeout) so content can resize naturally
Source: src/components/mdx/Accordion.astro