Never time out a snackbar that carries an action
M3's accessibility page forbids it outright: an actioned snackbar has to wait for the person to read it and reach its action. An entry with an action and no timeout of its own is now untimed, the close button it already draws being the way out; a timeout written out still wins. Plan step 11, actions.md ACT-03. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
04b655fa9b
commit
6e24ff2cf8
@@ -326,7 +326,7 @@ The snackbar host. Once per layout, near the end of `<body>`: `<x-toast />` (`po
|
|||||||
materialToast('Share deleted', { type: 'success', description: null, timeout: 4000, action: { label: 'Undo', handler: () => $wire.restore() } })
|
materialToast('Share deleted', { type: 'success', description: null, timeout: 4000, action: { label: 'Undo', handler: () => $wire.restore() } })
|
||||||
```
|
```
|
||||||
|
|
||||||
`type` (`success`, `error`, `warning`, `info`) adds the state icon; `timeout: 0` keeps it until dismissed; a toast with an action or no timeout gets a close button. Hover or focus pauses the timer.
|
`type` (`success`, `error`, `warning`, `info`) picks the announcement role; `timeout: 0` keeps it until dismissed; a toast with an action or no timeout gets a close button. Hover or focus pauses the timer. A toast with an `action` never auto-dismisses (M3's rule) unless you write a `timeout` out.
|
||||||
|
|
||||||
- `action`: `label`, plus `handler` (a function) and/or `event` (a name). Pressing it closes the snackbar, calls `handler`, then dispatches `new CustomEvent(event)` on `window`; give both and both run. Use `event` where a function cannot travel, such as a toast built from JSON.
|
- `action`: `label`, plus `handler` (a function) and/or `event` (a name). Pressing it closes the snackbar, calls `handler`, then dispatches `new CustomEvent(event)` on `window`; give both and both run. Use `event` where a function cannot travel, such as a toast built from JSON.
|
||||||
- `sticky: true` keeps a toast until it is dismissed or its action is pressed (any `timeout` is ignored), without holding the queue up: a toast dispatched meanwhile shows in its place, and the sticky one comes back once the queue is empty. One sticky toast is kept at a time; a newer one replaces it. Use it for a question that must be answered, not for news:
|
- `sticky: true` keeps a toast until it is dismissed or its action is pressed (any `timeout` is ignored), without holding the queue up: a toast dispatched meanwhile shows in its place, and the sticky one comes back once the queue is empty. One sticky toast is kept at a time; a newer one replaces it. Use it for a question that must be answered, not for news:
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* One snackbar at a time, as M3 shows them. Each waits its turn, stays for its timeout (paused
|
* One snackbar at a time, as M3 shows them. Each waits its turn, stays for its timeout (paused
|
||||||
* while hovered or focused, so it is never pulled away from someone reading or reaching for its
|
* while hovered or focused, so it is never pulled away from someone reading or reaching for its
|
||||||
* action) and is replaced by the next.
|
* action) and is replaced by the next. A snackbar carrying an action has no timeout at all —
|
||||||
|
* M3's accessibility page forbids one — unless the caller writes a timeout out.
|
||||||
*
|
*
|
||||||
* A `sticky` toast ("A new version is ready" with a Reload action) stays until it is answered, but
|
* A `sticky` toast ("A new version is ready" with a Reload action) stays until it is answered, but
|
||||||
* never holds the queue up: it is kept aside rather than queued, a toast that arrives while it shows
|
* never holds the queue up: it is kept aside rather than queued, a toast that arrives while it shows
|
||||||
@@ -52,12 +53,17 @@ document.addEventListener('alpine:init', () => {
|
|||||||
const toast = Array.isArray(detail) ? detail[0] : detail
|
const toast = Array.isArray(detail) ? detail[0] : detail
|
||||||
const sticky = toast.sticky === true
|
const sticky = toast.sticky === true
|
||||||
|
|
||||||
|
// M3 forbids a snackbar with an action from auto-dismissing: it has to wait for the
|
||||||
|
// person to read it and reach it. A timeout written out still wins, for a caller who
|
||||||
|
// means it; a missing one no longer falls back to the default.
|
||||||
|
const untimed = sticky || toast.timeout === 0 || toast.timeout === null || (toast.action != null && toast.timeout === undefined)
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
id: ++sequence,
|
id: ++sequence,
|
||||||
type: toast.type ?? null,
|
type: toast.type ?? null,
|
||||||
title: toast.title ?? '',
|
title: toast.title ?? '',
|
||||||
description: toast.description ?? null,
|
description: toast.description ?? null,
|
||||||
timeout: sticky || toast.timeout === 0 || toast.timeout === null ? 0 : (toast.timeout ?? DEFAULT_TIMEOUT_MS),
|
timeout: untimed ? 0 : (toast.timeout ?? DEFAULT_TIMEOUT_MS),
|
||||||
action: toast.action ?? null,
|
action: toast.action ?? null,
|
||||||
sticky,
|
sticky,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
dispatches from a Livewire component — and for `window.materialToast(title, options)` from
|
dispatches from a Livewire component — and for `window.materialToast(title, options)` from
|
||||||
JavaScript (`{ type, description, timeout, sticky, action: { label, handler, event } }`).
|
JavaScript (`{ type, description, timeout, sticky, action: { label, handler, event } }`).
|
||||||
Toasts queue and show in turn, each for its `timeout` (4s by default; M3 asks for 4–10s),
|
Toasts queue and show in turn, each for its `timeout` (4s by default; M3 asks for 4–10s),
|
||||||
paused while the pointer or focus is on it. A toast with an action or no timeout gets a close
|
paused while the pointer or focus is on it. A toast with an `action` has no timeout at all,
|
||||||
button. Pressing the action closes the snackbar, calls `handler` and dispatches `event` (a
|
as M3 requires — it waits to be read and acted on — unless the caller writes a `timeout` out.
|
||||||
name) on `window`; both may be given.
|
A toast with an action or no timeout gets a close button. Pressing the action closes the
|
||||||
|
snackbar, calls `handler` and dispatches `event` (a name) on `window`; both may be given.
|
||||||
|
|
||||||
`sticky: true` keeps a toast until it is dismissed or its action pressed, without holding up
|
`sticky: true` keeps a toast until it is dismissed or its action pressed, without holding up
|
||||||
the queue: a toast that arrives meanwhile shows in its place, and the sticky one comes back
|
the queue: a toast that arrives meanwhile shows in its place, and the sticky one comes back
|
||||||
|
|||||||
Reference in New Issue
Block a user