Toast
A brief notification in a fixed corner stack; canvas surface behind a 1px overlay border, status tints for the four polite statuses and the danger fill for critical ones.
stable · light DOM · 4.0.0. Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.
Live variants
default
Settings saved.
<j3w1-toast id="example-toast-default"><div class="toast-stack" role="region" aria-label="Notifications">
<div class="toast" role="status">
<span class="toast-glyph" aria-hidden="true">i</span>
<p class="toast-text">Settings saved.</p>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
<span class="toast-count" aria-hidden="true">+2</span>
</div>
</div></j3w1-toast>status
Connection lost. Changes are queued.
Battery at 10%.
Screenshot copied.
Workspace 3 moved to the left output.
Layout locked.
<j3w1-toast id="example-toast-status"><div class="toast-stack" role="region" aria-label="Notifications">
<div class="toast toast-danger" role="alert">
<span class="toast-glyph" aria-hidden="true">✕</span>
<p class="toast-text">Connection lost. Changes are queued.</p>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
</div>
<div class="toast toast-warning" role="status">
<span class="toast-glyph" aria-hidden="true">!</span>
<p class="toast-text">Battery at 10%.</p>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
</div>
<div class="toast toast-success" role="status">
<span class="toast-glyph" aria-hidden="true">✓</span>
<p class="toast-text">Screenshot copied.</p>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
</div>
<div class="toast toast-info" role="status">
<span class="toast-glyph" aria-hidden="true">i</span>
<p class="toast-text">Workspace 3 moved to the left output.</p>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
</div>
<div class="toast toast-neutral" role="status">
<span class="toast-glyph" aria-hidden="true">·</span>
<p class="toast-text">Layout locked.</p>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
<span class="toast-count" aria-hidden="true">+2</span>
</div>
</div></j3w1-toast>with-action
Window closed.
<j3w1-toast id="example-toast-with-action"><div class="toast-stack" role="region" aria-label="Notifications">
<div class="toast" role="status">
<span class="toast-glyph" aria-hidden="true">i</span>
<p class="toast-text">Window closed.</p>
<button class="toast-action" type="button">Undo</button>
<button class="toast-close" type="button" aria-label="Dismiss">✕</button>
<span class="toast-count" aria-hidden="true">+2</span>
</div>
</div></j3w1-toast>Install and register
Use the exact version. If npm publication is pending, install the release tarball from the installation guide.
npm install --save-exact @j3w1/ui@4.0.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/toast.css';
import '@j3w1/ui/register/toast';Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.
Copy the complete implementation
npx --package=@j3w1/ui@4.0.0 j3w1-ui copy toast --out ./vendor/j3w1/toastThe CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.
Public API
attributes
| Name | Type / signature | Meaning |
|---|---|---|
disabled | CustomEvent | Disable the native controls owned by this instance. |
loading | CustomEvent | Mark the primary control busy and prevent duplicate activation. |
properties
| Name | Type / signature | Meaning |
|---|---|---|
disabled | boolean | Delegates disabled state to native children. |
name | string | Native control name; application form keys remain explicit. |
methods
| Name | Type / signature | Meaning |
|---|---|---|
refresh | (): void | Reconnect behavior after replacing native child structure. |
focus | (options?: FocusOptions): void | Focus the first usable native control. |
dismiss | (id?: string): void | Dismiss a message; focused actions move to the next available control. |
events
| Name | Type / signature | Meaning |
|---|---|---|
j3w1-dismiss | CustomEvent | Cancelable message dismissal. |
j3w1-retry | CustomEvent | Request recovery; the host owns the result. |
j3w1-action | CustomEvent | An explicit message action. |
Dependencies and verification
Registered components: none. Style dependencies: none.
Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.
Full implementation manifest, API and token dependency closure
Canonical specification
Toast toast
A brief notification in a fixed corner stack; canvas surface behind a 1px overlay border, status tints for the four polite statuses and the danger fill for critical ones.
Report an issue with this component
Tokens
Focus a role to inspect its values; follow its link for persistent usage and source details.
| Part | Role | Value | Use |
|---|---|---|---|
root.bg | color.surface.canvasapproveduse | #000000 | Page and terminal background. |
root.border | color.border.overlayapproveduse | #c81a1a | D-041 owner correction: red control and floating-frame borders, distinct from rose text. |
root.text | color.text.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
glyph.text | color.status.info.textapproveduse | #82b4ff | D-041 status.info.text: color.primitive.modern.blue. |
warning.bg | color.status.warning.tintapproveduse | #1f1a0c | Warning background tint. |
warning.border | color.status.warning.borderapproveduse | #e5c07b | D-041 status.warning.border: color.primitive.modern.amber. |
warning.text | color.status.warning.textapproveduse | #e5c07b | D-041 status.warning.text: color.primitive.modern.amber. |
success.bg | color.status.success.tintapproveduse | #0f1a0e | Success background tint. |
success.border | color.status.success.borderapproveduse | #82d9a0 | D-041 status.success.border: color.primitive.modern.green. |
success.text | color.status.success.textapproveduse | #82d9a0 | D-041 status.success.text: color.primitive.modern.green. |
info.bg | color.status.info.tintapproveduse | #0f141c | Info background tint. |
info.border | color.status.info.borderapproveduse | #82b4ff | D-041 status.info.border: color.primitive.modern.blue. |
info.text | color.status.info.textapproveduse | #82b4ff | D-041 status.info.text: color.primitive.modern.blue. |
neutral.bg | color.status.neutral.tintapproveduse | #140b0b | D-041 status.neutral.tint: color.primitive.modern.raised. |
neutral.border | color.status.neutral.borderapproveduse | #986f72 | D-041 status.neutral.border: color.primitive.modern.control. |
neutral.text | color.status.neutral.textapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
danger.bg | color.status.danger.fillobserveduse | #dc282e | Danger fill. |
danger.text | color.status.danger.on-fillobserveduse | #f9faf9 | Text on the danger fill (4.58:1). |
danger.button-bg-hover | color.action.destructive.pressed-bgobserveduse | #ae1914 | Destructive button pressed fill. |
action.text | color.text.linkapproveduse | #f73f35 | Strong red link text, distinct from rose body text and headings; retain the underline. |
action.bg-hover | color.interaction.hover.bgapproveduse | #1c1010 | D-041 interaction.hover.bg: color.primitive.modern.hover. |
action.text-hover | color.text.link-hoverobserveduse | #f4eeee | Link text on hover, over interaction.hover.bg-strong. |
close.text | color.action.tertiary.textapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
close.bg-hover | color.action.tertiary.hover-bgobserveduse | #1c0a09 | Ghost and icon button hover. |
close.ring | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
count.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
stack.z | z.toastobserveduse | 40 |
State matrix
Every declared state and combination, statically rendered; the default cell is live. Sizes: compact, comfortable (switch with the density control above).
| State | Plain | Five statuses stacked | With action |
|---|---|---|---|
default | Settings saved. | Connection lost. Changes are queued. Battery at 10%. Screenshot copied. Workspace 3 moved to the left output. Layout locked. | Window closed. |
hover | |||
focus-visible | |||
stacked | |||
reduced-motion |
Purpose
A short notice that belongs to no one element on the page: “Saved”, “Copied”, “Connection lost”. It leaves on its own after a pause or when dismissed. A decision is a dialog; a notice tied to a form is an alert.
Anatomy
Parts as listed in the anatomy. The danger toast is the historical critical
notification: color.status.danger.fill with color.status.danger.on-fill
for the text, the glyph and both buttons.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | canvas surface, 1px overlay border, glyph in the status text colour | the glyph; the worded text |
| hover | action → color.interaction.hover.bg with color.text.link-hover; Dismiss → color.action.tertiary.hover-bg; the timeout pauses | cursor: pointer; the action’s underline thickens |
| focus-visible | 1px dashed color.interaction.focus.ring at −2px on the focused button, color.status.danger.on-fill on the danger fill; the timeout pauses | the ring |
| stacked | one column, 4px gap, newest at the end; the last visible toast shows “+n” in color.text.muted | the count text; at most three visible |
| reduced-motion | no transition; present or absent | prefers-reduced-motion; nothing moves |
No disabled, selected or busy state.
Keyboard
As in the key table. F6 is the web reference’s shortcut; the timeout pauses while a toast has focus or the pointer.
Accessibility
The text states the outcome in words; the glyph is aria-hidden. Every toast
has Dismiss; the timeout, at least 8 seconds, is extended for toasts with an
action, and an action is never the only way to reach what it does. Text
meets 4.5:1 on the canvas, on its tint and on the danger fill; borders, and
the danger fill against the canvas, 3:1.
Portability
Hosts with a notification daemon send the text and urgency instead of drawing a toast. Toolkits with a native toast overlay use it and record that the danger fill is not available.
Non-examples
A toast that slides in. A rounded, shadowed pill. No Dismiss and gone in two seconds. Taking focus on appearance. More than three stacked with no count. A form error as a toast. Colour-only status without the glyph and worded text.
Contrast report
26 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.
| Pair | State | Kind | Foreground | Background | Ratio | Min | Result |
|---|---|---|---|---|---|---|---|
| toast default text | default | text | color.text.default #e99499 | color.surface.canvas #000000 | 9.16 | 4.5 | pass |
| toast default border | default | ui | color.border.overlay #c81a1a | color.surface.canvas #000000 | 3.62 | 3 | pass |
| toast hover text | hover | text | color.text.link-hover #f4eeee | color.interaction.hover.bg #1c1010 | 16.19 | 4.5 | pass |
| toast focus-visible text | focus-visible | text | color.action.tertiary.text #e99499 | color.surface.canvas #000000 | 9.16 | 4.5 | pass |
| toast focus-visible outline | focus-visible | ui | color.interaction.focus.ring #e53935 | color.surface.canvas #000000 | 4.97 | 3 | pass |
| toast stacked text | stacked | text | color.text.muted #d4868b | color.surface.canvas #000000 | 7.58 | 4.5 | pass |
| toast stacked border | stacked | ui | color.border.overlay #c81a1a | color.surface.canvas #000000 | 3.62 | 3 | pass |
| toast reduced-motion text | reduced-motion | text | color.text.default #e99499 | color.surface.canvas #000000 | 9.16 | 4.5 | pass |
| toast reduced-motion border | reduced-motion | ui | color.border.overlay #c81a1a | color.surface.canvas #000000 | 3.62 | 3 | pass |
| glyph on the plain toast | — | text | color.status.info.text #82b4ff | color.surface.canvas #000000 | 9.92 | 4.5 | pass |
| action text on the plain toast | — | text | color.text.link #f73f35 | color.surface.canvas #000000 | 5.72 | 4.5 | pass |
| warning glyph on its tint | — | text | color.status.warning.text #e5c07b | color.status.warning.tint #1f1a0c | 10.04 | 4.5 | pass |
| warning border on its tint | — | ui | color.status.warning.border #e5c07b | color.status.warning.tint #1f1a0c | 10.04 | 3 | pass |
| text on the warning tint | — | text | color.text.default #e99499 | color.status.warning.tint #1f1a0c | 7.56 | 4.5 | pass |
| success glyph on its tint | — | text | color.status.success.text #82d9a0 | color.status.success.tint #0f1a0e | 10.54 | 4.5 | pass |
| success border on its tint | — | ui | color.status.success.border #82d9a0 | color.status.success.tint #0f1a0e | 10.54 | 3 | pass |
| text on the success tint | — | text | color.text.default #e99499 | color.status.success.tint #0f1a0e | 7.80 | 4.5 | pass |
| info glyph on its tint | — | text | color.status.info.text #82b4ff | color.status.info.tint #0f141c | 8.73 | 4.5 | pass |
| info border on its tint | — | ui | color.status.info.border #82b4ff | color.status.info.tint #0f141c | 8.73 | 3 | pass |
| text on the info tint | — | text | color.text.default #e99499 | color.status.info.tint #0f141c | 8.06 | 4.5 | pass |
| neutral glyph on its tint | — | text | color.status.neutral.text #d4868b | color.status.neutral.tint #140b0b | 7.01 | 4.5 | pass |
| neutral border on its tint | — | ui | color.status.neutral.border #986f72 | color.status.neutral.tint #140b0b | 4.48 | 3 | pass |
| text on the neutral tint | — | text | color.text.default #e99499 | color.status.neutral.tint #140b0b | 8.46 | 4.5 | pass |
| text, glyph and buttons on the danger fill | — | text | color.status.danger.on-fill #f9faf9 | color.status.danger.fill #dc282e | 4.58 | 4.5 | pass |
| the danger fill is its own boundary against the canvas | — | ui | color.status.danger.fill #dc282e | color.surface.canvas #000000 | 4.39 | 3 | pass |
| danger border on the danger fill (decorative) | — | ui | color.status.danger.border #e53935 | color.status.danger.fill #dc282e | 1.13 | 1 | pass |
Keys
| Key | Action |
|---|---|
| F6 / a host shortcut | Moves focus into the notification region; toasts never steal focus when they appear. |
| Tab / Shift+Tab | Within the region, reaches the action and then Dismiss of each toast in order. |
| Enter / Space | Activates the action or dismisses. |
| Escape | Dismisses the focused toast and returns focus to the region, then to the page. |
For agents
Component JSON ·Implementation brief ·Build a task kit ·
Related: alert dialog progress badge
Stress fixtures: FX-LONG FX-320 FX-ZOOM-200 FX-I18N FX-RTL FX-RM FX-HC FX-OVERFLOW FX-STATE-MATRIX