Toaster
Where toasts appear: short messages that come and go on their own.
SourcePackage @weft-js/warpPlayground
Preview
tsx
import { Button, Toaster, toast } from '@weft-js/warp'export function Basic() { return ( <> <Button onClick={() => toast.show({ title: 'Saved', description: 'Your changes are live.' })}>Save changes</Button> <Toaster /> </> )}Installation
npm install @weft-js/warpUsage
tsx
import { Toaster } from '@weft-js/warp'<> <Button onClick={() => toast.show({ title: 'Saved', description: 'Your changes are live.' })}>Save changes</Button> <Toaster /></>Tones
Each tone brings its own icon.
tsx
import { Button, Toaster, toast } from '@weft-js/warp'export function Tones() { return ( <> {TONES.map(tone => <Button key={tone} emphasis="outline" tone={tone} onClick={() => toast.show({ title: 'Deploy finished', tone })}>{tone}</Button>)} <Toaster /> </> )}const TONES = ['neutral', 'positive', 'info', 'caution', 'critical'] as constPosition
Use position on Toaster to pick the corner.
tsx
import { state } from '@weft-js/core'import { Button, Grid, Toaster, toast } from '@weft-js/warp'export function Position() { const position = state<(typeof CORNERS)[number]>('bottom-right') const show = (corner: (typeof CORNERS)[number]) => { position.value = corner toast.show({ title: 'Deploy finished', description: `Shown ${corner.replace('-', ' ')}.` }) } return ( <> <Grid cols={3} gap="tight"> {CORNERS.map(corner => <Button key={corner} emphasis="outline" tone="neutral" onClick={() => show(corner)}>{corner}</Button>)} </Grid> <Toaster position={position.value} /> </> )}const CORNERS = ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'] as constWith an action
An action gives people ten seconds to take it.
tsx
import { state } from '@weft-js/core'import { Button, Toaster, toast } from '@weft-js/warp'export function Undo() { const archived = state(false) const archive = () => { archived.value = true toast.show({ title: 'reports archived', action: { label: 'Undo', onClick: () => (archived.value = false) } }) } return ( <> <Button emphasis="outline" tone="neutral" disabled={archived.value} onClick={archive}>{archived.value ? 'Archived' : 'Archive reports'}</Button> <Toaster /> </> )}Following a promise
toast.promise shows one toast from pending to done, in place.
tsx
import { Button, Toaster, toast } from '@weft-js/warp'export const Promise = () => { const deploy = () => toast.promise(wait(2200), { pending: { title: 'Deploying storefront', description: 'This takes about two seconds.' }, done: { title: 'storefront is live', description: 'Serving 9f3ac21 in eu-west.' }, error: 'The deploy failed', }) return ( <> <Button icon="rocket" onClick={deploy}>Deploy</Button> <Toaster /> </> )}const wait = (ms: number) => new Promise(done => { setTimeout(done, ms) })Several at once
Three stack up, and fan out on hover. Hovering pauses every timer.
tsx
import { Button, Toaster, toast } from '@weft-js/warp'export const Several = () => { const many = () => ['eu-west', 'us-east', 'ap-south', 'eu-north'].forEach((region, i) => setTimeout(() => toast.show({ title: `${region} is up to date`, tone: 'positive' }), i * 250)) return ( <> <Button emphasis="outline" tone="neutral" onClick={many}>Roll out to four regions</Button> <Toaster /> </> )}Closing from code
duration: 0 keeps it up until toast.dismiss with the id toast.show returned.
tsx
import { state } from '@weft-js/core'import { Button, Toaster, toast } from '@weft-js/warp'export function Dismissed() { const id = state('') const start = () => (id.value = toast.show({ title: 'Watching for failures', description: 'This stays until you stop it.', duration: 0 })) const stop = () => { toast.dismiss(id.value); id.value = '' } return ( <> <Button emphasis="outline" tone="neutral" disabled={!!id.value} onClick={start}>Start</Button> <Button emphasis="outline" tone="neutral" disabled={!id.value} onClick={stop}>Stop</Button> <Toaster /> </> )}On arrival
Fire one as a page mounts, to finish what the last page started.
tsx
import { onMount } from '@weft-js/core'import { Text, Toaster, toast } from '@weft-js/warp'export function AfterRedirect() { onMount(() => toast.show({ title: 'Welcome back, Mara', description: 'You have two failed deploys to look at.', tone: 'info' })) return ( <> <Text subtle>This one fires as the page arrives. Press Replay.</Text> <Toaster /> </> )}When to use
Playground
Tone
import { Toaster } from '@weft-js/warp'toast.show({ title, description, tone, action })<Toaster />Accessibility
- F8
- Moves focus to the newest toast
- Esc
- Leaves the toasts
- Toasts are read out through a live region that is on the page from the start.
- Hovering or focusing the stack pauses every timer.
- A critical toast with an action stays until it is dismissed.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
position | "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center… | — | The corner or edge toasts stack in, such as top-center. Bottom right otherwise. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="toast"] [data-part="region"]
regionrooticontitledescriptionactionsprogress