Accordion
A stack of headings that open to show more.
SourcePackage @weft-js/warpPlayground
Preview
tsx
import { Accordion } from '@weft-js/warp'export function Boxed() { return ( <Accordion defaultOpen={['rollback']} items={QUESTIONS} /> )}const QUESTIONS = [ { value: 'rollback', title: 'How do I roll back a deploy?', content: 'Open the deploy you want and press Promote. Traffic moves over in about ten seconds.' }, { value: 'domains', title: 'Can I bring my own domain?', content: 'Yes. Add it under Settings, then point a CNAME at weft.app.' }, { value: 'bill', title: 'What counts towards my bill?', content: 'Requests and build minutes. Preview deploys are free.' },]Installation
npm install @weft-js/warpUsage
tsx
import { Accordion } from '@weft-js/warp'<Accordion defaultOpen={['rollback']} items={QUESTIONS} />Line
Hairlines only, for inside a card.
tsx
import { Accordion } from '@weft-js/warp'export function Line() { return ( <Accordion variant="line" defaultOpen={['rollback']} items={QUESTIONS} /> )}const QUESTIONS = [ { value: 'rollback', title: 'How do I roll back a deploy?', content: 'Open the deploy you want and press Promote. Traffic moves over in about ten seconds.' }, { value: 'domains', title: 'Can I bring my own domain?', content: 'Yes. Add it under Settings, then point a CNAME at weft.app.' }, { value: 'bill', title: 'What counts towards my bill?', content: 'Requests and build minutes. Preview deploys are free.' },]Several open
multiple leaves the others alone.
tsx
import { Accordion } from '@weft-js/warp'export function Multiple() { return ( <Accordion multiple defaultOpen={['rollback', 'bill']} items={QUESTIONS} /> )}const QUESTIONS = [ { value: 'rollback', title: 'How do I roll back a deploy?', content: 'Open the deploy you want and press Promote. Traffic moves over in about ten seconds.' }, { value: 'domains', title: 'Can I bring my own domain?', content: 'Yes. Add it under Settings, then point a CNAME at weft.app.' }, { value: 'bill', title: 'What counts towards my bill?', content: 'Requests and build minutes. Preview deploys are free.' },]A disabled item
Set disabled on the item, and say why in its title.
tsx
import { Accordion } from '@weft-js/warp'export function Disabled() { return ( <Accordion items={[ { value: 'plan', title: 'Plan', content: 'Team, billed monthly.' }, { value: 'seats', title: 'Seats', content: 'Eight of ten in use.' }, { value: 'sso', title: 'Single sign-on (Enterprise)', content: '', disabled: true }, ]} /> )}Hearing what is open
onChange gets the open values each time.
tsx
import { state } from '@weft-js/core'import { Accordion, Stack, Text } from '@weft-js/warp'export function HeardChange() { const open = state(['rollback']) return ( <Stack gap="group"> <Accordion multiple defaultOpen={['rollback']} onChange={list => (open.value = list)} items={QUESTIONS} /> <Text subtle>{open.value.length} of {QUESTIONS.length} open</Text> </Stack> )}const QUESTIONS = [ { value: 'rollback', title: 'How do I roll back a deploy?', content: 'Open the deploy you want and press Promote. Traffic moves over in about ten seconds.' }, { value: 'domains', title: 'Can I bring my own domain?', content: 'Yes. Add it under Settings, then point a CNAME at weft.app.' }, { value: 'bill', title: 'What counts towards my bill?', content: 'Requests and build minutes. Preview deploys are free.' },]Project settings
An item's content can be any JSX.
tsx
import { Accordion, Input, Stack, Switch } from '@weft-js/warp'export function Settings() { return ( <Accordion variant="line" defaultOpen={['general']} items={[ { value: 'general', title: 'General', content: <Input label="Project name" defaultValue="storefront" /> }, { value: 'build', title: 'Build', content: <Stack gap="related"><Input label="Build command" defaultValue="npm run build" /><Switch defaultChecked>Cache dependencies</Switch></Stack> }, { value: 'alerts', title: 'Alerts', content: <Switch>Tell me when a deploy fails</Switch> }, ]} /> )}When to use
Playground
Variant
import { Accordion } from '@weft-js/warp'<Accordion defaultOpen={['rollback']} items={QUESTIONS} />Accessibility
- Enter
- Opens or closes the focused item
- Space
- Opens or closes the focused item
- ↑↓
- Moves between headings
- HomeEnd
- Jumps to the first or last heading
- Each title is a real button inside a heading. Set
levelso the heading fits the page outline.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
items | AccordionItem[] | — | The entries: value, title, content and optionally disabled. |
variant | "line" | "boxed" | 'boxed' | Which form it takes. |
multiple | boolean | false | More than one open at once. |
defaultOpen | string[] | [] | What starts open. |
level | 2 | 3 | 4 | 6 | 5 | 3 | The heading level of each title: one below the heading the accordion sits under. Default 3, in a page section. |
| Event | Type | Default | Description |
|---|---|---|---|
onChange | ((open: string[]) => void) | — | Called with the new value. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="accordion"] [data-part="trigger"]
triggerrootitemheadingchevroncontentsweep