Cloud|

@k2b/ui

Description list

Semantic responsive key-value details with optional actions.

DescriptionList@k2b/uiSelect@k2b/ui

Semantic key-value content in a responsive grid or compact inspector rows. Both layouts retain real dl/dt/dd elements and support optional actions. A plain control as a row's value turns the whole row into that control.

Responsive gridScan a small set of peer facts across one to three columns.
Owner
Platform team
Region
Europe West
Created
31 July 2026
Repository
cloud
Open repository
Compact rowsAlign terms and values for inspector metadata and settings summaries.
Created
31 July 2026, 14:32
Updated
13 August 2026, 18:41
ID
Res7K2
Copy resource ID
Property rowsValues read as text; hover shows a quiet surface and a click anywhere in the row edits.
Due
Estimate
Priority
Labels
Created
31 July 2026, 14:32

TSX

Copy
{/* Scan-friendly facts */}
<DescriptionList columns={2} items={facts} />
{/* Compact metadata in a detail panel */}
<DescriptionList
layout="rows"
size="sm"
actionVisibility="progressive"
items={metadata}
/>
{/* Property rows: the value is the control, the whole row opens it */}
<DescriptionList
layout="rows"
size="sm"
items={[
{ term: "Due", description: <DateTimePicker aria-label="Due" appearance="plain" placeholder="No due date" clearable value={due} onValueChange={setDue} /> },
{ term: "Estimate", description: <NumberInput aria-label="Estimate" appearance="plain" placeholder="No estimate" suffix="min" min={1} formatValue={formatDuration} value={estimate} onValueCommit={setEstimate} /> },
{ term: "Priority", description: <Select aria-label="Priority" appearance="plain" placeholder="No priority" clearable options={priorities} value={priority} onValueChange={setPriority} /> },
{ term: "Labels", description: <MultiSelectInput aria-label="Labels" appearance="plain" placeholder="Label" placeholderIcon="ti ti-plus" options={labelOptions} value={labels} onValueChange={setLabels} /> },
]}
/>

DescriptionList presents exact key-value information with native description-list semantics.

Use DescriptionList

Use it for metadata, summaries, and compact detail panels. In layout="rows", a value may contain one compact control such as a status or assignee picker when that control has its own accessible name. Use a normal form layout for broader editing, and do not use the component for arbitrary card layouts.

Assistant details views use DescriptionList with layout="rows" for one record's 1..100 exact fields. These rows are read-only; number and date text uses the viewer's locale. A Cloud reference carries no URL and opens through the owning app's reader with the viewer's access after a confirmation; its pill keeps the neutral page icon, because a reference names an app object rather than a kind the chat knows. A hidden copy with stand-in text of each value's length reserves the rows, including lines that wrap on a phone, up to twelve one-line rows; more scrolls inside the record.

Property rows

A property row shows a value that people edit in place: label left, value as plain text, and the whole row as the control. Put a control with appearance="plain" directly into a row's description: Select and MultiSelectInput, the date pickers, or NumberInput. Give it an "aria-label" that repeats the term.

The row keeps its height and columns. Hovering anywhere in the row, keyboard focus, or an open picker paints a quiet surface 0.5rem past the row on both sides, behind the label and value; focus adds the ring to that surface. A click on the label opens the picker or edits the number. Nothing in the list moves between these states, and an item action stays clickable above the row. Because the surface reaches past the row, keep 0.5rem of room on both sides, as a DetailPanel.Summary or a section inside a DetailPanel.Group does. A list flush against a scrolling or clipping edge cuts off the surface and its ring.

Mix property rows with plain text rows freely. For people who cannot edit, render the same value as text, such as the dot and label of a priority or the Tag chips of labels, instead of a disabled control. The row then has no hover surface.

In layout="rows", the term sits where a one-line value sits. A value made of row-height lines, such as wrapping plain pills or a list of linked items, keeps the term beside its first line. Plain text that wraps starts at the top of the row, so the term sits slightly below its first line; keep row values short and move long text to its own section.

Import

tsx
import { Button, DescriptionList } from "@k2b/ui";

Layout

columns controls the wide-screen grid and collapses to one column on narrow screens. Set layout="rows" for a compact inspector-style label/value list. An item may provide one short action directly related to its value. Set actionVisibility="progressive" when repeated row actions should stay quiet: with a mouse or trackpad, including a tablet with a mouse, they stay hidden until their row is hovered, keyboard-focused, or has its menu open. Touch-only screens always show them.

Use layout="compact" for read-mostly metadata in previews and small panels. Labels size to their content (up to 40% of the available width), with a smaller horizontal gap than the space between rows. Unlike inspector rows, compact rows do not reserve extra height for controls. Values can wrap without losing their association with the label.

API reference

ts
type DescriptionListItem = {
  term: JSX.Element; description: JSX.Element; action?: JSX.Element;
};

type DescriptionListProps = {
  items: readonly DescriptionListItem[]; columns?: 1 | 2 | 3; layout?: "grid" | "rows" | "compact"; size?: "sm" | "md";
  actionVisibility?: "always" | "progressive"; class?: string;
};

columns defaults to 1, layout to "grid", and actionVisibility to "always"; size defaults to "md". Item content accepts Solid JSX. Only a plain control that is the direct value of a rows item takes over the row; nested deeper, such as an add action below a list of entries, it covers only itself.

Accessibility

The component renders real dl, dt, and dd elements. A property row's control keeps its own role and name; the row-wide hit area only extends where a pointer reaches it and adds no second tab stop. Terms must be concise, descriptions must remain meaningful without visual position, and icon-only actions need labels. Progressive actions remain keyboard-focusable and become visible through focus-within. An open menu keeps its trigger visible, and touch-only screens always show progressive actions. Visibility must never be the only indication that an action exists.

Runtime

Description lists are server-renderable and need no client JavaScript unless an item action is interactive.

Example

tsx
<DescriptionList
  layout="rows"
  actionVisibility="progressive"
  items={[
    { term: "Owner", description: "Platform team" },
    { term: "Region", description: "Europe West" },
    { term: "Repository", description: "cloud", action: <Button size="xs">Open</Button> },
  ]}
/>

Connect a coding agent

The Cloud skill provides compact working instructions. MCP supplies exact current documentation when details matter.

CLI command
bunx skills add https://docs.example.com

This command installs the working instructions published by this website in the selected coding agent.

For exact, current details, also connect the MCP server through one of the agent tabs.

Installation uses the open-source Vercel Skills CLI.

The skill and MCP complement each other: the skill describes workflows, while MCP supplies current documentation.