Skip to content
weftGitHub

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/warp

Usage

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

Use it for

  • Long answers where people want only one or two
  • Optional settings that can stay out of the way

Reach for something else

  • Tabs, when the sections are peers and only one is read at a time
  • Drawer, when the extra content is a task of its own

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 level so the heading fits the page outline.

API Reference

PropTypeDefaultDescription
itemsAccordionItem[]—The entries: value, title, content and optionally disabled.
variant"line" | "boxed"'boxed'Which form it takes.
multiplebooleanfalseMore than one open at once.
defaultOpenstring[][]What starts open.
level2 | 3 | 4 | 6 | 53The heading level of each title: one below the heading the accordion sits under. Default 3, in a page section.
EventTypeDefaultDescription
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

RelatedTabsCardDrawer