Overlays & navigation
Accordion
An accordion stacks sections that open and close in place: FAQs, settings groups, long forms. Plinth builds it on the native <details> element, so it works without JavaScript, the browser's find-in-page opens the matching section, and single mode uses the platform's exclusive accordion (shared name). The chevron turns and, in browsers that support it, the content slides open.
How does the free trial work?
Can I change plans later?
Which currencies can I invoice in?
What happens to my data if I cancel?
const faq: AccordionItemData[] = [ { id: "trial", title: "How does the free trial work?", content: "You get every feature of the Team plan for 14 days. No card is needed to start, and we'll remind you three days before the trial ends.", }, { id: "switch", title: "Can I change plans later?", content: "Yes. Upgrades apply right away and are prorated to the day. Downgrades take effect at the end of the current billing period.", }, { id: "currencies", title: "Which currencies can I invoice in?", content: "Ledgerly supports 38 currencies. Each client has a default currency, and you can override it on any single invoice.", }, { id: "cancel", title: "What happens to my data if I cancel?", content: "Your workspace becomes read-only for 30 days so you can export invoices, clients and payments as CSV or PDF. After that it is deleted.", },]; <Accordion items={faq} defaultOpen={["trial"]} className="mx-auto w-full max-w-xl" />Usage
import { Accordion } from "@/components/ui/accordion"; <Accordion items={[ { id: "trial", title: "How does the free trial work?", content: "You get every feature for 14 days…" }, { id: "cancel", title: "What happens if I cancel?", content: "Your workspace becomes read-only…" }, ]}/>Examples
FAQ
Single mode (the default) keeps one answer open at a time. defaultOpen takes the ids that start open.
How does the free trial work?
Can I change plans later?
Which currencies can I invoice in?
What happens to my data if I cancel?
const faq: AccordionItemData[] = [ { id: "trial", title: "How does the free trial work?", content: "You get every feature of the Team plan for 14 days. No card is needed to start, and we'll remind you three days before the trial ends.", }, { id: "switch", title: "Can I change plans later?", content: "Yes. Upgrades apply right away and are prorated to the day. Downgrades take effect at the end of the current billing period.", }, { id: "currencies", title: "Which currencies can I invoice in?", content: "Ledgerly supports 38 currencies. Each client has a default currency, and you can override it on any single invoice.", }, { id: "cancel", title: "What happens to my data if I cancel?", content: "Your workspace becomes read-only for 30 days so you can export invoices, clients and payments as CSV or PDF. After that it is deleted.", },]; <Accordion items={faq} defaultOpen={["trial"]} className="mx-auto w-full max-w-xl" />Variants and multiple
bordered (default) is one card; separated gives every item its own card; flush has only lines, for use inside other containers. type="multiple" lets several sections stay open.
How does the free trial work?
Can I change plans later?
Which currencies can I invoice in?
How does the free trial work?
Can I change plans later?
Which currencies can I invoice in?
<div className="mx-auto grid w-full max-w-3xl gap-8 md:grid-cols-2"> <div className="flex flex-col gap-2"> <span className="text-eyebrow">separated · multiple</span> <Accordion items={faq.slice(0, 3)} variant="separated" type="multiple" /> </div> <div className="flex flex-col gap-2"> <span className="text-eyebrow">flush</span> <Accordion items={faq.slice(0, 3)} variant="flush" /> </div></div>Icons, meta and disabled
An icon before the title, a quiet summary on the right, and a disabled section that can't be opened.
Members6 people
BillingTeam · yearly
NotificationsEmail
Single sign-onEnterprise
const settings: AccordionItemData[] = [ { id: "members", title: "Members", icon: <Users strokeWidth={1.75} />, meta: "6 people", content: "Invite teammates, change roles and remove people who have left. Admins can manage billing; members can create invoices.", }, { id: "billing", title: "Billing", icon: <CreditCard strokeWidth={1.75} />, meta: "Team · yearly", content: "Your next invoice of €228.00 is due on June 1. Payments are taken from the Visa card ending in 4242.", }, { id: "notifications", title: "Notifications", icon: <Bell strokeWidth={1.75} />, meta: "Email", content: "Get an email when an invoice is viewed, paid or overdue. Daily summaries go out at 9:00 in your time zone.", }, { id: "security", title: "Single sign-on", icon: <Lock strokeWidth={1.75} />, meta: "Enterprise", disabled: true, content: "Available on the Enterprise plan.", },]; <Accordion items={settings} type="multiple" className="mx-auto w-full max-w-xl" />Props
Accordion
itemsrequiredAccordionItemData[]default: —{ id, title, content, icon?, meta?, disabled? }[] in order.type"single" | "multiple"default: "single"Single closes the open section when another opens (native exclusive accordion).defaultOpenstring[]default: []Ids of the sections open on first render.variant"bordered" | "separated" | "flush"default: "bordered"One card, a card per item, or lines only.classNamestringdefault: —Classes for the root element.
AccordionItem
titlerequiredReactNodedefault: —Summary text. The whole row is the toggle.childrenrequiredReactNodedefault: —Section content.namestringdefault: —Items with the same name open one at a time.defaultOpenbooleandefault: —Open on first render.icon / meta / disabledReactNode / ReactNode / booleandefault: —Same as on items.
Accessibility
- Each section is a native <details> with a <summary>, which browsers expose as a button with an expanded or collapsed state.
- Tab moves between summaries; Enter or Space toggles the focused section.
- Content is in the DOM even when closed, so find-in-page and anchor links open the right section.
- Disabled sections have aria-disabled and are removed from the Tab order.
- The chevron is decorative (aria-hidden); the open state is conveyed by the element itself.