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

JobUseNot whenInsteadBecause
Fold sections of content away so a reader opens only the ones they needAccordionExactly one panel shows at a time and they are equal viewsTabsTabs swap panels in place; an accordion keeps every section in reading order.
The sections nest to any depth and the reader selects nodesTreeA tree is a hierarchy with its own keyboard contract.
The content is a list of actions behind a buttonMenuA 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 placeCitationThe link goes to a page and nothing is being citedHoverCardA 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 onePagerChipA 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 sourceCalloutA callout is a quiet aside inside prose.
Show a snippet of code or output to read or copyCodeBlockThe person types or edits the codeCodeEditorA code editor keeps a real textarea under the highlighting; a code block is read-only.
Two versions are comparedDiffA diff marks additions and removals in words and lines, not colour alone.
It is a keyboard key or a shortcutKeysKbd draws a key as a key; a code block is for code.
The value is a secretCredentialA 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 itContentsThe links go to other pages of the appSidebarPlaces in the app are navigation; contents are places in one document.
The sections should be shown one at a timeTabsTabs swap panels; contents keeps the whole document in one scroll.
The document has two headings or fewerSectionHeadContents draws nothing under three entries — the headings are enough.
Show two versions of a text and what changed between themDiffThere is one version of some code to showCodeBlockA code block shows a snippet, with a copy control and optional highlighting.
The change is one an agent proposes and a person must approveConfirmCardA confirm card lists the values it will write and waits for the yes.
The person is editing the textCodeEditorA 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 doesKeysThe list is API keysKeyList.key-list is the integrations list of API keys; this is keyboard keys.
It is a command or a code sampleCodeBlockA code block is for code to read or copy, not a key to press.
The shortcut belongs on a menu itemMenuMenuShortcut 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 allShortcutsuseShortcuts 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 commandCommandPaletteThe command palette binds ⌘K itself and lists the commands.
Preview the file selected in a library, beside the listDocPreviewThe document is the page, read on its own rather than previewed from a listPaperPaper is the sheet a document sits on and the ground behind it.
Two versions of the text are comparedDiffA diff marks what was added and removed, not by colour alone.
The pane is a modal side panel over the pageDrawerA 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 documentPaperThe content is scanned as data — a table, a tree, a split paneTableData takes the full width; the reader looks across it, not down it.
You want a surface for one self-contained item in a gridCardA card is a hairline surface for scanning; paper is a sheet for reading.
You are previewing a file inside a library paneDocPreviewThe preview pane has its own head and actions and holds prose in Reader.
Show a recorded exchange somebody works through and marks as evidenceTranscriptThe exchange is live, between the person and a system answering themConversationA conversation is two-sided, appended to and announced as it arrives.
Each entry is a note left about a recordCommentA 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, figuresTypeYou are naming a sectionSectionHeadA section name is the loud part; .label is 11px mono and inverts the hierarchy.
You are naming the pagePageHeadThe page title belongs in the page head band.
The small words report a statusTagA 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 — unmountClosed keeps 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.

Confused with Tabs, Tree, ContentsReact Accordion AccordionItemClasses .accordion

See it on the demo page

Citation

Mark a claim in prose with the source it came from, and show that source in place.

Use when

  • A marker like S4 inside a sentence, followed in place to what it names; SourceCard is 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">, and useDelegatedHoverCard previews it.
  • A source that cannot be found: missing draws 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.

Confused with HoverCard, PagerChip, CalloutReact Citation SourceCardClasses .citation .source-card

See it on the demo page

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: copyable adds a copy control — off by default.
  • Legibility, not correctness: language highlights 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. 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.

Confused with CodeEditor, Diff, Keys, CredentialReact CodeBlockClasses .code

See it on the demo page

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 reviewed with onReviewedChange for 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.

Confused with Sidebar, Paper, Tabs, LiveProgressReact ContentsClasses .contents

See it on the demo page

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() and tokenize() 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.

Confused with CodeBlock, ConfirmCard, DocPreviewReact DiffHooks diff tokenizeClasses .diff

See it on the demo page

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 / K and arrows with real roving focus: useListKeys, which ignores keys while typing or under a dialog.

Not when

  • 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.

Confused with KeyList, CodeBlock, Menu, CommandPalette, ShortcutsReact Kbd ShortcutListHooks useListKeys stepIndex isTypingTargetClasses .kbd .shortcut-list

See it on the demo page

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 in Sheet, 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.

Confused with Paper, DocList, Split, DrawerReact DocPreview DocPreviewHead DocPreviewTitle DocPreviewActions DocPreviewBody Reader SheetClasses .doc-preview .reader .sheet

See it on the demo page

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 in Reader.

Confused with Card, DocPreview, Contents, PanelReact Paper PaperAside PaperGroundClasses .paper

See it on the demo page

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.

Confused with Conversation, Comment, CitationReact Transcript TranscriptTurnClasses .transcript

No demo page yet.

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.
  • .lede for an intro paragraph, .muted for secondary copy (neutral-600, never neutral-500).
  • .num for tabular figures that line up; .mono for technical identifiers.

Not when

  • 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.

Confused with SectionHead, PageHead, TagClasses .label .lede .muted .num .mono

See it on the demo page

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.