Toast
Feedback on something that just happened: one line on the inverse surface at the bottom of the window, with at most one action, usually Undo. It rises with the expressive spring, one of the two moments that bounce.
- Behavior from Base UI
- 2.4 KB gzipped · script and styles
@orbex/sonar-components/toast
Examples
Code
import { Button } from '@orbex/sonar-components/button'
import { ToastProvider, useToast } from '@orbex/sonar-components/toast'
import { useState } from 'react'
/* Saving says it worked; removing offers to take it back. Neither asks first. */
function Actions() {
const toast = useToast()
const [shown, setShown] = useState(true)
return (
<>
<Button variant="tonal" onClick={() => toast({ message: 'Layout saved.' })}>
Save layout
</Button>
<Button
variant="outlined"
disabled={!shown}
onClick={() => {
setShown(false)
toast({ message: 'Inventory removed from your overview.', action: { label: 'Undo', onClick: () => setShown(true) } })
}}
>
{shown ? 'Remove Inventory' : 'Inventory removed'}
</Button>
</>
)
}
export default function Undo() {
return (
<ToastProvider>
<Actions />
</ToastProvider>
)
}
Sizes, variants and states
Usage
- Say what happened in a few words, in the past tense: “Layout saved.”
- Prefer an Undo in a toast to a confirmation before acting. Confirm only what cannot be undone.
- One toast at a time: a new one replaces the last. A toast with an action stays ten seconds instead of five.
- Wrap the app once in a
ToastProvider, and show toasts from anywhere withuseToast. - Toasts centre on the window, 24 px above its foot. In an app with a sidebar,
insetcentres them on the main area and lifts them above a footer or a bottom app bar, as the product does:inset={{ left: '224px', bottom: '66px' }}. closeButton={false}leaves out the close button (on the provider, or on one toast); the toast still goes after its time or with a swipe.
Do and don’t
Accessibility
Keyboard
| Key | What it does |
|---|---|
| F6 | Moves focus to the notifications region, from anywhere on the page. |
| Tab | Moves to the toast’s action and its close button. |
| Enter or Space | Activates the action, or dismisses the toast. |
Roles and attributes
| Element or attribute | What it gives |
|---|---|
role="region", aria-live="polite" |
The viewport, named “Notifications”: a new toast is announced without interrupting. |
role="dialog" |
Each toast, not modal, named by its message. |
| Timers | Pause while the pointer or focus is in the region, so a message never disappears while it is being read. A toast with an action stays for 10 seconds. |
Notes
- The message is announced politely by assistive technology, without moving focus.
- The timer pauses while the toast is hovered or focused, so there is time to reach the action.
- It can be dismissed with its close button or swiped away, down or to the side.
Use it
Each component is its own entry point with its own stylesheet, so an app loads only what it uses. The tokens and the cascade layers are set once for the app: see Installation.
import { ToastProvider } from '@orbex/sonar-components/toast'
import '@orbex/sonar-components/toast.css'
API
| Prop | Type | Default |
|---|---|---|
children
Required
The part of the app that can show toasts, usually all of it. useToast works anywhere inside. |
ReactNode
|
— |
timeout
Time a toast stays, in milliseconds. One with an action stays twice as long, so there is time to use it. |
number
|
5000 |
closeLabel
Name of the close button. |
string
|
'Dismiss' |
label
Name of the region the toasts appear in. Give each provider its own when a page has more than one. |
string
|
'Notifications' |
inset
Where the toasts sit, as CSS lengths: |
{ left?: string; right?: string; bottom?: string }
|
{ left: 0, right: 0, bottom: 24px } |
closeButton
Whether toasts carry a close button. One with an action can still be swiped away or wait for its timeout. |
boolean
|
true |