Skip to content

ToastStack

<caos-toast-stack>

where toasts accumulate

May be placed on a seam in the workspace frame.

Name Attribute Description Type Default Required
max max, markup only How many toasts may stay mounted. Anything past the cap is REMOVED oldest-first, so a burst cannot grow without bound. Unset (or zero) means uncapped. number none declared Optional
float float, markup only Pin the stack to a corner of the screen instead of flowing where it was put. The region itself becomes transparent to the pointer; the toasts inside it stay interactive. boolean false Optional
position position, markup only Which corner to pin to when floating: bottom-right, bottom-left, top-right or top-left. A bottom corner also reverses the stacking order, so the newest toast is the one nearest the edge and the list reads bottom-up. text — one of bottom-right, bottom-left, top-right, top-left bottom-right Optional

This piece raises no events.

Name What goes in it
the default slot The toasts. Appending one is what “arrived” means; it is the newest.
Design token What it controls
--caos-space-2 The gap between one toast and the next.
--caos-space-5 How far a floating stack sits from the two screen edges of its corner.
Name Description Arguments
push() Mount a toast into the stack as the newest one. The same thing as appending it — a name for the operation, so a caller does not have to know that DOM order is arrival order. toast: CaosToast

Nothing on this piece can be read back.

Part Which piece of it When it is there
::part(region) the region the toasts stack in Always

A surface raises more than one transient notice and they need somewhere to go, in order, with a cap on how many can pile up. If a screen only ever raises one at a time and already has a place to put it, a Toast on its own is enough.

  • Toast — A single notice, mounted somewhere the surface already has room for it.
  • NoticeBanner — The notice must not disappear — anything in this region can be dismissed, or pushed out by a later notice once the cap is reached.

The region is a labelled role=“region” with aria-live=“polite”, so a toast arriving is announced without interrupting — a danger toast overrides that with its own role=“alert”. A floating stack is transparent to the pointer except where a toast actually is, so it never eats a click meant for the page under it. What is left to the author: a toast dropped for exceeding max is removed silently, so the cap should be high enough that a person can plausibly have read what it displaces.

The default: the stack flows where it was put, spacing its toasts, so it composes inside any layout.

{
"id": "example",
"section": "Two notices, in place",
"columns": 1,
"items": [
{
"id": "toast_stack_1",
"type": "component",
"key": "toast_stack",
"inputs": {
"max": 3
},
"children": [
{
"id": "toast_2",
"type": "component",
"key": "toast",
"inputs": {
"intent": "success"
},
"children": [
"Order saved."
]
},
{
"id": "toast_3",
"type": "component",
"key": "toast",
"inputs": {
"intent": "warning"
},
"children": [
"Two line items have no amount."
]
}
]
}
]
}
<caos-toast-stack max="3">
<caos-toast intent="success">Order saved.</caos-toast>
<caos-toast intent="warning">Two line items have no amount.</caos-toast>
</caos-toast-stack>

Four toasts declared against a cap of two: the two oldest were removed, not hidden. Compare the code below with what is on the stage.

{
"id": "example",
"section": "At the cap",
"columns": 1,
"items": [
{
"id": "toast_stack_1",
"type": "component",
"key": "toast_stack",
"inputs": {
"max": 2
},
"children": [
{
"id": "toast_2",
"type": "component",
"key": "toast",
"inputs": {
"intent": "info"
},
"children": [
"Totals refreshed."
]
},
{
"id": "toast_3",
"type": "component",
"key": "toast",
"inputs": {
"intent": "info"
},
"children": [
"Draft saved."
]
},
{
"id": "toast_4",
"type": "component",
"key": "toast",
"inputs": {
"intent": "success"
},
"children": [
"Order saved."
]
},
{
"id": "toast_5",
"type": "component",
"key": "toast",
"inputs": {
"intent": "warning"
},
"children": [
"Two line items have no amount."
]
}
]
}
]
}
<caos-toast-stack max="2">
<caos-toast intent="info">Totals refreshed.</caos-toast>
<caos-toast intent="info">Draft saved.</caos-toast>
<caos-toast intent="success">Order saved.</caos-toast>
<caos-toast intent="warning">Two line items have no amount.</caos-toast>
</caos-toast-stack>

The floating case, which is what a workspace actually uses: pinned to the top-right of the screen rather than flowing in the page.

{
"id": "example",
"section": "Pinned to a corner",
"columns": 1,
"items": [
{
"id": "toast_stack_1",
"type": "component",
"key": "toast_stack",
"inputs": {
"float": true,
"position": "top-right",
"max": 3
},
"children": [
{
"id": "toast_2",
"type": "component",
"key": "toast",
"inputs": {
"intent": "success"
},
"children": [
"Order saved."
]
},
{
"id": "toast_3",
"type": "component",
"key": "toast",
"inputs": {
"intent": "info"
},
"children": [
"Totals refreshed from the rate table."
]
}
]
}
]
}
<caos-toast-stack float position="top-right" max="3">
<caos-toast intent="success">Order saved.</caos-toast>
<caos-toast intent="info">Totals refreshed from the rate table.</caos-toast>
</caos-toast-stack>