Skip to content

DetailSection

<caos-detail-section>

one titled block of a record page, holding the fields that belong together

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

Name Attribute Description Type Default Required
heading heading, markup only What this group of fields is called. Drawn as a mono uppercase category header over a hairline rule; a long one is truncated rather than wrapped. text none declared Optional
collapsible collapsible, markup only Turn the header into a real button that folds the content away, with a chevron that turns. Without it the header is a plain heading and nothing about the section is interactive. boolean false Optional
collapsed collapsed, markup only Start folded — and afterwards, the current state: the component sets and clears this itself as the header is pressed. Only meaningful alongside collapsible. boolean false Optional
readOnly read-only, markup only Draw the lock marker in the header saying these fields cannot be edited. It is a STATEMENT, not an enforcement — it does not disable anything placed inside, so whatever is in there has to be read-only in its own right. boolean false Optional
Name When it fires What it carries
caos-section-toggle The header of a collapsible section is pressed, or toggle() is called — before the state changes. It is cancelable: preventing it leaves the section as it was, which is how a host refuses to let a section be folded. { collapsed } — the state it is about to move to.
Name What goes in it
the default slot The body of the section: the fields that belong together — KeyValueRow rows, FieldRenderer fields, or a table. The section supplies the padding around them and nothing else; how they are laid out is up to what is placed here.
actions Controls that belong to this section, at the right-hand end of its header — an Edit button, an OverflowMenu. The row is not drawn when the slot is empty.
footer What belongs UNDER the body rather than beside the heading: a total, a “3 of 12 shown” line, a last-updated stamp, or the buttons that act on the whole block. Divided from the body by the same hairline the header uses, so a section with both reads as one card. Not drawn when the slot is empty, and folded away with the body when the section is collapsed.
Design token What it controls
--caos-color-surface The ground of the card.
--caos-color-border-strong The border around the card.
--caos-radius-lg The corners of the card.
--caos-shadow-card The elevation of the card.
--caos-color-border The hairline rule under the header, and the one over the footer.
--caos-color-surface-2 The tint a collapsible header takes on hover.
--caos-focus-ring The ring on a focused collapsible header.
--caos-font-mono The face of the heading and of the read-only marker.
--caos-color-text The heading ink.
--caos-color-text-muted The chevron and the read-only marker.
--caos-space-5 The padding of the content, and the inset the header rule stops at.
--caos-space-4 The header padding down, and the footer’s.
--caos-space-3 The gap between the chevron, the heading and the actions.
--caos-space-2 The gap between the controls in the actions slot, and between whatever sits in the footer.
--caos-space-1 The gap between the lock glyph and the words “Read only”.
Name Description Arguments
toggle() Fold or unfold the section, exactly as pressing the header does — the same cancelable event fires first. This is how something outside the section (an “expand all” control) drives it. takes none

Nothing on this piece can be read back.

Part Which piece of it When it is there
::part(section) the bordered section Always
::part(header) the header strip Always
::part(toggle) the header again — the same element, taking a second part name once it is a control Only while the section is collapsible. A section that cannot fold carries nothing under this name, so a stylesheet written against it matches nothing.
::part(title) the heading text Always
::part(actions) the action group at the right of the header Always
::part(content) the body the rows sit in Always
::part(footer) the strip under the body Always present as a part; it draws nothing until something is slotted into the footer.

Fields on a record that belong together and want naming — the record page’s unit of structure. Reach for it whenever a page has more fields than a person reads at once.

  • KeyValueRow — You want ONE pair, not a group. A single row does not need a titled card around it.
  • TabStrip — The groups are alternatives rather than a stack — facets of the same record, one shown at a time, rather than sections read down the page.
  • PageHeader — The title belongs to the whole surface rather than to one block of it.
  • Inspector — The fields belong in a panel beside the record rather than in the page flow.

A collapsible section is a real button carrying aria-expanded that tracks the state, so it is in the tab order, works from the keyboard and announces whether it is open — nothing to add. A non-collapsible section is a plain header with no button and no expanded state, which is correct: there is nothing to press. Two things are left to the author. The heading is styled text rather than an h2, so a surface that needs a heading outline has to provide one. And read-only draws a marker without enforcing anything — the fields inside must genuinely be read-only, or the marker is telling somebody something untrue.

The plain case: a titled card holding the rows that belong together, one of them with no value yet so the em dash shows.

{
"id": "example",
"section": "A section of fields",
"columns": 1,
"items": [
{
"id": "detail_section_1",
"type": "component",
"key": "detail_section",
"inputs": {
"heading": "Account information"
},
"children": [
{
"id": "key_value_row_2",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Name",
"value": "Meridian Supply"
}
},
{
"id": "key_value_row_3",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Owner",
"value": "Dana Whitfield"
}
},
{
"id": "key_value_row_4",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Region",
"value": "North"
}
},
{
"id": "key_value_row_5",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Reference",
"no_border": true
}
}
]
}
]
}
<caos-detail-section heading="Account information">
<caos-key-value-row label="Name" value="Meridian Supply"></caos-key-value-row>
<caos-key-value-row label="Owner" value="Dana Whitfield"></caos-key-value-row>
<caos-key-value-row label="Region" value="North"></caos-key-value-row>
<caos-key-value-row label="Reference" no-border></caos-key-value-row>
</caos-detail-section>

The same block made foldable — press the heading and it folds, and the chevron turns — with a control of its own in the header, which is where a section-scoped action goes.

{
"id": "example",
"section": "Foldable, with an action",
"columns": 1,
"items": [
{
"id": "detail_section_1",
"type": "component",
"key": "detail_section",
"inputs": {
"heading": "Delivery",
"collapsible": true
},
"children": [
{
"id": "button_2",
"type": "component",
"key": "button",
"inputs": {
"variant": "ghost",
"size": "sm"
},
"slot": "actions",
"children": [
"Edit"
]
},
{
"id": "key_value_row_3",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Region",
"value": "North"
}
},
{
"id": "key_value_row_4",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Terms",
"value": "Standard"
}
},
{
"id": "key_value_row_5",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Due date",
"value": "15 Sep 2026",
"no_border": true
}
}
]
}
]
}
<caos-detail-section heading="Delivery" collapsible>
<caos-button slot="actions" variant="ghost" size="sm">Edit</caos-button>
<caos-key-value-row label="Region" value="North"></caos-key-value-row>
<caos-key-value-row label="Terms" value="Standard"></caos-key-value-row>
<caos-key-value-row label="Due date" value="15 Sep 2026" no-border></caos-key-value-row>
</caos-detail-section>

The lock marker in the header, for a group whose values come from somewhere else and are not edited here — a different statement from folding one away.

{
"id": "example",
"section": "Stated as read only",
"columns": 1,
"items": [
{
"id": "detail_section_1",
"type": "component",
"key": "detail_section",
"inputs": {
"heading": "Amount summary",
"read_only": true
},
"children": [
{
"id": "key_value_row_2",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Subtotal",
"value": "12,400"
}
},
{
"id": "key_value_row_3",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Adjustments",
"value": "1,150"
}
},
{
"id": "key_value_row_4",
"type": "component",
"key": "key_value_row",
"inputs": {
"label": "Total",
"value": "13,550",
"no_border": true
}
}
]
}
]
}
<caos-detail-section heading="Amount summary" read-only>
<caos-key-value-row label="Subtotal" value="12,400"></caos-key-value-row>
<caos-key-value-row label="Adjustments" value="1,150"></caos-key-value-row>
<caos-key-value-row label="Total" value="13,550" no-border></caos-key-value-row>
</caos-detail-section>