Skip to content

StatusPill

<caos-status-pill>

a tinted state pill on a record or configuration row

May be placed on a record page, an app’s home page and a page inside an app.

Name Attribute Description Type Default Required
intent intent, markup only The tint: info, success, warning, danger, muted or dev. It colours the lettering and the 1px edge — there is no filled chip, so the colour never has to be legible against itself. An unrecognised value draws the muted treatment. text — one of info, success, warning, danger, muted, dev muted Optional
dot dot, markup only Put a 6px dot ahead of the word, in the pill’s own colour. Useful in a dense list where the lettering is small enough that the tint alone is easy to miss. boolean false Optional

This piece raises no events.

Name What goes in it
the default slot The state name. One or two words — it is set in 9px tracked capitals.
Design token What it controls
--caos-color-info The lettering and edge of an info pill.
--caos-color-success The lettering and edge of a success pill.
--caos-color-warning The lettering and edge of a warning pill.
--caos-color-danger The lettering and edge of a danger pill.
--caos-color-text-muted The lettering and edge of a muted pill, which is also the untinted default.
--caos-color-accent-strong The lettering and edge of a dev pill — the one intent that moves with a tenant’s brand.
--caos-font-mono The typeface the state name is set in.
--caos-font-weight-label The weight of the state name.

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(pill) the pill Always
::part(dot) the dot inside it Always

The single lifecycle state of a record or a configuration row, where the state comes from a fixed vocabulary and only one of them is true at a time.

  • Tag — The word was typed by a person rather than chosen by the object’s lifecycle. That is the whole line between these two: a pill answers “what state is this record in”, one value from a closed vocabulary; a tag answers “what did somebody label this”, any number of values from no vocabulary at all. If a record can carry two of them at once, or if the words vary by who typed them, it is a tag. Using a pill for a free-form label spends the state colours on something that has no state, and after that nothing on the row can be read at a glance.
  • StatusDot — What is being reported is the health of a service or an integration rather than the state of a record — connected, degraded, down. A dot says it in nine pixels and needs no word.
  • ProvenanceMarker — The subject is one VALUE and where it came from — computed, overridden, synced — rather than the record and where it has got to.
  • NoticeBanner — The state needs explaining rather than naming. A pill is one or two words; anything that needs a sentence and a decision is a banner.

The state is TEXT, and that is the accessibility story: the word is read out as ordinary content, the colour only reinforces it, and the optional dot is hidden from assistive tech because it says nothing the word does not. No role is set, deliberately — a pill is a piece of the sentence it sits in, not a control or a live region. Left to the author: keeping the word, since a pill drawn with a dot and no label would be colour alone; and keeping the vocabulary short, because the lettering is 9px capitals and long states are what force a state column wider than the name column beside it.

One object’s states in the order a record passes through them, so the tints can be assigned to a vocabulary as a set rather than one pill at a time.

{
"id": "example",
"section": "A lifecycle vocabulary",
"columns": 1,
"items": [
{
"id": "status_pill_1",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "muted"
},
"children": [
"Draft"
]
},
{
"id": "status_pill_2",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "info"
},
"children": [
"In review"
]
},
{
"id": "status_pill_3",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "warning"
},
"children": [
"Awaiting approval"
]
},
{
"id": "status_pill_4",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "success"
},
"children": [
"Approved"
]
},
{
"id": "status_pill_5",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "danger"
},
"children": [
"Rejected"
]
}
]
}
<caos-status-pill intent="muted">Draft</caos-status-pill>
<caos-status-pill intent="info">In review</caos-status-pill>
<caos-status-pill intent="warning">Awaiting approval</caos-status-pill>
<caos-status-pill intent="success">Approved</caos-status-pill>
<caos-status-pill intent="danger">Rejected</caos-status-pill>

The distinction the library is drawing, made visible: the pill on the left is the one state the record is in, and the two chips beside it are labels people put on it. They are different components because they answer different questions.

{
"id": "example",
"section": "A state pill beside a label tag",
"columns": 1,
"items": [
{
"id": "status_pill_1",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "success"
},
"children": [
"Approved"
]
},
{
"id": "tag_2",
"type": "component",
"key": "tag",
"children": [
"Rush"
]
},
{
"id": "tag_3",
"type": "component",
"key": "tag",
"children": [
"Repeat customer"
]
}
]
}
<caos-status-pill intent="success">Approved</caos-status-pill>
<caos-tag>Rush</caos-tag>
<caos-tag>Repeat customer</caos-tag>

The same states with the optional dot, which is what a dense list wants — the tint reads from further away than 9px lettering does.

{
"id": "example",
"section": "With a leading dot",
"columns": 1,
"items": [
{
"id": "status_pill_1",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "success",
"dot": true
},
"children": [
"Closed"
]
},
{
"id": "status_pill_2",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "warning",
"dot": true
},
"children": [
"Blocked"
]
},
{
"id": "status_pill_3",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "danger",
"dot": true
},
"children": [
"Cancelled"
]
},
{
"id": "status_pill_4",
"type": "component",
"key": "status_pill",
"inputs": {
"intent": "dev",
"dot": true
},
"children": [
"Dev"
]
}
]
}
<caos-status-pill intent="success" dot>Closed</caos-status-pill>
<caos-status-pill intent="warning" dot>Blocked</caos-status-pill>
<caos-status-pill intent="danger" dot>Cancelled</caos-status-pill>
<caos-status-pill intent="dev" dot>Dev</caos-status-pill>