Accordion
A stack of sections that open in place. Use it for filters, settings, and background details that most people do not need every time.
Single and multiple
The first section starts open. The third section is disabled.
Only one section can stay open
Multiple sections can stay open
Usage
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@tulipfarm/sprout/accordion";
<Accordion multiple defaultValue={["one"]}>
<AccordionItem value="one">
<AccordionTrigger>What is this example?</AccordionTrigger>
<AccordionContent>Real shared components with sample data.</AccordionContent>
</AccordionItem>
<AccordionItem value="three" disabled>
<AccordionTrigger>Disabled item</AccordionTrigger>
<AccordionContent>Unavailable</AccordionContent>
</AccordionItem>
</Accordion>One section opens at a time. Pass multiple to let several stay open. Give items a value to open them with defaultValue, or control them with value and onValueChange. An item without a value gets one of its own. disabled on an item blocks its trigger.
Trigger variants
<AccordionTrigger>About this integration</AccordionTrigger>
<AccordionTrigger
variant="quiet"
aria-label="Google calendars"
aria-describedby="source-summary"
>
<span className="grid gap-1">
<span>Google calendars</span>
<span id="source-summary" className="text-xs font-normal">2 of 3 shown</span>
</span>
</AccordionTrigger>default underlines its label on hover. quiet does not, so a title with a summary line below it stays calm. Name a two-line trigger with aria-label and link the summary with aria-describedby.
Trigger variants
default underlines its label on hover. quiet holds a title and a summary and stays still.
Filters
In a filter rail, use multiple and quiet triggers whose summaries show the current choice while the section is closed.
Calendar filters
multiple with quiet triggers. Each summary updates as you change the section.
Controlled settings
<Accordion
value={open ? ["settings"] : []}
onValueChange={(value) => setOpen(value.includes("settings"))}
>
<AccordionItem value="settings">
<AccordionTrigger>Import settings</AccordionTrigger>
<AccordionContent>…</AccordionContent>
</AccordionItem>
</Accordion>
{!open && <p>Documentation, Issues · since Apr 1, 2026 · only you</p>}GitHub import settings
Controlled with value and onValueChange. A summary replaces the settings while they are closed.
Documentation, Issues · since Apr 1, 2026 · only you
Forms and details
A single section can hold a form, with its own loading and error feedback, or a few paragraphs of background. Paragraphs inside content are spaced, and links are underlined.
Proposal recovery
One closed section with a form. Try 6f1c2a9e-4b7d-4e2a-9c51-0d3e8f7a1b24 or any other UUID.
Integration details
A single section at the end of a settings sheet, below a divider.
API
The four parts wrap Base UI Accordion. Every Base UI prop works, includingmultiple, value, defaultValue,onValueChange, disabled, hiddenUntilFound, and keepMounted.AccordionTrigger adds variant; accordionTriggerVariantNames lists them. className on AccordionContent styles its padded inner box.
Parts get data-slot values of accordion, accordion-item, accordion-header, accordion-trigger, accordion-trigger-icon, and accordion-content. Items have data-openand data-disabled; triggers have data-panel-openand data-variant.
Accessibility
Each trigger is a button inside a heading, with aria-expandedand aria-controls, and each panel is a region named by its trigger. Tab and Shift+Tab move between triggers and into open content, Enter and Space toggle a section, and disabled triggers are skipped.
The chevron turns over 120ms and content grows over 180ms. Both stop when reduced motion is requested.
Theme tokens
Accordion uses --sprout-line, --sprout-muted,--sprout-text, --sprout-focus, --sprout-radius-control, --sprout-text-sm, --sprout-motion-fast,--sprout-motion-normal, and --sprout-motion-ease, so it follows light, dark, and the TulipFarm theme.