Skip to content

PagePending

<caos-page-pending>

the state a page or route wears while it waits

Nowhere yet — this piece is not offered to a page.

Name Attribute Description Type Default Required
pending pending, markup only The whole declaration: this page or route is waiting. Set, the mark and its line are drawn and the element reports itself busy. Unset, it draws nothing, announces nothing and takes up no space, so a surface can mount it once and toggle it rather than build and discard it. boolean false Optional
size size, markup only How big the mark is drawn, on the platform size scale — the same five steps the icon and the avatar take. A value that names no step falls back to the default rather than being refused. text — one of xs, sm, md, lg, xl lg Optional
label label, markup only The line under the mark, and the thing that is actually announced — say what is being waited on (“Confirming your email…”), not that something is happening. An empty value is read as asking for the default rather than for silence. text Loading… Optional

This piece raises no events.

Nothing goes inside this piece.

Design token What it controls
--caos-font The typeface of the line under the mark.
--caos-space-3 The gap between the mark and its line.
--caos-space-6 The space above and below the pair.
--caos-space-5 The space to either side of them.
--caos-size-xs-height The mark at the xs step.
--caos-size-sm-height The mark at the sm step.
--caos-size-md-height The mark at the md step.
--caos-size-lg-height The mark at the lg step, which is the default.
--caos-size-xl-height The mark at the xl step.

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(container) the centred column holding the mark and its line Always
::part(mark) the ring Always
::part(label) the line under it, which is also the live region Always

The PAGE is what is waiting: a route reached from a link, before it knows what it is going to be. If a control started the wait, the control says so; if a region of a known shape is filling, the placeholder says so. This is the case where neither exists.

  • Button — Somebody clicked something and that click is what is taking time. The button’s own loading flag draws the mark on the control that caused the wait and makes it non-interactive, which is the whole story for a save.
  • SkeletonBlock — A region whose shape is already known is filling. A placeholder in the shape of the content that is coming keeps the layout still when the data lands; a mark drawn over the top of it moves everything twice.
  • ProgressBar — There is an operation to report on, with or without a number. A bar says “a job is running and here is how far”; this says “the page has not resolved yet”.
  • EmptyState — The wait is over and the answer was nothing. A pending state left up forever is how a person ends up staring at a page that has already finished failing.

While pending is set the element carries aria-busy, and the line of copy sits in a role="status" live region so it is announced politely rather than interrupting. Clearing pending EMPTIES that region and drops aria-busy — the announcement is retracted rather than left standing by a mark that merely stopped turning, which is the difference between a reader being told the page resolved and a reader being told nothing more. The ring itself is aria-hidden: it says the same thing as the line beside it, and saying it twice is worse than once. Left to the author: giving it a label that names what is being waited on, and taking it down when the wait ends rather than when the next paint happens to remove it.

The whole piece: a ring and the thing being waited on, named. This is what an email verification page shows between the click and the answer.

{
"id": "example",
"section": "A route that landed from a link",
"columns": 1,
"items": [
{
"id": "page_pending_1",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"label": "Confirming your email…"
}
}
]
}
<caos-page-pending pending label="Confirming your email…"></caos-page-pending>

The same element under prefers-reduced-motion: reduce. The ring stops; it does not change, because it was already three quarters of a circle and that is the part that reads as unfinished. Turn the setting on and the example above becomes this one.

{
"id": "example",
"section": "The same page, reduced motion",
"columns": 1,
"items": [
{
"id": "page_pending_1",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"label": "Confirming your email…"
}
}
]
}
<caos-page-pending pending label="Confirming your email…"></caos-page-pending>

The platform size scale, the same five the icon and the avatar take. A small step suits a route that resolves inside a card; the larger ones suit a page with nothing else on it.

{
"id": "example",
"section": "The five steps",
"columns": 1,
"items": [
{
"id": "page_pending_1",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"size": "xs",
"label": "Loading at xs…"
}
},
{
"id": "page_pending_2",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"size": "sm",
"label": "Loading at sm…"
}
},
{
"id": "page_pending_3",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"size": "md",
"label": "Loading at md…"
}
},
{
"id": "page_pending_4",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"size": "lg",
"label": "Loading at lg…"
}
},
{
"id": "page_pending_5",
"type": "component",
"key": "page_pending",
"inputs": {
"pending": true,
"size": "xl",
"label": "Loading at xl…"
}
}
]
}
<caos-page-pending pending size="xs" label="Loading at xs…"></caos-page-pending>
<caos-page-pending pending size="sm" label="Loading at sm…"></caos-page-pending>
<caos-page-pending pending size="md" label="Loading at md…"></caos-page-pending>
<caos-page-pending pending size="lg" label="Loading at lg…"></caos-page-pending>
<caos-page-pending pending size="xl" label="Loading at xl…"></caos-page-pending>

Without pending there is nothing to see and nothing to hear: no mark, no line, no busy state, and no space taken. This is the state a surface leaves it in rather than removing it.

{
"id": "example",
"section": "After it resolves",
"columns": 1,
"items": [
{
"id": "page_pending_1",
"type": "component",
"key": "page_pending",
"inputs": {
"label": "Confirming your email…"
}
}
]
}
<caos-page-pending label="Confirming your email…"></caos-page-pending>