<!-- Protocore Design System — DefinitionList -->
# DefinitionList

- **Category:** Data Display (`data-display`)
- **Slug:** `data-display/definition-list`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { DefinitionList } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/data-display/definition-list

> A dt/dd record display — mono uppercase label beside (or above) a typed value atom.

## When to use it

DefinitionList is for **one entity's fields** — a transaction's details, a deployment's config, a key's metadata: the key→value view you'd see in a detail panel or the expanded row of a list.

Use a **Table** instead when you're comparing *many* records across the *same* columns — DefinitionList is deliberately a single-record layout. It's structure only: it renders the `dt`/`dd` scaffold and expects each value to be a typed value atom (CodeRef for ids, MaskedValue for secrets, MoneyAmount for money, Badge for status, RelativeTime for timestamps) rather than a bare string, so the record reads consistently with the rest of the console.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `className` | `string` | no | — | — |
| `items` | `DefinitionListItem[]` | no | — | Rows as data, an alternative to composing `DefinitionList.Item` children. |
| `labelWidth` | `string \| number` | no | `160` | Width of the label column in the `horizontal` variant — a number (px) or any CSS length. Defaults to `160px`. Ignored when `stacked`. |
| `style` | `CSSProperties` | no | — | — |
| `variant` | `enum` | no | `horizontal` | Layout: `horizontal` puts the label in a fixed-width column beside the value; `stacked` puts the label above the value. Defaults to `horizontal`. |

## Examples

### Basics

Horizontal is the default: a fixed-width mono UPPERCASE label in a column beside a sans value. Tune the column with `labelWidth`. Each value should be a **typed atom** — CodeRef, MoneyAmount, Badge, RelativeTime — never a naked string.

```tsx
import { DefinitionList, CodeRef, Badge, MoneyAmount, RelativeTime } from "@protocore/pds";

// Horizontal is the default: a fixed-width mono UPPER label beside a sans value.
// Each value is a typed atom, never a naked string.
export default function DefinitionListBasics() {
  return (
    <DefinitionList labelWidth={140}>
      <DefinitionList.Item term="Transaction">
        <CodeRef full="txn_9f2c1a7e40b3" />
      </DefinitionList.Item>
      <DefinitionList.Item term="Amount">
        <MoneyAmount amount={4_120_00} minorUnits={2} currency="EUR" />
      </DefinitionList.Item>
      <DefinitionList.Item term="Status">
        <Badge tone="success">Settled</Badge>
      </DefinitionList.Item>
      <DefinitionList.Item term="Created">
        <RelativeTime value="2026-07-03T09:24:00Z" />
      </DefinitionList.Item>
    </DefinitionList>
  );
}
```

### Stacked

Set `variant="stacked"` to put the label above the value. Use it in narrow columns and side panels where a fixed label column would crowd the value.

```tsx
import { DefinitionList, Tag, MaskedValue } from "@protocore/pds";

// `stacked` puts the label above the value — good in narrow columns and side
// panels where a fixed label column would crowd the value.
export default function DefinitionListStacked() {
  return (
    <DefinitionList variant="stacked">
      <DefinitionList.Item term="API key">
        <MaskedValue value="sk_live_9f2c1a7e40b3c21b" copyable />
      </DefinitionList.Item>
      <DefinitionList.Item term="Environment">
        <Tag bordered>prod</Tag>
      </DefinitionList.Item>
      <DefinitionList.Item term="Scopes">ledger:read · ledger:write</DefinitionList.Item>
    </DefinitionList>
  );
}
```

## Usage

**Do**

- Use it for a single record's fields in detail panels and expanded rows.
- Fill each value with the right typed atom (CodeRef, MoneyAmount, Badge, RelativeTime, MaskedValue).
- Switch to `stacked` in narrow side panels; keep `horizontal` in wide detail views.
- Use `span` for long values like URLs or addresses so they aren't cramped.

**Don't**

- Don't use it to compare many records — that's a Table.
- Don't put naked strings where a value atom exists (ids, secrets, money, time).
- Don't nest a whole form inside it; it's read-only record display.
- Don't fight the mono UPPERCASE label styling with per-item overrides.

## Accessibility

**Notes**

- DefinitionList renders semantic `<dl>` / `<dt>` / `<dd>` markup, so assistive tech announces each term paired with its description.
- It carries no interactive semantics of its own; keyboard behaviour comes from the value atoms inside (e.g. a copyable MaskedValue or a CodeRef).
- The mono uppercase label is a visual style — the underlying `<dt>` text is read as-authored, so keep terms human-legible.

## Related

`table`, `code-ref`, `masked-value`, `badge`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
