a11y(toaster): announce toasts to screen readers (U-F)

The toast is the app's main feedback channel but had no live region, so a screen
reader never spoke it. Each toast now carries role + aria-live by severity:
error/fatal interrupt (alert/assertive), everything else waits its turn
(status/polite).
This commit is contained in:
2026-07-21 23:13:53 +02:00
parent 58b9691467
commit b769439229
+5
View File
@@ -19,9 +19,14 @@ export default function Toaster() {
<div className="absolute bottom-4 left-4 z-overlay flex flex-col gap-2 w-80 max-w-[calc(100vw-2rem)]">
{toasts.map((toast) => {
const { icon: Icon, color, bar } = LEVEL_STYLE[toast.level];
const urgent = toast.level === "error" || toast.level === "fatal";
return (
<div
key={toast.id}
// Announce toasts to screen readers — the toast is the app's main feedback channel.
// Errors interrupt (assertive/alert); everything else waits its turn (polite/status).
role={urgent ? "alert" : "status"}
aria-live={urgent ? "assertive" : "polite"}
className="toast-card glass relative overflow-hidden rounded-xl px-3 py-3 flex items-start gap-3 animate-[popIn_0.16s_ease]"
>
<Icon className={`w-5 h-5 shrink-0 mt-0.5 ${color}`} />