Feedback and dialogs Required
Use toasts only to confirm finished work
Use a toast only to confirm that something worked, such as "Invoice sent". Announce it through a live region, keep it for at least 6 seconds, and pause it while hovered or focused.
How to do it
Write toasts into one region with role="status" that is in the page from the start, as status messages requires. Never move focus to a toast. Give it a close button. If a toast holds an action, such as Undo, keep it until closed or offer the same action elsewhere, because time limits apply. Show at most 3 at once.
Example
const MIN_VISIBLE_MS = 6000;
const region = document.querySelector<HTMLElement>('#toasts')!;
export function toast(message: string) {
const item = Object.assign(document.createElement('p'), { textContent: message, className: 'toast' });
region.append(item);
let remaining = MIN_VISIBLE_MS;
let startedAt = Date.now();
let timer: ReturnType<typeof setTimeout> | undefined = setTimeout(() => item.remove(), remaining);
const pause = () => {
if (!timer) return;
clearTimeout(timer);
timer = undefined;
remaining -= Date.now() - startedAt;
};
const resume = () => {
if (timer || item.matches(':hover, :focus-within')) return;
startedAt = Date.now();
timer = setTimeout(() => item.remove(), remaining);
};
for (const event of ['pointerenter', 'focusin']) item.addEventListener(event, pause);
for (const event of ['pointerleave', 'focusout']) item.addEventListener(event, () => setTimeout(resume));
}
import json
@app.post("/invoices/<invoice_id>/send")
def send_invoice(invoice_id):
invoices.send(current_user().account_id, invoice_id)
response = make_response(render_template("invoices/_status.html", status="sent"))
response.headers["HX-Trigger"] = json.dumps({"toast": {"message": "Invoice sent"}})
return response
How to check
A browser test sends an invoice. The status region, present before the click, holds the message. Focus stays on the button, and the toast is still there after 5 seconds.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/feedback-and-dialogs/toasts-for-status.