Skip to content

Notification ​

Something people should know about: a toast when it happens, and a list of past ones behind the bell in the Header.

Open in Storybook to try every prop.

When to use ​

Use a notification forUse instead
Something that happened, especially in the background (an upload finished, a password is expiring)The result of what someone just did on the page (show it there: a Button's status, a field's error)
Something people may want to come back to (it stays in the pane)A problem that blocks the page (an alert on the page)
A question that needs an answer before continuing (a dialog)

Anatomy ​

PartRequiredNotes
iconYesFrom the type, 16px, in its colour.
titleYesShort, bold.
descriptionNoA string, or a render function for bold text and links.
actionNoOne small basic Button, e.g. "Change password". Closes the toast or pane.
timePane only"4 minutes ago" (RelativeTime: the exact date and time on hover or focus), kept up to date.
unread dotPane only8px primary dot, and a light blue background on the row.
×YesToast: closes it (it stays in the pane). Pane: removes it.

Types ​

TypeIconColourToast staysAnnounced
infoInfo (i)blue #0354836 secondsWhen the screen reader is idle
successCircle checkgreen #007A166 secondsWhen the screen reader is idle
warningTriangleyellow #F1C70B, black outline6 secondsStraight away
errorCircle ×red #D2042DUntil closedStraight away

With an action, every type stays until closed, so people have time to use it, except compact ones (e.g. Undo), which stay 10 seconds. Errors always stay.

Compact ​

One line, for quick confirmations: icon, title, the action on the right, then ×.

ts
notify({ type: 'success', title: 'Student disabled', compact: true, action: { label: 'Undo', onSelect: undo } })
RuleValue
WidthThe same as other toasts (384px), only shorter
Padding20px left (icons line up with full toasts), 6px top and bottom, 6px right beside the × (16px without one)
ContentTitle only: the description isn't shown in the toast. In the pane it's a normal row.
Gaps12px icon to title (as in the full toast), 12px title to action

Properties ​

notify(input, options) ​

FieldTypeDefaultDescription
titlestring—Required.
typeinfo | success | warning | errorinfo
descriptionstring | () => VNode—No HTML strings, so nothing in a notification can run as code.
action—
compactbooleanfalseOne-line toast (see Compact).
idstringgeneratedNotifying with the same id replaces it, e.g. "Uploading…" then "Uploaded".
createdAtDatenow
options.toastbooleantrueFalse: only add it to the pane.
options.durationnumber (ms)see Types

Components ​

ComponentPropertyTypeDefault
Toasternotificationsthe listthe shared useNotifications()
Toasterpositionbottom-right | top-right | bottom-centerbottom-right
ToastermaxHeightnumber (px)320: older toasts past this collapse into a stack
Toasterlimitnumber10: the most kept at once
Toaster@moreevent"+3 more" was pressed (it also opens the pane)
NotificationPanenotificationsthe listthe shared useNotifications()
NotificationPanelabelstring"Notifications"
NotificationPaneemptyTextstring"You're all caught up."
Notificationappearancecard | rowcard
Notificationcompactbooleanfalse
Notificationdismissible, dismissLabelboolean, stringtrue, "Dismiss: {title}"

Sizes ​

PartValue
Toast384px wide (full width minus 16px each side on phones), 16px padding (20px on the left), shadow, 4px corners, 8px between toasts, 16px from the edges
Pane384px wide, as tall as fits under the Header then scrolls; heading row 44px; rows clipped to its 4px corners
Pane row16px sides, 12px top and bottom, a line between
Icon to text12px
Title / description14px / 20px; title bold black, description black 65% (bold parts black)
Time12px, black 65%
ActionSmall basic Button, 8px above
Unread count16px red circle, white bold 12px, "99+" above 99, white ring

Behaviour ​

ActionResult
notify()Added to the top of the pane; a toast slides up from below the screen and the others move up with it (300ms, ease-out; top-right drops in 16px with a fade)
More than maxHeight of toastsThe older ones shrink into the "+5 more" pill (to 50%, fading out) as newer ones arrive, and grow back out of it when spread out or when there's room again
Any toasts not in view, collapsedA "+5 more" pill (96px wide, 28px tall, 16px corners, 12px bold, white) sits 8px above the stack, counting every toast not in view: in the pill or waiting
Spreading out or collapsingThe pill and the "+3 more" row are one button that morphs: its position, width (96px ↔ full), height (28 ↔ 36px), corners (16 ↔ 4px) and text size (12 ↔ 14px) animate together (300ms, ease-out). Spread out, it counts only those waiting, and fades away if none are
Tap or click the pillThe toasts spread out (focus moves to the newest, without a focus ring), for touch screens with no hover
Hover the toasts, or focus in them (Tab, F8)They spread out, 8px apart; leaving collapses them again
A toast closesIt fades where it is while the others slide to close the gap (300ms, ease-out); one from the pill grows out to fill the space
A toast has to wait (newer ones took its place)It shrinks into "+N more" (the row when spread out, the pill when collapsed) before it goes
A waiting toast's turn comesIt grows out of "+N more", rather than sliding in from the edge like a new one
More than fit on the screen spread out (its height, less 80px for the Header and edges)The oldest wait (not shown, timers not started); the ones in view are always the newest, in the order they came in. When spread out, a "+3 more" row (36px, bold, white) after the last toast counts just those waiting
"+3 more" pressedThe pane opens with everything in it; focus moves to its heading
Pane open (however it was opened)Toasts showing fade away and waiting ones are dropped (they're all in the pane); new notifications go straight to the pane, with no toast
Hover a toast, or leave the windowIts timer pauses
Swipe a toast rightIt closes
F8Focus jumps to the toasts
Open the paneUnread ones show a dot
Close the paneAll marked read; the count goes
× in the paneRemoved; focus moves to the next one's × (or the heading)
Clear allAll removed; focus moves to the heading

Accessibility ​

PartAnnounced as
BellButton "Notifications, 3 unread"
ToastRead out when it appears ("Notification, Warning: Password Expiry, Your password expires in 7 days"), politely or straight away by type
Toasts arearegion "Notifications (F8)"
Paneregion named by its heading, a list of notifications
Each notificationgroup named by its title; the type is read before the title
Unread"Unread," before the time
×"Dismiss: {title}" in the pane, "Close: {title}" on a toast

Colour is never the only signal: each type has its own icon and is said in words.

Platform adaptation ​

PlatformImplementationDifferences
Web / desktop (Vue)Notification.vue, Toaster.vue, NotificationPane.vue (Reka UI Toast and Popover)—
iOS (SwiftUI)—System notifications when the app is closed; a banner overlay in the app; the list in a sheet.
Android (Compose)—Snackbar for toasts (one at a time); the list in a bottom sheet or screen.

Tokens used ​

TokenUsed for
color blue / green / yellow / redtype icons (yellow fills the warning triangle; black outlines it)
color redunread count
color primaryunread dot
color blue (5%)unread row background
color black (65%)description, time
color black (15%)borders, lines

Do / Don't ​

DoDon't
Write a title that makes sense on its ownPut the important part only in the description
Give errors a way forward (an action)Notify for every small save: show those where they happened
Use id to update one notification as something progressesSend several notifications for the same thing

Released under the PolyForm Noncommercial License 1.0.0.