Components · Data display
DescriptionList
Key/value facts on detail pages, with copyable values, empty placeholders and clamped long values.
Record facts
- Owner
- Ada Lovelace
- Stage
- Proposal
- Created
- 3 March
- Source
- Inbound
- Notes
- Follow up after the product review.
import { DescriptionItem, DescriptionList } from '@rookcom/monarch-react';
<DescriptionList columns={2} style={{ width: '100%' }}>
<DescriptionItem term="Owner">Ada Lovelace</DescriptionItem>
<DescriptionItem term="Stage">Proposal</DescriptionItem>
<DescriptionItem term="Created">3 March</DescriptionItem>
<DescriptionItem term="Source">Inbound</DescriptionItem>
<DescriptionItem term="Notes" wide>
Follow up after the product review.
</DescriptionItem>
</DescriptionList>Usage examples
Copyable values and empty placeholders
import { DescriptionItem, DescriptionList } from '@rookcom/monarch-react';
<DescriptionList columns={2} style={{ width: '100%' }}>
<DescriptionItem term="Workspace ID" copyable>
ws_8f2a91c4
</DescriptionItem>
<DescriptionItem term="Webhook URL" copyable>
https://hooks.example.com/w/8f2a91c4
</DescriptionItem>
<DescriptionItem term="Phone">{null}</DescriptionItem>
<DescriptionItem term="Tax ID" placeholder="Not provided">
{''}
</DescriptionItem>
</DescriptionList>Inline layout with a clamped value
import { DescriptionItem, DescriptionList } from '@rookcom/monarch-react';
<DescriptionList
layout="inline"
columns={1}
style={{ width: '100%', maxWidth: '32rem' }}
>
<DescriptionItem term="Page title">
Pricing plans for teams of every size
</DescriptionItem>
<DescriptionItem term="Meta description" truncate={2}>
Compare plans side by side, see what each includes, and start a free trial. Every
plan includes unlimited projects, guest access and priority support during business
hours, with annual billing available at a discount.
</DescriptionItem>
<DescriptionItem term="Canonical">{null}</DescriptionItem>
</DescriptionList>Responsive columns
import { DescriptionItem, DescriptionList } from '@rookcom/monarch-react';
<DescriptionList columns="auto" style={{ width: '100%' }}>
<DescriptionItem term="Plan">Team</DescriptionItem>
<DescriptionItem term="Seats">12 of 15</DescriptionItem>
<DescriptionItem term="Renews">1 June</DescriptionItem>
<DescriptionItem term="Billing">Annual</DescriptionItem>
</DescriptionList>Purpose
Key/value facts on a detail page (owner, stage, created, …), as a semantic <dl>. Items can offer a copy button, show a placeholder for empty values, and clamp long values behind "Show more".
Use when
- Showing read-only fields of one record.
- Ids, keys and URLs people copy: use
copyable. - Values that may be missing: the placeholder replaces hand-rolled em dashes.
Avoid when
- Comparing many records: use a table.
- Editable fields: use a form with Field, or InlineEditText per value.
Design principles
- Semantic markup: each item is a
<dt>/<dd>pair. - Values wrap anywhere so long ids and URLs never overflow.
- An empty value is visibly empty (a muted dash) and audibly named ("Not set"), never a blank cell.
- Truncation never hides data: the full value is one "Show more" away, not only in a tooltip.
API reference
import { DescriptionItem, DescriptionList } from '@rookcom/monarch-react';| Export | Kind | Rendering | Root class |
|---|---|---|---|
DescriptionItem | component | server-safe | .mn-dl-min-column |
DescriptionList | component | server-safe | .mn-dl-min-column |
DescriptionList renders a <dl>; DescriptionItem a <div> with <dt> and <dd>. Both forward their ref.
Server-safe: the list and items have no state. The copy button and the clamp toggle are client components rendered only when used.
--mn-dl-min-column sets the minimum column width of columns="auto" (default 12rem).
Generated from the TypeScript declarations of packages/react/src/components/data-display/description-list.
Properties
DescriptionItem
| Prop | Type | Description |
|---|---|---|
term required | ReactNode | |
children | ReactNode | The value. `null`, `undefined`, `false` and `''` render the `placeholder`. |
className | string | |
collapseLabel | string | Label of the collapse button. Default "Show less". |
copyable | string | boolean | Adds an icon CopyButton after the value. `true` copies the value when it is a string or number; pass a string to copy something else (the full id behind a shortened one). Not shown for an empty value. |
copyLabel | string | Accessible name of the copy button. Default "Copy" followed by the term when it is text. |
emptyLabel | string | Screen-reader text for the default placeholder. Default "Not set". |
expandLabel | string | Label of the expand button. Default "Show more". |
placeholder | ReactNode | Shown for an empty value. Default an em dash, read as `emptyLabel`. |
truncate | number | boolean | Clamp the value to this many lines (`true` is 1) with a "Show more" button that expands it. The button appears only when the text overflows. |
wide | boolean | Span all columns. |
DescriptionList
Key/value facts on detail pages (owner, stage, created, …).
| Prop | Type | Description |
|---|---|---|
children | ReactNode | |
className | string | |
columns | 3 | 1 | "auto" | 4 | 2 | Grid columns. `auto` fits as many columns of at least `--mn-dl-min-column` (default 12rem) as the width allows. Every value becomes one column below 640px. Default 2. |
id | string | |
layout | "inline" | "stacked" | `stacked` (default, vertical) puts the term above the value; `inline` (horizontal) puts them side by side, and stacks again below 420px. |
Variants
| Prop | Values | Description |
|---|---|---|
columns | '1''2''3''4''auto' | Grid columns. Default 2. 4 drops to two columns below 1024px; auto fits columns of at least --mn-dl-min-column. Exposed as data-columns. |
layout | 'stacked''inline' | stacked (default, vertical) puts the term above the value; inline (horizontal) side by side. Exposed as data-layout. |
DescriptionItem wide | 'true''false' | Spans all columns (data-wide). |
DescriptionItem copyable | 'false''true''string' | true copies a text value; a string copies that text (the full key behind a masked one). |
DescriptionItem truncate | 'false''true (1 line)''number of lines' | Clamps the value and adds "Show more" when it overflows. |
States
| State | Exposed as | Behaviour |
|---|---|---|
| Empty | data-empty on the item | null, undefined, false or "" render the placeholder (default a muted em dash read as "Not set"). 0 is a value. |
| Clamped / expanded | data-expanded on .mn-dl__clamp | The toggle shows only when the text overflows the clamp; aria-expanded follows. |
| Copied | – | The copy button shows a check and announces "Copied to clipboard" (CopyButton). |
Interaction behaviour
- The copy button copies the value and confirms in place.
- "Show more" expands the clamped value; "Show less" clamps it again.
- The overflow check runs after mount and on resize, so a value that fits never shows a toggle.
Keyboard support
| Keys | Action |
|---|---|
| Tab | Moves to each copy button and "Show more" toggle in reading order. |
| Enter / Space | Copies the value, or expands and collapses it. |
A list without copyable or truncated items has nothing to focus.
Accessibility
- Role
- none (native dl/dt/dd semantics)
- Accessible name
- –
- Terms render as
<dt>and values as<dd>, so screen readers pair them. - The copy button is named "Copy {term}" when the term is text; pass
copyLabelotherwise. - The expand toggle is a button with
aria-expandedandaria-controlspointing at the value. - The default placeholder hides the dash from assistive technology and reads
emptyLabelinstead.
Responsive behaviour
- At 640px and below every column count collapses to one column.
columns={4}shows two columns between 641px and 1023px.- In
inlinelayout terms take a fixed 9rem column, and stack above the value below 420px.
Theme support
- Term, value, placeholder and link-coloured toggle use semantic text tokens.
- The toggle focus ring uses
--mn-color-focus-ring.
Do and don't
Do
- Use
widefor long values such as notes or addresses. - Pass missing values straight through; the placeholder handles them.
- Make ids, keys and URLs
copyable.
Don't
- Do not put form controls in a description list.
- Do not hide truncated values behind a
titleattribute only; usetruncate.
Related components
- RecordHeader: Renders its key facts with a DescriptionList.
- CopyButton: The copy affordance on
copyableitems. - Card: A surface to group the list.
Dependencies
| Kind | Depends on |
|---|---|
| npm packages | react |
| Monarch components | CopyButton |
Testing coverage
- Renders terms as
<dt>and values as<dd>. - Exposes columns and layout and forwards refs.
- Empty values show the placeholder read as "Not set";
0is a value. - Copies values with the keyboard and the pointer; no copy button for empty values.
- Clamps long values with an
aria-expandedtoggle shown only on overflow. - Renders on the server.
| Check | Covered |
|---|---|
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | Visual baselines: /__gallery/description-list; Cross-browser axe: /components/description-list |
Tests: packages/react/src/components/data-display/description-list