Skip to content

KeyValueRow

<caos-key-value-row>

one label/value pair for read-only detail

May be placed on a record page and a page inside an app.

Name Attribute Description Type Default Required
label label, markup only What the field is called. Drawn as a mono uppercase kicker in the muted ink. A label slotted into the label slot is drawn after this text, so use one or the other. text none declared Optional
value value, markup only The value, as a plain string — already formatted, because this piece formats nothing. Slotted content is drawn beside it and is what to use for a value that is not plain text. With neither, the row shows an em dash. text none declared Optional
stacked stacked, markup only Put the label ABOVE the value instead of beside it. This is the field-group cell — several stacked rows laid into a grid by whatever holds them makes a field-group card. boolean false Optional
interactive interactive, markup only Make the value LOOK editable or linkable: a pointer, and a dashed accent underline that hugs the value on hover. Appearance only — it adds no click handling and raises no event, so the surface has to make the row actually do something. boolean false Optional
noBorder no-border, markup only Drop the hairline under the row. Set it on the last row of a group, where the rule would otherwise draw a line across the bottom of the section’s content. boolean false Optional

This piece raises no events.

Name What goes in it
the default slot The value, when it is not plain text: a StatusPill, a Tag, a link, a ProvenanceMarker, or a SkeletonBlock standing in while it loads. Anything here suppresses the em dash.
label The label, when it needs to be more than a string — a label with a Tooltip or an InlineHint beside it. Drawn after any text set through the label attribute.
Design token What it controls
--caos-font-mono The face of the label kicker.
--caos-font-weight-label The weight of the label.
--caos-color-text-muted The label ink, and the em dash on an empty row.
--caos-font The face of the value.
--caos-text-body The size of the value.
--caos-color-text The value ink.
--caos-color-border The hairline under the row.
--caos-color-accent The underline and ink an interactive value takes on hover.
--caos-space-4 The gap between the label column and the value.
--caos-space-2 The padding above and below the row.
--caos-space-1 The gap between label and value in the stacked variant.

Nothing else drives this piece by calling it.

Nothing on this piece can be read back.

Part Which piece of it When it is there
::part(row) the row Always
::part(label) the label side Always
::part(value) the value side Always

Showing one field of a record that is being READ. If the value can be changed here, it is a field rather than a row, and a field piece should draw it — the interactive attribute makes a row look editable without making it editable.

  • FieldRenderer — The value can be EDITED, or its type should decide how it draws. That piece reads or edits whatever it is handed, in that field’s own type.
  • DetailSection — You are placing the group rather than the row — the titled card these sit inside.
  • StatTile — The value is a headline figure being read on its own rather than one field among many.
  • DataTable — The same fields are being read across several records. A column of rows repeated per record is a table drawn the hard way.

The label and the value are read in order as ordinary text, and a row with no value is read as an em dash rather than as silence — so an empty field is not mistaken for a missing one. What is left to the author is the label wording and, above all, the interactive attribute: it is appearance only, so a row that looks editable but is not is announced as plain text and reached by nobody using a keyboard. If the row is meant to do something, the thing that does it has to be a real control placed in the value slot.

Four fields as they read down a section, the last of them with no value so the em dash stands in and the last rule dropped.

{
"id": "example",
"section": "Rows of a record",
"columns": 1,
"items": [
{
"id": "key_value_row_1",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Account",
"value": "Meridian Supply"
}
},
{
"id": "key_value_row_2",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Reference",
"value": "ORD-4471"
}
},
{
"id": "key_value_row_3",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Total",
"value": "12,400"
}
},
{
"id": "key_value_row_4",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Purchase order",
"no_border": true
}
}
]
}
<caos-key-value-row label="Account" value="Meridian Supply"></caos-key-value-row>
<caos-key-value-row label="Reference" value="ORD-4471"></caos-key-value-row>
<caos-key-value-row label="Total" value="12,400"></caos-key-value-row>
<caos-key-value-row label="Purchase order" no-border></caos-key-value-row>

The same pairs with the label over the value — the cell shape a field-group card is built from, which is a different reading order from the row above and not just a narrower one.

{
"id": "example",
"section": "Stacked, as a field group",
"columns": 1,
"items": [
{
"id": "key_value_row_1",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Account",
"value": "Meridian Supply",
"stacked": true
}
},
{
"id": "key_value_row_2",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Stage",
"value": "Draft",
"stacked": true
}
},
{
"id": "key_value_row_3",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Owner",
"value": "D. Whitfield",
"stacked": true
}
}
]
}
<caos-key-value-row label="Account" value="Meridian Supply" stacked></caos-key-value-row>
<caos-key-value-row label="Stage" value="Draft" stacked></caos-key-value-row>
<caos-key-value-row label="Owner" value="D. Whitfield" stacked></caos-key-value-row>

A pill in the value slot instead of a string, and beside it a row marked interactive — which only LOOKS editable on hover, and needs the surface to make it do something.

{
"id": "example",
"section": "A value that is not text",
"columns": 1,
"items": [
{
"id": "key_value_row_1",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Stage"
},
"children": [
{
"id": "status_pill_2",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "muted"
},
"children": [
"Draft"
]
}
]
},
{
"id": "key_value_row_3",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Owner",
"value": "D. Whitfield",
"interactive": true,
"no_border": true
}
}
]
}
<caos-key-value-row label="Stage">
<caos-status-pill intent="muted">Draft</caos-status-pill>
</caos-key-value-row>
<caos-key-value-row label="Owner" value="D. Whitfield" interactive no-border></caos-key-value-row>