---
id: "packages/active-ui/description-list"
title: "DescriptionList"
description: "Read-only label and value pairs as a real description list, stacked in columns or inline in a narrow container."
url: "/packages/active-ui/description-list"
locale: "en"
revision: "a9b023d663a626f9"
---

# DescriptionList

`DescriptionList` shows the properties of a record as label and value pairs: a policy number, a
start date, a premium. It renders a `<dl>` with a `<div>` per pair. Use `stacked` with columns at
page width, and `inline` in a dialog, a side panel or a narrow card.

**Example: Stacked and inline pairs**

Client: Runs entirely in your browser. Source: `examples/ui/description-list.tsx`.

```tsx
// apps/docs/examples/ui/description-list.tsx
import {
  DescriptionItem,
  DescriptionList,
} from '@workspace/active-ui/components/composed/description-list';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@workspace/active-ui/components/primitives/card';

/**
 * Read-only label and value pairs: stacked in three columns at page width,
 * inline in a narrow card. An item without a value shows a dash; `0` is a
 * value. The data is fictitious.
 */
export default function DescriptionListExample() {
  return (
    <div className="grid w-full gap-8">
      <DescriptionList columns={3}>
        <DescriptionItem label="Policy number">PN-2026-00418</DescriptionItem>
        <DescriptionItem label="Premium" className="tabular-nums">
          € 1,240.00
        </DescriptionItem>
        <DescriptionItem label="Start date">1 January 2026</DescriptionItem>
        <DescriptionItem label="Claims">{0}</DescriptionItem>
        <DescriptionItem label="End date">{null}</DescriptionItem>
        <DescriptionItem label="Intermediary">Northwind Advice</DescriptionItem>
      </DescriptionList>
      <Card className="max-w-xs">
        <CardHeader>
          <CardTitle>Participant</CardTitle>
        </CardHeader>
        <CardContent>
          <DescriptionList columns={1} orientation="inline">
            <DescriptionItem label="Name">Ada Jansen</DescriptionItem>
            <DescriptionItem label="Born">3 March 1971</DescriptionItem>
            <DescriptionItem label="Scheme">Career average</DescriptionItem>
          </DescriptionList>
        </CardContent>
      </Card>
    </div>
  );
}
```

## What the composition adds

- **Columns that collapse**: `columns` 1 to 4 (default 2) from the `sm` width; below it always one
  column.
- **Two orientations**: `stacked` (default), the label above the value; `inline`, the label beside
  it, set from the list so items stay simple.
- **An empty value is a dash**: `null`, `undefined` and `''` show `-`; `0` is a value.
- **`className` on an item** applies to label and value together, such as `tabular-nums`.

No formatting, no hiding of empty items and no status logic: the values arrive formatted, and an
item you leave out is not rendered. A large key figure is a [StatCard](/packages/active-ui/stat-card).

## Usage

```tsx
import {
  DescriptionItem,
  DescriptionList,
} from '@workspace/active-ui/components/composed/description-list';

<DescriptionList columns={3}>
  <DescriptionItem label="Policy number">{policy.number}</DescriptionItem>
  <DescriptionItem label="End date">
    {policy.endDate && formatDate(policy.endDate)}
  </DescriptionItem>
</DescriptionList>;
```

## What your application provides

- Formatted values, translated labels, and a word instead of the dash where your readers need one.
- The choice to leave an item out: `{value && <DescriptionItem …/>}`.

## Accessibility

A screen reader announces a description list with its pairs, term and definition. Keep labels
short; they name their value.

## API

**DescriptionList**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | yes | Only {@link DescriptionItem} elements. |
| `columns` | `DescriptionListColumns` | no | Number of columns from `sm` up. Default: 2. |
| `orientation` | `DescriptionListOrientation` | no | Direction of the label relative to the value. Default: `"stacked"`. |

**DescriptionItem**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | `ReactNode` | yes | The translated label. The caller supplies the text; this component does not translate. |
| `children` | `ReactNode` | no | The formatted value: text, or any node (`StatusBadge`, `Link`, `Badge`, a custom composition).  `null`, `undefined` and `''` count as empty and yield a dash. `0` is **not** an empty value and is shown as `0`. |

**DescriptionListColumns**

```ts
type DescriptionListColumns = 1 | 2 | 3 | 4;
```

The number of columns from `sm` up. Below `sm` the list is always a single
column — see the notes on {@link DescriptionList}.

Four is the measured maximum (metadata strips with short values). More
columns are deliberately impossible: a label/value pair needs room, and
anyone who thinks they need more should look at a table.

**DescriptionListOrientation**

```ts
type DescriptionListOrientation = 'stacked' | 'inline';
```

The direction in which label and value sit relative to each other.

- `"stacked"` (default) — label above the value. The shape for detail
screens and overview cards at full page width.
- `"inline"` — label on the left, value next to it. The shape for narrow
containers: dialogs, side panels and narrow cards, where stacking
needlessly doubles the height.

The choice follows from the **width of the container**, not from taste.

**DescriptionListProps**

```ts
interface DescriptionListProps extends React.ComponentProps<'dl'> {
  columns?: DescriptionListColumns;
  orientation?: DescriptionListOrientation;
  children: React.ReactNode;
}
```

**DescriptionItemProps**

```ts
interface DescriptionItemProps extends Omit<
  React.ComponentProps<'div'>,
  'children'
> {
  label: React.ReactNode;
  children?: React.ReactNode;
}
```
