Skip to main content

Description List

A semantically correct description list built on the HTML <dl> element. Renders a list of label/value pairs, commonly used in detail views to display metadata about a resource.

Compose <DescriptionList.Root> with <DescriptionList.Item>, <DescriptionList.Label>, and <DescriptionList.Value> as direct children.

Key
my-api-key
ID
aigk_2fKm9x8Hn3QpYT7zKlR0vW5
Description
Production API key for the billing service
Created
2 days ago by admin@example.com
Last Used
Never
Metadata
17 Bytes
import { DescriptionList } from "@ngrok/mantle/description-list"; <DescriptionList.Root>	<DescriptionList.Item>		<DescriptionList.Label>Key</DescriptionList.Label>		<DescriptionList.Value className="font-bold">my-api-key</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>ID</DescriptionList.Label>		<DescriptionList.Value translate="no">aigk_2fKm9x8Hn3QpYT7zKlR0vW5</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>Description</DescriptionList.Label>		<DescriptionList.Value>Production API key for the billing service</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>Created</DescriptionList.Label>		<DescriptionList.Value>2 days ago by admin@example.com</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>Last Used</DescriptionList.Label>		<DescriptionList.Value>			<span className="italic text-muted">Never</span>		</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>Metadata</DescriptionList.Label>		<DescriptionList.Value>17 Bytes</DescriptionList.Value>	</DescriptionList.Item></DescriptionList.Root>;

Composition

Compose the parts of a DescriptionList together to build your own:

DescriptionList.Root└── DescriptionList.Item    ├── DescriptionList.Label    └── DescriptionList.Value

Polymorphism

DescriptionList.Root, DescriptionList.Item, DescriptionList.Label, and DescriptionList.Value each accept an asChild prop. When true, the part renders its single child instead of its default element (<dl>, <div>, <dt>, <dd>), forwarding all class names, data-* attributes, and the ref onto that child.

import { DescriptionList } from "@ngrok/mantle/description-list"; <DescriptionList.Root>	<DescriptionList.Item>		<DescriptionList.Label>Docs</DescriptionList.Label>		<DescriptionList.Value asChild>			<a href="https://mantle.ngrok.com">mantle.ngrok.com</a>		</DescriptionList.Value>	</DescriptionList.Item></DescriptionList.Root>;

Actions in a row

To put a copy button or another action beside a value, use an IconButton with size="2xs". Its 20px box fits inside the line of text, so a row with an action is the same height as a row without one. Wrap the value text in its own element beside the button.

Name
my-api-key
ID
aigk_2fKm9x8Hn3QpYT7zKlR0vW5
import { IconButton } from "@ngrok/mantle/button";import { DescriptionList } from "@ngrok/mantle/description-list";import { CopyIcon } from "@phosphor-icons/react/Copy"; <DescriptionList.Root>	<DescriptionList.Item>		<DescriptionList.Label>Name</DescriptionList.Label>		<DescriptionList.Value>my-api-key</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>ID</DescriptionList.Label>		<DescriptionList.Value className="flex items-center gap-2">			<span translate="no" className="truncate">				aigk_2fKm9x8Hn3QpYT7zKlR0vW5			</span>			<IconButton				appearance="ghost"				intent="neutral"				size="2xs"				label="Copy ID"				icon={<CopyIcon />}			/>		</DescriptionList.Value>	</DescriptionList.Item></DescriptionList.Root>;

Long values

The value column has a 0 minimum width, so a long value stays inside its row instead of widening the list. Set the overflow behavior on DescriptionList.Value or on a child: truncate clips a single line with an ellipsis, and wrap-anywhere breaks a line at any character. DescriptionList.Value does not need min-w-0.

When the end of the value is the part that matters, as in a URL or an ID, render it with TruncatedText: the head clips and the tail stays visible.

Token
aigk_2fKm9x8Hn3QpYT7zKlR0vW5bN1cD4eF6gH8jK0lM2nP4qR6sT8uV0wX2yZ4aB6cD8eF0gH2jK4
import { DescriptionList } from "@ngrok/mantle/description-list"; <DescriptionList.Root>	<DescriptionList.Item>		<DescriptionList.Label>Request URL</DescriptionList.Label>		<DescriptionList.Value>			<span className="block truncate">				https://example.ngrok.app/api/items?filter=%7B%22name%22%3A%22very-long-value%22%7D&limit=200&offset=0			</span>		</DescriptionList.Value>	</DescriptionList.Item>	<DescriptionList.Item>		<DescriptionList.Label>Token</DescriptionList.Label>		<DescriptionList.Value translate="no" className="wrap-anywhere">			aigk_2fKm9x8Hn3QpYT7zKlR0vW5bN1cD4eF6gH8jK0lM2nP4qR6sT8uV0wX2yZ4aB6cD8eF0gH2jK4		</DescriptionList.Value>	</DescriptionList.Item></DescriptionList.Root>;

Content that cannot shrink and has no scroll container of its own (a wide table, a pre) overflows its cell. DescriptionList.Root scrolls to reveal it. Give that content overflow-x-auto to scroll it inside the row instead.

API Reference

DescriptionList.Root

The root container for a description list. Renders a <dl> element. The value column has a 0 minimum width, so a value that truncates or wraps stays inside the row instead of widening the list.

All props from dl, plus:

PropTypeDefaultDescription
children?ReactNodeCompose DescriptionList.Item components as direct children.
className?stringAdditional CSS class names to apply to the root element.
asChild?booleanfalseUse the asChild prop to compose the DescriptionList.Root styling onto alternative element types or your own React components.

Every part stamps a data-slot. A data-slot passed to DescriptionList.Root joins in front of its own value instead of replacing it.

Data AttributeValueDescription
data-slot"description-list"The <dl>.
data-slot"description-list-item"The row wrapper.
data-slot"description-list-label"The <dt>.
data-slot"description-list-value"The <dd>.

DescriptionList.Item

A wrapper that groups a DescriptionList.Label and DescriptionList.Value pair. Renders a <div> with a default subgrid layout that inherits column tracks from the root.

All props from div, plus:

PropTypeDefaultDescription
children?ReactNodeA DescriptionList.Label and DescriptionList.Value pair.
className?stringAdditional CSS class names to apply to the item wrapper.
asChild?booleanfalseUse the asChild prop to compose the DescriptionList.Item styling onto alternative element types or your own React components.

DescriptionList.Label

The label for a description list item. Renders a <dt> element.

All props from dt, plus:

PropTypeDefaultDescription
children?ReactNodeThe label text for this description list item.
className?stringAdditional CSS class names to apply to the label element.
asChild?booleanfalseUse the asChild prop to compose the DescriptionList.Label styling onto alternative element types or your own React components.

DescriptionList.Value

The value for a description list item. Renders a <dd> element. Compose any content inside — the component imposes no layout on its children.

All props from dd, plus:

PropTypeDefaultDescription
children?ReactNodeThe value content for this description list item. Can be any React node — text, formatted values, interactive elements, etc.
className?stringAdditional CSS class names to apply to the value element.
asChild?booleanfalseUse the asChild prop to compose the DescriptionList.Value styling onto alternative element types or your own React components.