Skip to content
Component installs need the registry setup
VegaStack Design

Property List

Record-facts rows — an icon + label column beside a value column, rendered as an accessible definition list.

Status
stable
Since
0.3.0
Accessibility pattern
native description list

Last updated

Domains
attio.com
Name
Attio
Team
Set a value…
Categories
Information TechnologyB2B

Install

Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Property List before installation. Retain the digest printed by this command.

pnpm exec vegastack-design verify property-list

Install with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.

pnpm dlx shadcn@4.21.0 add @vegastack/property-list

Run the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.

Usage

import {
  PropertyLabel,
  PropertyList,
  PropertyRow,
  PropertyValue,
} from "@/components/ui/property-list";

<PropertyList aria-label="Record details">
  <PropertyRow>
    <PropertyLabel icon={<Globe />}>Domains</PropertyLabel>
    <PropertyValue>
      <a href="…">attio.com</a>
    </PropertyValue>
  </PropertyRow>
  <PropertyRow>
    <PropertyLabel icon={<Users />}>Team</PropertyLabel>
    <PropertyValue>
      <span className="text-sm text-muted-foreground">Set a value…</span>
    </PropertyValue>
  </PropertyRow>
</PropertyList>;

Anatomy

A <dl> of <dt>(label)/<dd>(value) pairs. The list is a named container (@container/property-list), and the row layout follows the PANE's width rather than the viewport's — the same facts pane is as often a narrow sidebar on a wide screen as a wide column on a narrow one:

  • At @xs and up — two tracks. The label track shrinks to its content above an 80px floor (minmax(calc(var(--spacing) * 20), max-content)), so short labels stop wasting the value column's width and long ones are no longer clipped by a track that never negotiated with them.
  • Below @xs — the row stacks, and the value gets the full width instead of a sliver.

Values wrap; they do not truncate. A value is the point of its row, and the overflow: hidden that truncation implies also clipped the focus ring of any link inside it. Compose TruncatedText explicitly where a single line is genuinely required. Values are compositions: plain text, a link, a TagGroup, or a muted placeholder span for the "Set a value…" slot.

Semantics

The definition list announces each label→value relationship natively. Label icons are decorative (aria-hidden); keep the text label present — never an icon-only <dt>.

PropertyList vs DataList vs SettingsRow

PropertyListDataListSettingsRow
Shapekey→value panehomogeneous <table>label + control row
Forrecord facts, metadatacollections of recordspreference forms

Anatomy

Property List is a compound component. Every exported part, with the data-slot it renders (generated from the canonical source):

PropertyEmpty — data-slot="property-empty"
PropertyLabel — data-slot="property-label"
PropertyList — data-slot="property-list"
PropertyRow — data-slot="property-row"
PropertySection — data-slot="property-section" | "property-section-title"
PropertyValue — data-slot="property-value"

Examples

Compose plain values, links, empty values, and tag groups in the same aligned definition list. Long values wrap onto as many lines as they need; the label track sizes itself to the longest label above its 80px floor. Rows are top-aligned: the label sits on the value's first line, so a value that wraps keeps its label beside its opening line, and a quiet picker or select trigger shares the label's centre like plain text does.

Domains
attio.com
Name
Attio
Team
Set a value…
Categories
Information TechnologyB2B

Narrow panes

In a narrow record pane the value wraps rather than clipping, and below @xs the row stacks so the value gets the full width. An unset property renders a muted placeholder — an honest "nothing here yet" affordance instead of a blank row a reader has to interpret.

Domains
marketing.internal.example-corporation.com
Name
Example Corporation Holdings
Team
Set a value…

Inline rows and sections

