Component Craft · 2024–2025

Designing the
notification system

A box with text and an icon — until you account for severity, placement, stacking, timing, and what a screen reader hears.

Role
Design System Lead
Company
SpotOn
Timeline
2024–2025
Status
Shipped

A "simple" component that wasn't

A notification is a box with text until you account for severity, placement, timing, and stacking.

Underneath, it's a system of decisions: which severities mean what, where a message appears, how long it stays, whether it can be dismissed, what happens when several fire at once.

At SpotOn, teams answered those questions independently. The same event could be a red banner in one product and a gray toast in another. The governance push was the moment to define what these components are for, not just document them.

NEW — create from real product screenshots, redact if needed img/cs5-inconsistency.png

The same event — a failed payment — rendered as a red persistent banner in one product and a gray dismissible toast in another

So the first thing I defined was when to reach for each one

A decision framework so the same event always produces the same type of notification.

Component Priority Behavior Use for
Toast Low Disappears automatically Successful actions, non-critical errors in the moment
Banner Medium Persists until dismissed or resolved Persistent errors, informative messages that require awareness
Modal / Bottom Sheet High Blocks flow until action taken Anything requiring a decision before continuing

Teams had been choosing by vibe. The table isn't about color or icon. It's about interruption level and resolution path.

The banner rule that mattered most: severity before style

Three severity levels, with one rule that matters most: an error banner can't be dismissed until it's resolved.

Informative: helpful messages, dismissable. Warning: needs attention soon, not immediate action. Error: needs addressing now, and stays until the state that caused it is fixed.

An error banner with a close button is a lie. It lets users hide a problem they haven't solved. That constraint came from asking what "resolved" actually means for the user.

✅ HAVE IT — banner documentation images img/cs5-banner-severity.png

Severity before style — the rule determines the component, not the color

NEW — prototype the interaction img/cs5-error-banner-nodismiss.gif

Click the close button — nothing happens. The error stays until the underlying state is fixed

One banner at a time, because if everything's urgent nothing is

Only one global banner at a time, because stacking urgency destroys it.

Multiple simultaneous banners alarm users and dilute urgency. Stacking three red errors doesn't communicate priority, it communicates chaos. The constraint forces the product to decide what's actually most important right now.

Banners are system-level messaging only, not promotional content. No "Exclusive new user offer!" in a banner. That's a toast or a marketing surface.

✅ HAVE IT — banner documentation images img/cs5-banner-donts.png

One banner at a time — if everything is urgent, nothing is

NEW — prototype both states img/cs5-stacked-vs-one.gif

Three red banners stacking (alarming, unreadable) vs the same situation resolved to one prioritized banner

With toasts, the visual is easy and the behavior is the work

The toast's visual is simple; the motion, content, and grouping rules are the real design.

Motion: animate in from their side, out the opposite way. New toasts push existing ones. Content: object plus -ed verb for success ("Credit card attached"), single-word actions, two-line max, no generic errors.

The rule that changed behavior: group same-kind actions into one toast. "Added 3 items to your order" instead of three separate toasts. That cut notification noise significantly across products.

✅ HAVE IT — toast documentation images img/cs5-toast-variants.png

The visual design is simple. The behavioral rules are where the work is.

NEW — prototype the motion or screen-record from Storybook img/cs5-toast-motion.gif

Animates in from its side, a second toast pushes the first, then auto-dismisses out the opposite way

NEW — prototype both behaviors img/cs5-toast-grouping.gif

Three "Added an item" toasts firing one after another, then the same operation as "Added 3 items to your order"

Accessibility was in the spec from the start, not bolted on after

Four accessibility rules written into the component docs so they travel with it.

Minimum 6-second display (5s plus 1s per 120 characters). Consistent placement so screen reader users know where to expect feedback. Full tab and shift-tab navigation in a stable focus order. No toasts on page load, which confuse users still orienting.

These came from research into notification accessibility, specifically Sheri Byrne-Haber's work, and were written into the docs so they travel with the component, not just the people who knew them.

✅ HAVE IT — toast documentation image 16 img/cs5-accessibility-spec.png

Rules written into the docs so they travel with the component

What it shipped as: a framework, not just two components

Two documented components that replaced a fragmented set of one-off implementations.

Banner (informative, warning, error × global, inline) and Toast (success, error × with/without action × fixed width mobile, dynamic width desktop), fully documented with behavioral specs, content rules, placement, dos and don'ts, and accessibility.

Teams stopped asking "should I use a banner or a toast?" because the answer was in the docs.

✅ HAVE IT — combine from banner + toast documentation images img/cs5-full-system.png

Banner + Toast — the full system

Next case study

Counter app & Loyalty

Designing a customer-facing POS kiosk for fast-paced restaurant environments.