Skip to content
omaris

Data Display

Data List

Key/value details — an order's number, status and total; a profile's email, role and join date — as a real <dl>, so a screen reader reads each label with its value rather than as two unrelated runs of text.

import { DataList } from 'omaris'
Learn

Examples

Basic

An order's details as a real <dl>. The labels sit in a column beside their values, and the whole list stacks once it is narrower than 24rem.

Order
#4021
Status
Paid
Customer
Kurdistan Coffee Roasters
Placed
3 March 2026, 2:20 PM
Delivery note
Not set
<script lang="ts">	import { Badge, DataList, DataListItem } from 'omaris';</script>​<DataList dividers class="max-w-lg">	<DataListItem label="Order" value="#4021" copyable />	<DataListItem label="Status">		<Badge tone="success" variant="tonal">Paid</Badge>	</DataListItem>	<DataListItem label="Customer" value="Kurdistan Coffee Roasters" />	<DataListItem label="Placed" value="3 March 2026, 2:20 PM" />	<DataListItem label="Delivery note" /></DataList>

Profile

vertical stacks each label over its value — the shape of a profile panel. copyable adds a copy button whose own tick is the confirmation; a string copies something other than what is shown, like the full key behind a mask.

Name
Grace Hopper Grace Hopper
Email
grace@example.com
API key
sk_live_••••••••4f2a
Role
Owner
<script lang="ts">	import { Avatar, DataList, DataListItem } from 'omaris';</script>​<DataList orientation="vertical" class="max-w-sm">	<DataListItem label="Name">		<span class="inline-flex items-center gap-2">			<Avatar size="xs" name="Grace Hopper" colorize />			Grace Hopper		</span>	</DataListItem>	<DataListItem label="Email" value="grace@example.com" copyable>		{#snippet icon()}			...		{/snippet}	</DataListItem>	<DataListItem label="API key" value="sk_live_••••••••4f2a" copyable="sk_live_51Hx9q2Lp4f2a" />	<DataListItem label="Role" value="Owner" /></DataList>

Receipt

align="end" is the receipt: every figure at the far edge, lined up under the one above. size steps the type and the row padding together.

Subtotal
42,000 IQD
Delivery
3,500 IQD
Discount
−5,000 IQD
Total
40,500 IQD
<script lang="ts">	import { Card, DataList, DataListItem } from 'omaris';</script>​<Card class="w-80 max-w-full">	<DataList align="end" size="sm">		<DataListItem label="Subtotal" value="42,000 IQD" />		<DataListItem label="Delivery" value="3,500 IQD" />		<DataListItem label="Discount" value="−5,000 IQD" />	</DataList>	<DataList align="end" size="lg" class="border-t border-border pt-3">		<DataListItem label="Total" value="40,500 IQD" classes={{ value: 'font-semibold' }} />	</DataList></Card>

Overridden

labelWidth sets the label column, and the caller's own style and aria-label are kept beside it. classes reaches a row's parts — here a monospaced tracking number with its own copy label.

Carrier
Aramex
Tracking
AX-99120-IQ
Weight
2.4 kg
<script lang="ts">	import { DataList, DataListItem } from 'omaris';</script>​<DataList	labelWidth="7rem"	style="max-width: 28rem"	aria-label="Shipment"	dividers	class="w-full divide-dashed">	<DataListItem label="Carrier" value="Aramex" />	<DataListItem		label="Tracking"		value="AX-99120-IQ"		copyable		copyLabel="Copy tracking number"		classes={{ label: 'text-primary', content: 'font-mono' }}	/>	<DataListItem label="Weight" value="2.4 kg" /></DataList>

When to use it

Use it for

  • The details of one thing — an order's number, status, customer and date; a user's email, role and join date — as label/value pairs in a real <dl>.
  • A detail panel that has to read right in a wide page, a side sheet and a phone: horizontal puts labels beside values and stacks them on its own once the list is narrower than 24rem.
  • A profile or settings summary with each label over its value: orientation="vertical".
  • Values people paste elsewhere — an order number, an API key, an IBAN — with copyable, whose own tick is the confirmation.
  • A receipt's totals, lined up at the far edge: align="end".

Not for

  • Many records of the same shape, compared or sorted → Table.
  • Rows you press to open something → List.
  • Values the person edits in place → Input in a form, or Inline Edit for one field at a time.
  • One headline figure and its trend → Stat Card.
  • Nested or arbitrary data — an API response → JSON Viewer.

Do

  • Keep labels short and the same kind of word — nouns, "Email", "Role" — so the column scans.
  • Put rich values in the children — a Badge for a status, an Avatar and a name, a link.
  • Leave an unknown value empty rather than writing "N/A"; the row shows a dash and tells a screen reader the value is not set.
  • Set labelWidth when labels are long, so the value column does not start halfway across a narrow panel.

Don't

  • Wrap it in a Card per row; one dividers list is one object.
  • Use copyable on values nobody pastes — a status, a date.
  • Fire a toast from a copy; the button already turned into a tick.
  • Put a paragraph in a value. A long note belongs under the list as body text.

Quick reference

orientation
  • horizontal (default)
  • vertical
size
  • sm
  • md (default)
  • lg
align
  • start (default)
  • end

API

DataList

Key/value details — an order's number, status and total; a profile's email, role and join date — as a real <dl>, so a screen reader reads each label with its value rather than as two unrelated runs of text.

horizontal puts the labels in a column beside their values, and stacks them on its own once the list itself is narrower than 24rem. That is a container query, not a screen one, so the same list reads right in a wide page, a side panel and a phone without being told which it is in.

import { DataList } from 'omaris'
<DataList dividers>  <DataListItem label="Order" value="#4021" copyable />  <DataListItem label="Status"><Badge tone="success">Paid</Badge></DataListItem></DataList>

Props

orientation

Defaults to 'horizontal'

DataListOrientation

horizontal puts each label in a column beside its value, and stacks them once the list is narrower than 24rem. vertical always stacks.

size

Defaults to 'md'

DataListSize

Text size and row padding together.

dividers

Defaults to false

boolean

A hairline between rows.

align

Defaults to 'start'

DataListAlign

Where values sit in a horizontal list. end is the receipt layout — a total at the far edge, lined up with the numbers above it.

labelWidth
number | string

Width of the label column in a horizontal list: pixels, or any CSS length. Defaults to 40% of the list, up to 12rem.

class
string
children
Snippet

DataListItem

One row of a DataList: a <dt> and its <dd>, grouped in a <div> the way the HTML spec allows, so each row can be styled as one.

copyable adds a copy button after the value — an order number, an API key, an IBAN. The confirmation is the button itself turning into a tick, right where the finger is; there is no toast to say what the tick said.

import { DataListItem } from 'omaris'

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
label
The <dt>.
value
The <dd>: the value and, if there is one, the copy button.
content
The value itself, which wraps rather than pushing the row wider.
copy
The copy button.

Props

label required
string

The term — "Order", "Email", "Joined".

value
string | number | null

The value, as text. Use children for anything richer — a badge, a link, an avatar. With neither, the row shows a dash and tells a screen reader the value is not set.

copyable

Defaults to false

boolean | string

Add a copy button after the value. true copies what is shown — the value, or the text of the children; a string copies that instead, for a value displayed differently from how it is pasted (a masked key, a formatted IBAN).

copyLabel
string

Accessible name of the copy button. Defaults to "Copy {label}".

class
string
classes
DataListItemClasses

Per-part Tailwind overrides. class still covers the root.

icon
Snippet

An icon before the label.

children
Snippet

Rich value, in place of value.