variant="inline" is the record-aside row for a narrow rail card: icon + label in a fixed 112px column (a long label truncates, its full text in the tooltip), and the value left-aligned in the second column, so every value starts at the same x — as in Linear or Notion. An editable value is a ghost Record Chip (variant="ghost"): PropertyValue hangs its padding past the column's start and its 24px height outside the line, so its text lines up with plain values and every row is the same height. An editable text value is an inline Editable Cell: PropertyValue gives it the same compact box — 6px and 2px of padding hung outside by equal negative margins — so its text keeps the plain values' left edge, baseline and row height at rest, on hover and while editing, and the tint sits just around it. An unset value is the chip's muted placeholder ("Set due date"), or PropertyEmpty ("—") when it cannot be edited. PropertySection puts a small muted title over values too big for a row (chips, people). The rail's other value shapes — an avatar, avatar rows with "+N", a long value clamped to three lines — are in Record Aside.

Type
Client call
Duration
42 min
Code
RL-26-104
Owner
Follow-up
Created at
Region
—

Linked to

Two columns

columns={2} flows the rows into two columns, left to right, once the list's own container is at least @xl (36rem) wide — a wide record pane reads as two columns of facts — and keeps one column in a narrower pane, whatever the viewport. It works with both variants: inline keeps its fixed label column inside each column. The third list below is the same inline list in a 288px rail, back to one column.

Type
Pendant
Brand
Regent
SKU
RL-26-104
Lead time
6 weeks
Finish
Matt black
Origin
Switzerland
Owner
Asha Rao
Updated
2 days ago
Type
Pendant
Brand
Regent
SKU
RL-26-104
Lead time
6 weeks
Finish
Matt black
Origin
Switzerland
Owner
Asha Rao
Updated
2 days ago
Type
Pendant
Brand
Regent
SKU
RL-26-104
Lead time
6 weeks
Finish
Matt black
Origin
Switzerland
Owner
Asha Rao
Updated
2 days ago

API Reference

PropertyList

PropTypeDefaultDescription
columns1 | 212 flows the rows into two columns, left to right, once the list's own container is wide enough (@xl, 36rem) — a wide record pane reads as two columns of facts, and the same list in a narrow rail stays one column. Works with both variants; inline keeps its fixed label column inside each column.
variant"inline" | "stacked""stacked"stacked — the label column beside the value, stacking when the pane is narrow. inline — the record-aside row for a narrow rail card: a fixed 112px label column (a long label truncates, its full text in the tooltip), so every value starts at the same x, left-aligned, as in Linear or Notion; its editable values are quiet pickers — RecordChip variant="ghost".

Data attributes and CSS variables on PropertyList

AttributeValues
data-columnsmirrors a prop or state value
data-slot"property-list"
data-variantmirrors a prop or state value

PropertyRow

PropertyRow accepts native <div> props and groups one <dt>/<dd> pair.

PropertyLabel

PropTypeDefaultDescription
iconReact.ReactNode—Leading inline-role icon (decorative — the text carries the meaning).

Data attributes and CSS variables on PropertyLabel

AttributeValues
data-slot"property-label"

PropertyValue

PropertyValue accepts native <dd> props and forwards its ref to the value cell.

PropertyEmpty

PropTypeDefaultDescription
childrenReact.ReactNode"—"What an unset value shows. Pass a quiet "+ Add" picker trigger instead when the value is editable.

Data attributes and CSS variables on PropertyEmpty

AttributeValues
data-slot"property-empty"

PropertySection

PropTypeDefaultDescription
title*React.ReactNode—The section's small muted title, e.g. "Participants" or "Linked to".

Data attributes and CSS variables on PropertySection

AttributeValues
data-slot"property-section" | "property-section-title"

Accessibility

  • Native <dl>, <dt>, and <dd> semantics expose each label/value relationship.
  • Label icons are decorative; always keep a visible text label.
  • Links and controls inside values keep their native keyboard behavior and focus indicator.
  • Source order remains label then value in both LTR and RTL layouts.
  • Values do not clip their overflow, so a link inside one keeps its full focus outline.
KeyAction
TabMove through links and controls inside property values.
EnterActivate the focused link or control.
ContractStates tested
Behaviourdefault
Accessibilitylabeled, semantic-html
Visualdefault

Do / Don't

Do
Use PropertyList for stable record facts with concise labels and honest empty values.
Don't
Use it for a homogeneous record collection, hide a label behind an icon alone, or add overflow-hidden to a value — it clips the focus ring of any link inside.

On this page