Toast
A transient message in a live region, paused while it has focus or the pointer.
Code
The three render the same class names, the same ARIA and the same data attributes. That is checked when this site builds: a class in any of these samples that neither the markup contract nor the shipped stylesheet defines fails the build.
<div class="wsu-toasts" role="region" aria-label="Notifications">
<div class="wsu-toast wsu-alert--success" role="status">
<svg class="wsu-icon" aria-hidden="true"><use href="/assets/wayne-ui/icons.svg#wsu-circle-check"/></svg>
<div class="wsu-alert__body">
<span class="wsu-sr-only">Success:</span>
<p class="wsu-alert__title">Course added</p>
CSC 2110 is on your schedule.
</div>
<button class="wsu-btn wsu-btn--icon wsu-btn--ghost wsu-btn--sm" type="button">
<span class="wsu-sr-only">Dismiss notification</span>
<svg class="wsu-icon" aria-hidden="true"><use href="/assets/wayne-ui/icons.svg#wsu-x"/></svg>
</button>
</div>
</div>{{-- <x-wsu::toast> renders the same markup as Vue's <Toasts>, but has no
timer, pause or dismiss script wired to it. A Blade page that has just
done something is usually better served by <x-wsu::alert> instead,
which needs no script and stays on the page across the next
navigation. --}}
<x-wsu::toasts label="Notifications">
<x-wsu::toast variant="success" title="Course added">
CSC 2110 is on your schedule.
</x-wsu::toast>
</x-wsu::toasts><!-- Once, in the shell -->
<Toasts label="Notifications" />
<script setup>
import { pushToast } from '@waynestate/wayne-ui-vue'
pushToast({ variant: 'success', title: 'Course added', message: 'CSC 2110 is on your schedule.' })
</script>Why it works this way
- The container is a labeled region that pauses its timers on mouseenter and focusin. A message that disappears while someone is reading it or tabbing to its dismiss button fails 2.2.1. That queue, timer and pause behavior lives in packages/vue/src/composables/toasts.js, on the Vue path only.
- A toast is the wrong place for anything the user must act on. If it matters, it belongs on the page.
- <x-wsu::toast> and <x-wsu::toasts> exist on the Blade path and render the same markup, but carry no script of their own: nothing sets a timer, pauses on hover or focus, or wires the dismiss button, since the shared runtime a Blade page loads has no toast queue the way it has a drawer or a countdown. A Blade page that has just done something is usually better served by <x-wsu::alert>, which needs no script and stays on the page.
Accessibility
- role="status" normally, role="alert" for the danger variant (4.1.3).
- Timers pause on hover and focus, on the Vue path that runs them (2.2.1).
- Dismiss is a real button with a name (4.1.2); on the Blade path nothing is wired to press it yet.
Success criteria in brackets refer to WCAG 2.2. Every one of them is checked by axe-core in both themes at three viewport widths before this page can be published. See Accessibility for what the gates are.
Props
Blade
| Attribute | Default | What it does |
|---|---|---|
variant | 'info' | info, success, warning or danger. danger sets role="alert"; the rest set role="status". |
title | null | Rendered above the body. |
dismissLabel | 'Dismiss notification' | Accessible name for the close button, which has no script wired to it on this path. |
Vue
| Prop | Type and default | What it does |
|---|---|---|
Toasts label | String, 'Notifications' | Names the live region. |
variant | String, 'info' | info, success, warning or danger. |
title / message | String, '' | Title is optional, message is not. |
dismissLabel | String, 'Dismiss notification' | Accessible name for the close button. |