KeyValueList
The facts of one thing as names and values side by side: the headers of a message, the details of a connection, the properties of a record. A compound component on a description list (<dl>). For a setting a person changes, use a SettingsRow instead.
import { KeyValueList } from '@adecore/ui';import { KeyValueList } from '@adecore/ui';
export default function KeyValueListDemo() {
return (
<KeyValueList.Root className="w-full max-w-sm">
<KeyValueList.Item>
<KeyValueList.Name>Length</KeyValueList.Name>
<KeyValueList.Value>3 min 45 s</KeyValueList.Value>
</KeyValueList.Item>
<KeyValueList.Item>
<KeyValueList.Name>Tempo</KeyValueList.Name>
<KeyValueList.Value>118 BPM</KeyValueList.Value>
</KeyValueList.Item>
<KeyValueList.Item>
<KeyValueList.Name>Mood</KeyValueList.Name>
<KeyValueList.Value>Warm, unhurried, with a lift in the last chorus</KeyValueList.Value>
</KeyValueList.Item>
</KeyValueList.Root>
);
}<KeyValueList.Root>
<KeyValueList.Item>
<KeyValueList.Name>Tempo</KeyValueList.Name>
<KeyValueList.Value>118 BPM</KeyValueList.Value>
</KeyValueList.Item>
</KeyValueList.Root>Parts
| Part | What it is |
|---|---|
KeyValueList.Root | The list, a <dl>. divided puts a hairline between rows. |
KeyValueList.Item | One row, which holds a name and its value. |
KeyValueList.Name | The name, a <dt>, in the faint text color. |
KeyValueList.Value | The value, a <dd>. mono sets it in the monospace face. |
Every part takes className, ref and a render prop to draw another element.
Alignment
The names take the width of the widest one, so every value starts on the same line. A long name stops at two fifths of the list and wraps there, so a list of message headers never squeezes its values into a sliver. A value wraps too, also in the middle of a long token or URL, instead of running out of its column.
A long list
divided draws a hairline between rows and gives each a little air, for a list that runs to dozens of rows. Without it the rows sit close, which suits three or four facts in a card. mono on a value sets it in the monospace face, for a header, an id or a path that a person reads back letter by letter.
import { KeyValueList } from '@adecore/ui';
const HEADERS: [string, string][] = [
['From', 'Billing <billing@example.com>'],
['To', 'ada@example.com'],
['Subject', 'Your invoice for September'],
['Message-ID', '<20261005134412.4f8a2c91e7b3@mail.example.com>'],
['DKIM-Signature', 'v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=mail; h=from:to:subject:date; bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='],
['X-Mailer-Campaign-Identifier', 'autumn-billing-2026']
];
export default function KeyValueListDividedDemo() {
return (
<KeyValueList.Root divided className="w-full max-w-xl">
{HEADERS.map(([name, value]) => (
<KeyValueList.Item key={name}>
<KeyValueList.Name>{name}</KeyValueList.Name>
<KeyValueList.Value mono>{value}</KeyValueList.Value>
</KeyValueList.Item>
))}
</KeyValueList.Root>
);
}Rich content
A name and a value take any content: an Icon before a name, a status icon before a value, or a row of Pills. An icon sits on the middle of the line of text beside it.
import { CircleCheck, Globe, KeyRound, Server } from 'lucide-react';
import { Icon, KeyValueList, Pill } from '@adecore/ui';
export default function KeyValueListRichDemo() {
return (
<KeyValueList.Root divided className="w-full max-w-md">
<KeyValueList.Item>
<KeyValueList.Name>
<Icon icon={Server} size={14} /> Host
</KeyValueList.Name>
<KeyValueList.Value mono>smtp.example.com</KeyValueList.Value>
</KeyValueList.Item>
<KeyValueList.Item>
<KeyValueList.Name>
<Icon icon={Globe} size={14} /> Port
</KeyValueList.Name>
<KeyValueList.Value mono>587</KeyValueList.Value>
</KeyValueList.Item>
<KeyValueList.Item>
<KeyValueList.Name>
<Icon icon={KeyRound} size={14} /> Security
</KeyValueList.Name>
<KeyValueList.Value>
<Icon icon={CircleCheck} size={14} className="text-positive" /> STARTTLS
</KeyValueList.Value>
</KeyValueList.Item>
<KeyValueList.Item>
<KeyValueList.Name>Tags</KeyValueList.Name>
<KeyValueList.Value className="flex flex-wrap gap-1">
<Pill>billing</Pill>
<Pill>autumn</Pill>
</KeyValueList.Value>
</KeyValueList.Item>
</KeyValueList.Root>
);
}Copying
The interface around it cannot be selected, but a value can: a person selects a header or a token and copies it with the platform's shortcut. The names stay out of the selection.
KeyValueListRootProps, KeyValueListItemProps, KeyValueListNameProps and KeyValueListValueProps are exported types.