Orbex Sonar-DB Design system , home

Examples

Saved, and removed with undo
Code
tsx
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

Content and action 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 with useToast.
  • Toasts centre on the window, 24 px above its foot. In an app with a sidebar, inset centres 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

DoA toast confirms what just happened, and offers to undo it.
Don’tA toast for a problem that needs action: it leaves before it is read. Use a notice or a dialog.
DoA few words, on one line.
Don’tA paragraph in a toast.

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.

tsx
import { ToastProvider } from '@orbex/sonar-components/toast'
import '@orbex/sonar-components/toast.css'

API

Props of ToastProvider
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 and right bound the area they centre in (such as the main area, right of a sidebar), bottom lifts them above a footer or a bottom app bar. The window’s safe area is added to bottom.

{ 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