# Data List

Show the details of one record as label and value rows, side by side or stacked.

Subscription details

[Complete TSX file](/examples/data-list/default.tsx)

```tsx
"use client";

import {
  Card,
  CardHeader,
  CardPanel,
  CardTitle,
} from "@/siteplane/components/card";
import {
  DataList,
  DataListItem,
  DataListLabel,
  DataListValue,
} from "@/siteplane/components/data-list";

const subscription = [
  { label: "Plan", value: "Pro, billed yearly" },
  { label: "Renewal", value: "March 1, 2027" },
  { label: "Seats", value: "12 of 20 in use" },
  { label: "Billing email", value: "billing@northlight.studio" },
];

export default function Example() {
  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>Subscription</CardTitle>
      </CardHeader>
      <CardPanel>
        <DataList>
          {subscription.map((detail) => (
            <DataListItem key={detail.label}>
              <DataListLabel>{detail.label}</DataListLabel>
              <DataListValue>{detail.value}</DataListValue>
            </DataListItem>
          ))}
        </DataList>
      </CardPanel>
    </Card>
  );
}
```

## Installation

Complete [one-time setup](/docs/installation/) first.

```bash
pnpm dlx shadcn@4.18.0 add @siteplane/data-list
```

With npm: `npx shadcn@4.18.0 add @siteplane/data-list`. [Registry JSON](/registry/data-list.json) lists source files and dependencies.

For this page’s examples, also install:

```bash
pnpm dlx shadcn@4.18.0 add @siteplane/badge @siteplane/card @siteplane/code @siteplane/separator
```

## Usage

```tsx
import {
  DataList,
  DataListItem,
  DataListLabel,
  DataListValue,
} from "@/siteplane/components/data-list";

<DataList>
  <DataListItem>
    <DataListLabel>Plan</DataListLabel>
    <DataListValue>Pro, billed yearly</DataListValue>
  </DataListItem>
</DataList>;
```

## Composition

```text
DataList
└── DataListItem
    ├── DataListLabel
    └── DataListValue
```

`DataList` renders a description list, `dl`. Each `DataListItem` groups one `DataListLabel`, a `dt`, with its `DataListValue`, a `dd`, so assistive technologies read every label with its value.

## Label column

The labels share one column, beside their values. It is as wide as the widest label, up to 40% of the list, and the values take the rest, 16 px after it. A longer label wraps inside the column. Set `--data-list-label-width` on `DataList` for a fixed column, so that lists one under another line up:

```tsx
<DataList className="[--data-list-label-width:8rem]">
```

Labels take the quieter text at the regular weight and values the primary text. Long values, such as a URL or an ID without spaces, wrap within their column and never widen the list.

## Dividers

Set `dividers` to draw the hairline that cards and separators draw between two items, with 12 px above and below it. The first item keeps no space above its content and the last item none below it, so the text lines up with the content around the list, as in this card. A value can hold inline parts, such as a `Code`, a `Badge` or a `time` element.

Connection details with dividers

[Complete TSX file](/examples/data-list/dividers.tsx)

```tsx
"use client";

import { Badge } from "@/siteplane/components/badge";
import {
  Card,
  CardHeader,
  CardPanel,
  CardTitle,
} from "@/siteplane/components/card";
import { Code } from "@/siteplane/components/code";
import {
  DataList,
  DataListItem,
  DataListLabel,
  DataListValue,
} from "@/siteplane/components/data-list";
import { Separator } from "@/siteplane/components/separator";

export default function Example() {
  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>Connection</CardTitle>
      </CardHeader>
      <Separator role="presentation" />
      <CardPanel>
        <DataList dividers>
          <DataListItem>
            <DataListLabel>Fields</DataListLabel>
            <DataListValue>1,248 in 12 folders</DataListValue>
          </DataListItem>
          <DataListItem>
            <DataListLabel>Last sync</DataListLabel>
            <DataListValue>
              <time dateTime="2026-10-15T16:20">Today, 4:20 PM</time>
            </DataListValue>
          </DataListItem>
          <DataListItem>
            <DataListLabel>Agent</DataListLabel>
            <DataListValue>Claude Code on a MacBook Pro</DataListValue>
          </DataListItem>
          <DataListItem>
            <DataListLabel>Package</DataListLabel>
            <DataListValue>
              <Code>1.1.0</Code>{" "}
              <Badge variant="warning">1.2.0 available</Badge>
            </DataListValue>
          </DataListItem>
        </DataList>
      </CardPanel>
    </Card>
  );
}
```

## Vertical

Set `orientation="vertical"` to place each label above its value, for a narrow column such as a side panel, or for long values. The label sits 4 px above its value and the items are 16 px apart.

Billing details with labels above the values

[Complete TSX file](/examples/data-list/vertical.tsx)

```tsx
"use client";

import {
  DataList,
  DataListItem,
  DataListLabel,
  DataListValue,
} from "@/siteplane/components/data-list";

export default function Example() {
  return (
    <DataList className="w-full max-w-md" orientation="vertical">
      <DataListItem>
        <DataListLabel>Company</DataListLabel>
        <DataListValue>Northlight Studio Inc.</DataListValue>
      </DataListItem>
      <DataListItem>
        <DataListLabel>Billing address</DataListLabel>
        <DataListValue>
          500 Market Street, San Francisco, CA 94105
        </DataListValue>
      </DataListItem>
      <DataListItem>
        <DataListLabel>Tax ID</DataListLabel>
        <DataListValue>94-1234567</DataListValue>
      </DataListItem>
    </DataList>
  );
}
```

## API reference

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| DataList.orientation | DataListOrientation: horizontal \| vertical | horizontal | horizontal sets each label beside its value, in one label column; vertical sets each label above its value. |
| DataList.dividers | boolean | false | Draws a hairline between two items, with 12 px above and below it. |
| DataList --data-list-label-width | CSS length | fit-content(40%) | Width of the horizontal label column: as wide as the widest label, up to 40% of the list. Set it on DataList, for example with className="[--data-list-label-width:8rem]". |
| DataListItem | div props | — | One label and its value. |
| DataListLabel | dt props | — | The name of a value. |
| DataListValue | dd props | — | The value: text or inline parts, such as a Badge, a Code or a link. |
DataListProps extends native dl props; DataListItem, DataListLabel and
DataListValue accept native div, dt and dd props. All parts accept refs,
children and string className. DataListOrientation is exported. The list holds
no state and renders on the server.

[Read the installed source](/source/data-list).

## Usage notes

Use a Data List for the properties of one record, such as an account, a deployment or an invoice. Use [Table](/docs/components/table/) when people compare, sort or filter many records, and [Settings List](/docs/components/settings-list/) when every row holds a control that changes a setting.
