# List

> Typographic list (ul or ol) that renders `items` on the text ladder; size matches the surrounding Text voice, listStyleType styles or removes markers, and spacing owns the inter-item rhythm.

- Status: stable
- Group: structure
- Page: https://www.digitaltableteur.com/design-system/components/list
- Contract: https://www.digitaltableteur.com/contracts/v1/List.contract.json

## When to use

List renders `items` as a typographic list on the text ladder: `as` picks ul/ol semantics, `size` matches the surrounding Text voice, `listStyleType` styles or removes markers, `spacing` sets the rhythm between items. It owns inter-item spacing; no margins on items. For custom marker treatments (like ProcessBlock's em dashes) pass `listStyleType="none"` and style via className.

## When not to use

- Do not pass pre-wrapped `<li>` elements in items; items are the contents; List renders the li.
- Do not use it for a single item or for layout; Stack is layout, List is list semantics.
- Do not use a list for a single item or for layout; Stack is layout, List is semantics.

## Look-alikes

The contract names no look-alike with a deciding condition.

## Props

| Prop | Type | Default | Description | Required |
| --- | --- | --- | --- | --- |
| `items` | `React.ReactNode[]` | none | Ordered content rendered as one list item per entry. | Yes |
| `as` | `"ol" \| "ul"` | `ul` | Semantic list element. | No |
| `className` | `string` | `""` | Additional class name applied to the list element. | No |
| `size` | `"xl" \| "xs" \| "s" \| "xxs" \| "m" \| "l" \| "xxl"` | `m` | Tokenized text size. | No |
| `lineHeight` | `"normal" \| "tight" \| "snug" \| "relaxed" \| "loose"` | none | Optional tokenized line height. | No |
| `style` | `React.CSSProperties` | none | Inline style merged before the computed marker style: when listStyleType or striped resolves a marker, it overrides style.listStyleType. | No |
| `listStyleType` | `"none" \| "decimal" \| "circle" \| "square" \| "disc" \| "decimal-leading-zero" \| "lower-alpha" \| "upper-alpha" \| "lower-roman" \| "upper-roman" \| "dash"` | none | Native marker style or the custom dash treatment. "none" and "dash" blank the native marker with a single-space string, not CSS none, so Safari and VoiceOver keep list semantics. | No |
| `spacing` | `"normal" \| "relaxed" \| "compact"` | `normal` | Vertical spacing between items. | No |
| `role` | `string` | none | Optional ARIA role override for specialized list semantics. | No |
| `striped` | `boolean` | `false` | Alternate row backgrounds for long lists of multi-line entries; rows get padding and no markers unless listStyleType asks for them. This includes as="ol", so a striped ordered list hides its numbers unless listStyleType is set. | No |

## Variants

- Available sizes: `s`, `m`, `l`, `xxs`, `xs`, `xl`, `xxl` (default `m`).
- Allowed `as` values: `ol`, `ul` (default `ul`).
- Allowed `lineHeight` values: `normal`, `tight`, `snug`, `relaxed`, `loose`.
- Allowed `listStyleType` values: `none`, `decimal`, `circle`, `square`, `disc`, `decimal-leading-zero`, `lower-alpha`, `upper-alpha`, `lower-roman`, `upper-roman`, `dash`.
- Available spacings: `normal`, `relaxed`, `compact` (default `normal`).

## Invalid combinations

The contract records no invalid combinations.

## Keyboard

The contract records no keyboard interaction.

## Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

| Level | Rule | How it is checked |
| --- | --- | --- |
| MUST | ARIA: Renders a real `<ul>`/`<ol>` with one `<li>` per entry, so assistive tech announces list role and item count. | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | ARIA: `listStyleType="none"` maps to a single-space marker (`" "`) rather than CSS `none`, which preserves list semantics in Safari/VoiceOver where `list-style:none` silences them. `listStyleType="dash"` gets the same single-space marker and draws the dash with `li::before`, so dash lists keep list semantics too. | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | Required stories produce no axe violations at the configured severity. | Automated by `npm run test:stories:matrix:ci`. WCAG 2.5.8. |
| MUST | The accessibility tree (role, name, state) matches the committed snapshot for every required story. | Automated by `npm run test:stories:matrix:ci`. WCAG 1.3.1, 4.1.2. |
| MUST | The component remains legible and operable under a real browser forced-colors: active pass. | Automated by `npm run test:stories:hc`. |
| MUST | A human completed an end-to-end accessibility review of this component. | Manual review, last on 2026-11-04. |
| SHOULD | Pick as by meaning: ol when order matters, ul otherwise. | Not stated in the contract. |
| SHOULD | Match size to the surrounding Text so lists read as part of the prose voice. | Not stated in the contract. |
| SHOULD | Use spacing (compact\|normal\|relaxed) for rhythm instead of margins on items. | Not stated in the contract. |
| SHOULD | Use listStyleType none plus a class for custom markers; keep the semantic list element. | Not stated in the contract. |
| SHOULD NOT | Do not pass pre-wrapped li elements in items; items are the contents; List renders the li. | Not stated in the contract. |

## Install and import

- Install: `npm install @digitaltableteur/react` (version 0.9.1, restricted access on npm).
- Import: `import { List } from "@digitaltableteur/react";`
- Entry point: `@digitaltableteur/react/content` exports it too.
- Styles: import `@digitaltableteur/react/style.css` once at the app boundary.
- Also available as the custom element `<dt-list>`; see the custom elements manifest.

## Links

- Machine-readable contract (Design System Contract 1.0): https://www.digitaltableteur.com/contracts/v1/List.contract.json
- Markdown version of this page: https://www.digitaltableteur.com/design-system/components/list.md
- Component index as JSON: https://www.digitaltableteur.com/design-system/components.json
- All components: https://www.digitaltableteur.com/design-system/components
- Source: The implementation lives in a private repository. This page, its Markdown twin and the contract are generated from it at build time and are the public source of truth.
