Reading
Which component to use for a document, prose, code, sources or type someone reads. Find the job, take the component, and read the “not when” before you commit: it names the thing people reach for by mistake, and what to use instead.
At a glance
| Job | Use | Not when | Instead | Because |
|---|---|---|---|---|
| Fold sections of content away so a reader opens only the ones they need | Accordion | Exactly one panel shows at a time and they are equal views | Tabs | Tabs swap panels in place; an accordion keeps every section in reading order. |
| The sections nest to any depth and the reader selects nodes | Tree | A tree is a hierarchy with its own keyboard contract. | ||
| The content is a list of actions behind a button | Menu | A menu floats and closes on a choice; an accordion discloses content inline. | ||
| Mark a claim in prose with the source it came from, and show that source in place | Citation | The link goes to a page and nothing is being cited | HoverCard | A hover card previews what any link or name leads to; a citation is a source behind a claim. |
| The sources are a list to step through one by one | PagerChip | A pager chip walks a set in place — S4 of 19 — with source cards as the content. | ||
| The aside is a note of your own, not a source | Callout | A callout is a quiet aside inside prose. | ||
| Show a snippet of code or output to read or copy | CodeBlock | The person types or edits the code | CodeEditor | A code editor keeps a real textarea under the highlighting; a code block is read-only. |
| Two versions are compared | Diff | A diff marks additions and removals in words and lines, not colour alone. | ||
| It is a keyboard key or a shortcut | Keys | Kbd draws a key as a key; a code block is for code. | ||
| The value is a secret | Credential | A credential keeps the secret out of the DOM until revealed and copies without reveal. | ||
| Show where you are in a long document and jump elsewhere in it | Contents | The links go to other pages of the app | Sidebar | Places in the app are navigation; contents are places in one document. |
| The sections should be shown one at a time | Tabs | Tabs swap panels; contents keeps the whole document in one scroll. | ||
| The document has two headings or fewer | SectionHead | Contents draws nothing under three entries — the headings are enough. | ||
| Show two versions of a text and what changed between them | Diff | There is one version of some code to show | CodeBlock | A code block shows a snippet, with a copy control and optional highlighting. |
| The change is one an agent proposes and a person must approve | ConfirmCard | A confirm card lists the values it will write and waits for the yes. | ||
| The person is editing the text | CodeEditor | A code editor is a textarea that shows the shape of what is typed. | ||
| Show a keyboard key, or the keys a surface binds and what each does | Keys | The list is API keys | KeyList | .key-list is the integrations list of API keys; this is keyboard keys. |
| It is a command or a code sample | CodeBlock | A code block is for code to read or copy, not a key to press. | ||
| The shortcut belongs on a menu item | Menu | MenuShortcut sets the shortcut at the end of the item it triggers. | ||
| The page binds its own single keys and needs them off while typing, an off-switch, and one list of them all | Shortcuts | useShortcuts binds the keys, turns single keys off on request and registers them for ShortcutHelp; Keys only draws them. | ||
| The keys open a search over every command | CommandPalette | The command palette binds ⌘K itself and lists the commands. | ||
| Preview the file selected in a library, beside the list | DocPreview | The document is the page, read on its own rather than previewed from a list | Paper | Paper is the sheet a document sits on and the ground behind it. |
| Two versions of the text are compared | Diff | A diff marks what was added and removed, not by colour alone. | ||
| The pane is a modal side panel over the page | Drawer | A drawer takes the page over and must be dismissed; a preview pane sits beside the list. | ||
| Set a document on a sheet, on a ground, so it reads as a document | Paper | The content is scanned as data — a table, a tree, a split pane | Table | Data takes the full width; the reader looks across it, not down it. |
| You want a surface for one self-contained item in a grid | Card | A card is a hairline surface for scanning; paper is a sheet for reading. | ||
| You are previewing a file inside a library pane | DocPreview | The preview pane has its own head and actions and holds prose in Reader. | ||
| Show a recorded exchange somebody works through and marks as evidence | Transcript | The exchange is live, between the person and a system answering them | Conversation | A conversation is two-sided, appended to and announced as it arrives. |
| Each entry is a note left about a record | Comment | A comment is one authored note about something; a transcript turn is part of a continuous exchange. | ||
| Set the voice of text — mono labels, an intro paragraph, secondary copy, figures | Type | You are naming a section | SectionHead | A section name is the loud part; .label is 11px mono and inverts the hierarchy. |
| You are naming the page | PageHead | The page title belongs in the page head band. | ||
| The small words report a status | Tag | A status is a tag with a tone that means something; a label is only a voice. |
Accordion
Fold sections of content away so a reader opens only the ones they need.
Use when
- A list of questions, details or optional sections where most readers want few of them.
- Several may be open at once by default;
type="single"closes one when another opens. - Opening a panel should cause the work it holds —
unmountClosedkeeps fetches off until then.
Not when
- Exactly one panel shows at a time and they are equal views →
Tabs. Tabs swap panels in place; an accordion keeps every section in reading order. - The sections nest to any depth and the reader selects nodes →
Tree. A tree is a hierarchy with its own keyboard contract. - The content is a list of actions behind a button →
Menu. A menu floats and closes on a choice; an accordion discloses content inline.
Citation
Mark a claim in prose with the source it came from, and show that source in place.
Use when
- A marker like
S4inside a sentence, followed in place to what it names;SourceCardis the file, the locator, the cited words and a way to open it there. - Generated or sanitised HTML: the same class styles
<a class="citation">, anduseDelegatedHoverCardpreviews it. - A source that cannot be found:
missingdraws a dashed, unlinked marker that says so in words.
Not when
- The link goes to a page and nothing is being cited →
HoverCard. A hover card previews what any link or name leads to; a citation is a source behind a claim. - The sources are a list to step through one by one →
PagerChip. A pager chip walks a set in place —S4 of 19— with source cards as the content. - The aside is a note of your own, not a source →
Callout. A callout is a quiet aside inside prose.
CodeBlock
Show a snippet of code or output to read or copy.
Use when
- A command, a config file or a sample, with a title (a filename or a language) in the head.
- Something meant to be run:
copyableadds a copy control — off by default. - Legibility, not correctness:
languagehighlights sh, ts, tsx, js, css and json; leave it off for logs and stack traces.
Not when
- The person types or edits the code →
CodeEditor. A code editor keeps a real textarea under the highlighting; a code block is read-only. - Two versions are compared →
Diff. A diff marks additions and removals in words and lines, not colour alone. - It is a keyboard key or a shortcut →
Keys.Kbddraws a key as a key; a code block is for code. - The value is a secret →
Credential. A credential keeps the secret out of the DOM until revealed and copies without reveal.
Contents
Show where you are in a long document and jump elsewhere in it.
Use when
- A long document with headings: the entry in view is marked
aria-current="location"as the reader scrolls. - Review section by section — pass
reviewedwithonReviewedChangefor a box per entry and a count. - A run is writing the document — each entry carries the same live mark as its section.
Not when
- The links go to other pages of the app →
Sidebar. Places in the app are navigation; contents are places in one document. - The sections should be shown one at a time →
Tabs. Tabs swap panels; contents keeps the whole document in one scroll. - The document has two headings or fewer →
SectionHead. Contents draws nothing under three entries — the headings are enough.
Diff
Show two versions of a text and what changed between them.
Use when
- Before and after of a document, a field or a setting — inline or split into two panes, by word or by line.
- Removals are struck through and additions underlined, as real
<del>and<ins>, so a change never rests on colour alone. - The operations rather than the rendering:
diff()andtokenize()are exported.
Not when
- There is one version of some code to show →
CodeBlock. A code block shows a snippet, with a copy control and optional highlighting. - The change is one an agent proposes and a person must approve →
ConfirmCard. A confirm card lists the values it will write and waits for the yes. - The person is editing the text →
CodeEditor. A code editor is a textarea that shows the shape of what is typed.
Keys
Show a keyboard key, or the keys a surface binds and what each does.
Use when
- A key drawn as a key inside text —
J,Enter,⇧— as a real<kbd>(Kbd). - A "?" sheet or the foot of a panel that binds keys:
ShortcutList, a description list of keys and what they do, with glyphs given spoken names. - Moving through a list of cards by
J/Kand arrows with real roving focus:useListKeys, which ignores keys while typing or under a dialog.
Not when
- The list is API keys →
KeyList..key-listis the integrations list of API keys; this is keyboard keys. - It is a command or a code sample →
CodeBlock. A code block is for code to read or copy, not a key to press. - The shortcut belongs on a menu item →
Menu.MenuShortcutsets the shortcut at the end of the item it triggers. - The page binds its own single keys and needs them off while typing, an off-switch, and one list of them all →
Shortcuts.useShortcutsbinds the keys, turns single keys off on request and registers them forShortcutHelp;Keysonly draws them. - The keys open a search over every command →
CommandPalette. The command palette binds ⌘K itself and lists the commands.
DocPreview
Preview the file selected in a library, beside the list.
Use when
- A pane with the file's title and actions in a head and its rendered body below.
- Prose in
Reader, its measure capped at 72ch; a spreadsheet inSheet, a grid shown as a grid.
Not when
- The document is the page, read on its own rather than previewed from a list →
Paper. Paper is the sheet a document sits on and the ground behind it. - Two versions of the text are compared →
Diff. A diff marks what was added and removed, not by colour alone. - The pane is a modal side panel over the page →
Drawer. A drawer takes the page over and must be dismissed; a preview pane sits beside the list.
Paper
Set a document on a sheet, on a ground, so it reads as a document.
Use when
- Anything read as a document — a report, a specification, a generated write-up.
- Navigation for the document — its contents, a provenance rail — goes beside the sheet in
PaperAside, not on it.
Not when
- The content is scanned as data — a table, a tree, a split pane →
Table. Data takes the full width; the reader looks across it, not down it. - You want a surface for one self-contained item in a grid →
Card. A card is a hairline surface for scanning; paper is a sheet for reading. - You are previewing a file inside a library pane →
DocPreview. The preview pane has its own head and actions and holds prose inReader.
Transcript
Show a recorded exchange somebody works through and marks as evidence.
Use when
- An interview or session transcript with any number of speakers, read in order and marked for what each stretch is evidence of.
- Actions on a turn appear on interaction, not on every row — an hour is hundreds of turns.
Not when
- The exchange is live, between the person and a system answering them →
Conversation. A conversation is two-sided, appended to and announced as it arrives. - Each entry is a note left about a record →
Comment. A comment is one authored note about something; a transcript turn is part of a continuous exchange.
Type
Set the voice of text — mono labels, an intro paragraph, secondary copy, figures.
Use when
.label— the mono voice for section markers, figures and data labels. Never above a heading as an eyebrow..ledefor an intro paragraph,.mutedfor secondary copy (neutral-600, never neutral-500)..numfor tabular figures that line up;.monofor technical identifiers.
Not when
- You are naming a section →
SectionHead. A section name is the loud part;.labelis 11px mono and inverts the hierarchy. - You are naming the page →
PageHead. The page title belongs in the page head band. - The small words report a status →
Tag. A status is a tag with a tone that means something; a label is only a voice.
Other guides: Screens · Overlays · Status and feedback · Navigation · Data · Input · Agents and live work
Generated from the when.ts beside each component — the same data the Claude Code plugin reads.