Aksara UI

Toast

Toasts give short feedback after an action. Mount one Toaster, then call toast from anywhere.

import { Toaster, toast } from '@aksornproject/aksara-ui'

Basic toast

Mount <Toaster /> once near the root of the app, then call toast(message, options). description adds a second line. toast returns the toast id.

Sonner owns the queue, the timers, swipe to dismiss, the hover pause and the live region. Aksara UI supplies the colours, the icons, the layout and the action and close Buttons.

Each demo on this page mounts its own Toaster with an id and sends toasts to it with toasterId. An app with one Toaster needs neither.

<Button
  onClick={() =>
    toast.success('Changes saved', {
      description: 'Your profile is visible to your class.',
      toasterId: 'toast-basic',
    })
  }
>
  Save profile
</Button>
<Toaster id="toast-basic" />

Tones

toast, toast.success, toast.error, toast.warning and toast.information pick the tone colour and icon. Choose by meaning. Success confirms, error reports a failure, warning flags a risk and information adds context.

<Button
  variant="secondary-accent"
  onClick={() => toast('Lesson plan duplicated', options)}
>
  Default
</Button>
<Button
  variant="secondary-accent"
  onClick={() => toast.success('Grades submitted', options)}
>
  Success
</Button>
<Button
  variant="secondary-accent"
  onClick={() => toast.error('Upload failed', options)}
>
  Error
</Button>
<Button
  variant="secondary-accent"
  onClick={() => toast.warning('Storage almost full', options)}
>
  Warning
</Button>
<Button
  variant="secondary-accent"
  onClick={() => toast.information('Timetable updated', options)}
>
  Information
</Button>
<Toaster id="toast-variants" />

Action

action adds a Button with a label and an onClick. A click dismisses the toast unless onClick calls event.preventDefault() synchronously. Use duration: Infinity for an action that must stay available, because keyboard focus does not pause the timer.

<Button onClick={upload}>Upload report</Button>
<Toaster id="toast-action" />

Updating and dismissing

A call with the id of an open toast replaces it. An update keeps the native options it omits, so set duration again when you replace a persistent toast. toast.dismiss(id) closes it.

<Button variant="secondary-accent" onClick={save}>
  Save draft
</Button>
<Toaster id="toast-update" />

Icon and close button

icon replaces the tone icon, and icon: null hides it. closeButton: false removes the close button. closeButtonLabel renames it, "Close toast" by default. className and classNames merge last, so your classes win.

<Button
  variant="secondary-accent"
  onClick={() =>
    toast.information('Link copied', {
      icon: <IconFoldersFolderLink aria-hidden />,
      toasterId: 'toast-options',
    })
  }
>
  Custom icon
</Button>
<Button
  variant="secondary-accent"
  onClick={() =>
    toast.warning('You are offline', {
      icon: null,
      closeButton: false,
      toasterId: 'toast-options',
    })
  }
>
  No icon or close
</Button>
<Toaster id="toast-options" />

Position and width

position, duration, visibleToasts, gap, offset and hotkey pass through to Sonner. The --width style sets the desktop toast width, 542px by default. Below a 480px toast, and on phones, the action moves to its own row under the text.

<Button
  variant="secondary-accent"
  onClick={() =>
    toast('Attendance marked for 5/2', {
      toasterId: 'toast-position',
      action: { label: 'Undo', onClick: () => {} },
    })
  }
>
  Mark attendance
</Button>
<Toaster
  id="toast-position"
  position="top-center"
  style={{ '--width': '420px' }}
/>

Accessibility

  • Sonner's <section aria-live="polite"> is the only live region. Toasts carry no alert or status role, so errors are announced politely too. Use a Dialog for anything that must interrupt.
  • Icons are decorative. Put the meaning in the message.
  • The action and close buttons are type="button", so a Toaster inside a form never submits it. The action comes before the close in the tab order.
  • Alt+T focuses the toast region and pauses the stack while it is expanded.
  • Tab focus does not pause the timer. Give a toast with an action duration: Infinity.

API

Toaster

Prop

Type

toast

toast(message, options) and each tone take these options.

Prop

Type

ToastAction

Prop

Type

Edit on GitHub

On this page