Accordion
PortedA stack of sections. Each has a heading that opens and closes its content, with a line between them. Use it for a set of sections that share a page, such as the parts of a candidate's record or the questions on a help page. Use Collapsible for one "show more" toggle, or when the trigger and its content sit apart (a filter panel, a table's row group). Tab moves between the headings; Enter or Space opens and closes one. Find in page also opens a closed item that holds a match.
import { Accordion, AccordionItem } from "@etched/monet/accordion";
const stages = [
{ value: "screen", title: "Recruiter screen", body: "Sam Lee, Oct 2. Strong on clock trees; wants to stay close to silicon bring-up." },
{ value: "technical", title: "Technical interview", body: "Kai Ito, Oct 9. Walked through a timing closure on a 5 nm block without notes." },
{ value: "onsite", title: "Onsite loop", body: "Four interviews on Oct 16. Two strong yes, one yes, one waiting for feedback." },
];
export function Preview() {
return (
<div style={{ inlineSize: "18rem" }}>
<Accordion defaultValue={["screen"]}>
{stages.map(({ value, title, body }) => (
<AccordionItem key={value} value={value} title={title}>
{body}
</AccordionItem>
))}
</Accordion>
</div>
);
}Installation
import { Accordion, AccordionItem } from "@etched/monet/accordion";Examples
One open at a time
The default: opening an item closes the open one. Use it for sections that are read one by one, such as the stages of an interview loop.
import { Accordion, AccordionItem } from "@etched/monet/accordion";
const stages = [
{ value: "screen", title: "Recruiter screen", body: "Sam Lee, Oct 2. Strong on clock trees; wants to stay close to silicon bring-up." },
{ value: "technical", title: "Technical interview", body: "Kai Ito, Oct 9. Walked through a timing closure on a 5 nm block without notes." },
{ value: "onsite", title: "Onsite loop", body: "Four interviews on Oct 16. Two strong yes, one yes, one waiting for feedback." },
];
export function OneOpen() {
return (
<div style={{ maxInlineSize: "30rem" }}>
<Accordion defaultValue={["technical"]}>
{stages.map(({ value, title, body }) => (
<AccordionItem key={value} value={value} title={title}>
{body}
</AccordionItem>
))}
</Accordion>
</div>
);
}Several open, controlled
With multiple, items open and close on their own. Here the app holds the open items, so two buttons open and close all of them.
Senior physical design engineer at Tenstorrent, 2021 to now. Before that, four years at Apple on the A15 and A16.
MS Electrical Engineering, University of Illinois Urbana-Champaign.
Ana and I worked together on the A16 power grid. She is the person I call when timing will not close.
Kai Ito · Oct 14
import { useState } from "react";
import { Button } from "@etched/monet/button";
import { Text } from "@etched/monet/text";
import { Accordion, AccordionItem } from "@etched/monet/accordion";
export function SeveralOpen() {
const [open, setOpen] = useState(["experience"]);
return (
<div style={{ display: "grid", gap: "var(--et-space-3)", maxInlineSize: "30rem" }}>
<div className="row">
<Button size="sm" onClick={() => setOpen(["experience", "education", "note"])}>
Open all
</Button>
<Button size="sm" onClick={() => setOpen([])}>
Close all
</Button>
</div>
<Accordion multiple value={open} onValueChange={setOpen}>
<AccordionItem value="experience" title="Experience">
<Text as="p">Senior physical design engineer at Tenstorrent, 2021 to now. Before that, four years at Apple on the A15 and A16.</Text>
</AccordionItem>
<AccordionItem value="education" title="Education">
<Text as="p">MS Electrical Engineering, University of Illinois Urbana-Champaign.</Text>
</AccordionItem>
<AccordionItem value="note" title="Referral note">
<Text as="p">Ana and I worked together on the A16 power grid. She is the person I call when timing will not close.</Text>
<Text as="p" size="sm" variant="secondary">
Kai Ito · Oct 14
</Text>
</AccordionItem>
</Accordion>
</div>
);
}A disabled item
A disabled item does not open, and its title fades. Say why in the title or near the accordion.
import { Accordion, AccordionItem } from "@etched/monet/accordion";
export function DisabledItem() {
return (
<div style={{ maxInlineSize: "30rem" }}>
<Accordion>
<AccordionItem value="feedback" title="Interview feedback">
Three of four interviewers have sent feedback.
</AccordionItem>
<AccordionItem value="offer" title="Offer (after the final interview)" disabled>
Draft the offer once the loop is complete.
</AccordionItem>
</Accordion>
</div>
);
}Accessibility
Tabmoves between the headings' buttons.EnterorSpaceopens and closes an item.- Each title is a heading (
h3by default) that holds abutton. An open panel is aregion, named by its button. - Each button has
aria-expanded. A disabled item's button is disabled. Find in page opens a closed item that holds a match. - Set
titleAsso the headings fit the page's outline.
API reference
AccordionItem
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | – | Names the item in the accordion's value and defaultValue. Without it, the item gets its own id. |
| title * | ReactNode | – | The heading's text. Its button opens and closes the item. |
| titleAs | "h2" | "h3" | "h4" | "h5" | "h6" | "h3" | The heading level, so it fits the page's outline. |
| disabled | boolean | – | The item does not open or close. |
| children * | ReactNode | – | The content. It stays mounted while closed, hidden until found, so find in page reaches it. |
Accordion
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string[] | – | The open items, controlled: the value of each open AccordionItem. |
| defaultValue | string[] | [] | The items open at first, uncontrolled. |
| onValueChange | (value: string[]) => void | – | |
| multiple | boolean | false | More than one item can be open. Without it, opening an item closes the open one. |
| disabled | boolean | – | No item opens or closes. |
| children * | ReactNode | – | AccordionItems. |