Accordions group dense information into scannable sections — ideal for student profiles, therapy plans, billing/authorizations, audit logs, and workspace member portal summaries. They are keyboard navigable, accessible, and token-driven for theme safety.
Enterprise default: one panel open at a time. Collapsible allows closing the currently open panel.
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent
} from "@/design-system/components/Accordion";
export function Example() {
return (
<Accordion type="single" collapsible defaultValue="overview" variant="contained" tone="neutral">
<AccordionItem value="overview">
<AccordionHeader>
<AccordionTrigger description="High-level clinical summary and status">
Student overview
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="stack-sm">
<div className="text-sm">Primary diagnosis, key notes, and care team summary.</div>
</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="sessions">
<AccordionHeader>
<AccordionTrigger description="Session cadence, attendance, and note cadence">
Sessions
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">Upcoming sessions, recent notes, and supervision flags.</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="billing">
<AccordionHeader>
<AccordionTrigger description="Billing status, authorizations, and payer notes">
Billing
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">Coverage, authorizations, and billing exceptions.</div>
</AccordionContent>
</AccordionItem>
</Accordion>
);
}
Multiple panels can be open at the same time. Useful for plan builders and multi-section reviews.
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent
} from "@/design-system/components/Accordion";
export function Example() {
return (
<Accordion type="multiple" defaultValue={["plan", "goals"]} tone="primary" variant="contained">
<AccordionItem value="plan">
<AccordionHeader>
<AccordionTrigger description="Plan metadata + approvals">
Therapy plan
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">Plan details and approval history.</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="goals">
<AccordionHeader>
<AccordionTrigger description="Goals and measurement cadence">
Goals
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">Goal list with targets and measurement rules.</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="audit">
<AccordionHeader>
<AccordionTrigger description="Enterprise audit trail for compliance">
Audit log
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">System-level events, exports, and access changes.</div>
</AccordionContent>
</AccordionItem>
</Accordion>
);
}
Contained, Flush, and Card variants. Use Flush inside already-bordered panels; Card for dashboards.
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent
} from "@/design-system/components/Accordion";
export function Example() {
return (
<div className="accordions-grid">
<Accordion variant="contained" tone="neutral">
<AccordionItem value="a">
<AccordionHeader>
<AccordionTrigger description="Outer border + dividers">Contained</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Contained accordion with outer border.</AccordionContent>
</AccordionItem>
</Accordion>
<Accordion variant="flush" tone="neutral">
<AccordionItem value="b">
<AccordionHeader>
<AccordionTrigger description="No outer border; fits inside cards">Flush</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Flush accordion for inside panels/cards.</AccordionContent>
</AccordionItem>
</Accordion>
<Accordion variant="card" tone="neutral" type="multiple" defaultValue={["c1"]}>
<AccordionItem value="c1">
<AccordionHeader>
<AccordionTrigger description="Each item is its own premium card">Card item</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Useful for dashboards and settings.</AccordionContent>
</AccordionItem>
<AccordionItem value="c2">
<AccordionHeader>
<AccordionTrigger description="Second card in the same group">Another card item</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Scales nicely for dense admin pages.</AccordionContent>
</AccordionItem>
</Accordion>
</div>
);
}
Density control. Use sm for tight tool panels, md for most screens, lg for primary workflows.
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent
} from "@/design-system/components/Accordion";
export function Example() {
return (
<div className="accordions-grid">
<Accordion size="sm" tone="neutral">
<AccordionItem value="sm">
<AccordionHeader>
<AccordionTrigger description="Compact density for tool panels">
Small
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Small content.</AccordionContent>
</AccordionItem>
</Accordion>
<Accordion size="md" tone="neutral">
<AccordionItem value="md">
<AccordionHeader>
<AccordionTrigger description="Default density for forms and screens">
Medium
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Medium content.</AccordionContent>
</AccordionItem>
</Accordion>
<Accordion size="lg" tone="neutral">
<AccordionItem value="lg">
<AccordionHeader>
<AccordionTrigger description="Comfortable density for primary workflows">
Large
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Large content.</AccordionContent>
</AccordionItem>
</Accordion>
</div>
);
}
Enterprise pattern: meta/actions are siblings of the trigger (interactive actions are NOT inside the button).
import { Button } from "@/design-system/components/Button";
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent,
AccordionHeaderMeta, AccordionHeaderActions
} from "@/design-system/components/Accordion";
export function Example() {
return (
<Accordion type="single" defaultValue="risk" tone="neutral" variant="contained">
<AccordionItem value="risk">
<AccordionHeader>
<AccordionTrigger description="Risk score and last review timestamp">
Risk & compliance
</AccordionTrigger>
<AccordionHeaderMeta>Updated 2d ago</AccordionHeaderMeta>
<AccordionHeaderActions>
<Button size="sm" variant="ghost">Export</Button>
</AccordionHeaderActions>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">Audit-relevant summary and evidence links.</div>
</AccordionContent>
</AccordionItem>
</Accordion>
);
}
Disable items for permission-locked sections (e.g., supervisor-only controls).
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent
} from "@/design-system/components/Accordion";
export function Example() {
return (
<Accordion tone="neutral" variant="contained">
<AccordionItem value="ready">
<AccordionHeader>
<AccordionTrigger description="Always available">Available section</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Visible content.</AccordionContent>
</AccordionItem>
<AccordionItem value="locked" disabled>
<AccordionHeader>
<AccordionTrigger description="Requires supervisor permissions">
Locked section
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>Not accessible.</AccordionContent>
</AccordionItem>
</Accordion>
);
}
Group form inputs into collapsible sections while preserving input state.
import { Input } from "@/design-system/components/Input";
import { Button } from "@/design-system/components/Button";
import {
Accordion, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent
} from "@/design-system/components/Accordion";
export function Example() {
return (
<Accordion type="multiple" defaultValue={["contact"]} tone="primary" variant="contained">
<AccordionItem value="contact">
<AccordionHeader>
<AccordionTrigger description="Workspace admin-facing contact details">
Contact
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="stack-sm">
<Input label="Workspace member email" placeholder="workspace member@example.com" />
<Input label="Phone" placeholder="(555) 000-0000" />
<div className="accordions-toolbar">
<Button variant="primary" size="sm">Save</Button>
<Button variant="ghost" size="sm">Cancel</Button>
</div>
</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="notes">
<AccordionHeader>
<AccordionTrigger description="Non-critical notes for internal staff">
Internal notes
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<div className="text-sm">
Use this for scannable operational notes (avoid PHI in unintended places).
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
);
}
Implementation detail: accordion content is not unmounted during close; it is hidden after collapse completes, preserving internal state (e.g., partially filled forms).