Collapsible
A text trigger and the content it shows, with a line at the content's start edge. For other layouts, use the parts.
Strong on clock trees. Wants to stay close to silicon bring-up.
import { Text } from "@etched/reticle/text";
import { Collapsible } from "@etched/reticle/collapsible";
export function Preview() {
return (
<div style={{ inlineSize: "16rem" }}>
<Collapsible label="View note" defaultOpen>
<Text as="p">Strong on clock trees. Wants to stay close to silicon bring-up.</Text>
</Collapsible>
</div>
);
}Installation
import { Collapsible, CollapsiblePanel, CollapsibleRoot, CollapsibleTrigger } from "@etched/reticle/collapsible";Examples
View note
The all-in-one: a text trigger and the content it shows. The closed note stays mounted, so find in page reaches it and opens it.
Accepted by Sam Lee · Oct 14
The Ashby owner was wrong. Moved to Kai Ito, who ran the first screen.
import { Text } from "@etched/reticle/text";
import { Collapsible } from "@etched/reticle/collapsible";
export function ViewNote() {
return (
<div style={{ maxInlineSize: "26rem" }}>
<Text as="p" size="sm" variant="secondary">
Accepted by Sam Lee · Oct 14
</Text>
<Collapsible label="View note">
<Text as="p">The Ashby owner was wrong. Moved to Kai Ito, who ran the first screen.</Text>
</Collapsible>
</div>
);
}Unsaved edits
Starts open with defaultOpen, like Orbit's inbox when a send fails and keeps the drafts.
Ana Ruiz
Thanks for the call today. Could you send the tape-out timeline before Friday?
Kai Ito
Moving our chat to Thursday at 10:00. The Taipei trip is still on.
import { Text } from "@etched/reticle/text";
import { Collapsible } from "@etched/reticle/collapsible";
const drafts = [
{ name: "Ana Ruiz", body: "Thanks for the call today. Could you send the tape-out timeline before Friday?" },
{ name: "Kai Ito", body: "Moving our chat to Thursday at 10:00. The Taipei trip is still on." },
];
export function UnsavedEdits() {
return (
<div style={{ maxInlineSize: "26rem" }}>
<Collapsible label="2 unsaved edits" defaultOpen>
{drafts.map((draft) => (
<div key={draft.name}>
<Text as="p" bold>
{draft.name}
</Text>
<Text as="p" variant="secondary">
{draft.body}
</Text>
</div>
))}
</Collapsible>
</div>
);
}Filters panel
The parts, controlled with open and onOpenChange. The trigger is a Button in the header and the panel sits below it. Done closes the panel and moves focus back to the trigger.
import { useRef, useState } from "react";
import { Button } from "@etched/reticle/button";
import { Select } from "@etched/reticle/select";
import { Text } from "@etched/reticle/text";
import { CollapsiblePanel, CollapsibleRoot, CollapsibleTrigger } from "@etched/reticle/collapsible";
interface Referral {
name: string;
role: string;
by: string;
}
const referrals: [string, Referral[]][] = [
[
"Active",
[
{ name: "Ana Ruiz", role: "ASIC design engineer", by: "Sam Lee" },
{ name: "José Núñez", role: "Firmware engineer", by: "Kai Ito" },
],
],
[
"Inactive",
[
{ name: "Lee Park", role: "Thermal engineer", by: "Sam Lee" },
{ name: "Mira Osei", role: "Physical design lead", by: "Ana Ruiz" },
],
],
];
export function FiltersPanel() {
const [open, setOpen] = useState(false);
const trigger = useRef<HTMLButtonElement>(null);
return (
<CollapsibleRoot open={open} onOpenChange={setOpen}>
<div className="row" style={{ justifyContent: "space-between", maxInlineSize: "32rem" }}>
<Text variant="heading">Submitted referrals</Text>
<CollapsibleTrigger ref={trigger} render={<Button size="sm" />}>
Filters
</CollapsibleTrigger>
</div>
<CollapsiblePanel>
<div className="row" style={{ alignItems: "end", paddingBlockStart: "var(--et-space-3)" }}>
<Select label="Status" items={{ new: "New", accepted: "Accepted", declined: "Declined" }} placeholder="Any status" />
<Select label="Referred by" items={{ sam: "Sam Lee", kai: "Kai Ito", ana: "Ana Ruiz" }} placeholder="Anyone" />
<Button
onClick={() => {
setOpen(false);
trigger.current?.focus();
}}
>
Done
</Button>
</div>
</CollapsiblePanel>
</CollapsibleRoot>
);
}Table row groups
Each group folds its own rows: the panel renders as a tbody, and the trigger sits in the group row's heading. A row group folds at once, without the height animation.
| Candidate | Role | Referred by |
|---|---|---|
| Ana Ruiz | ASIC design engineer | Sam Lee |
| José Núñez | Firmware engineer | Kai Ito |
| Lee Park | Thermal engineer | Sam Lee |
| Mira Osei | Physical design lead | Ana Ruiz |
import { Table } from "@etched/reticle/table";
import { CollapsiblePanel, CollapsibleRoot, CollapsibleTrigger } from "@etched/reticle/collapsible";
interface Referral {
name: string;
role: string;
by: string;
}
const referrals: [string, Referral[]][] = [
[
"Active",
[
{ name: "Ana Ruiz", role: "ASIC design engineer", by: "Sam Lee" },
{ name: "José Núñez", role: "Firmware engineer", by: "Kai Ito" },
],
],
[
"Inactive",
[
{ name: "Lee Park", role: "Thermal engineer", by: "Sam Lee" },
{ name: "Mira Osei", role: "Physical design lead", by: "Ana Ruiz" },
],
],
];
export function TableRowGroups() {
return (
<div className="card">
<Table aria-label="Referrals">
<thead>
<tr>
<th style={{ inlineSize: "30%" }}>Candidate</th>
<th>Role</th>
<th style={{ inlineSize: "20%" }}>Referred by</th>
</tr>
</thead>
{referrals.map(([group, rows]) => (
<CollapsibleRoot key={group} defaultOpen={group === "Active"}>
<tbody>
<tr>
<th scope="rowgroup" colSpan={3}>
<CollapsibleTrigger>
{group} ({rows.length})
</CollapsibleTrigger>
</th>
</tr>
</tbody>
<CollapsiblePanel render={<tbody />}>
{rows.map((row) => (
<tr key={row.name}>
<th scope="row">{row.name}</th>
<td>{row.role}</td>
<td>{row.by}</td>
</tr>
))}
</CollapsiblePanel>
</CollapsibleRoot>
))}
</Table>
</div>
);
}API reference
CollapsiblePanel
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | – |
Collapsible
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | – | |
| label * | ReactNode | – | The trigger's text, such as "View note". |
| className | string | – | Class on the wrapper, for layout. |
CollapsibleRoot
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | – |
CollapsibleTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | – |