Components

Toast

Notification stack from sonner, unstyled, with the tokens left to you

import { Toaster, toast, useSonner } from "@nyte-ai/ui/sonner";

Transient notifications. @nyte-ai/ui/sonner re-exports sonner, so sonner owns the lifecycle and the API below is sonner's.

No Nyte styling here. Pass toastOptions={{ unstyled: true }} to Toaster and supply your own classes.

Usage

  • Mount Toaster near the root of the app. One unnamed toaster renders every toast. Give it an id and route toasts to it with toasterId when you need more than one.
  • Call toast from anywhere, including outside React. It is a plain function, not a hook.
  • Give a repeated notification a stable id so a second call updates the open toast instead of stacking another one.
  • Every call that opens a toast returns its id. Pass it to toast.dismiss to close that one, or call toast.dismiss() with no argument to close all of them.

Exports

ExportKindDescription
ToastercomponentThe list that renders the open toasts.
toastfunctionOpens a toast. Also carries the variant and control methods.
useSonnerhookReturns { toasts }, the currently open toasts.
ExternalToasttypeThe options object every toast.* call takes.
ToasterPropstypeThe props of Toaster.

Examples

Mounting the toaster

<Toaster
  position="bottom-right"
  offset={16}
  gap={8}
  expand
  closeButton
  containerAriaLabel="Notifications"
  icons={{ success: <CheckIcon />, error: <WarningIcon />, close: <XIcon /> }}
  toastOptions={{
    unstyled: true,
    closeButtonAriaLabel: "Dismiss notification",
    classNames: {
      toast: styles.toast,
      title: styles.title,
      description: styles.description,
      actionButton: styles.action,
      closeButton: styles.close,
    },
  }}
/>

Opening a toast

toast("Workspace saved");
toast.success("3 chats archived");
toast.error("Could not reach the server", { description: error.message });
toast.warning("This model is deprecated");

An action, and undo

toast.success("3 chats archived", {
  id: "archive",
  action: { label: "Undo", onClick: () => restore() },
  onAutoClose: () => commit(),
});

action and cancel take { label, onClick } or a React node when you want to render the button yourself.

Replacing an open toast

The same id updates the open toast in place.

toast.success(`${count} chats archived`, { id: "archive" });

A pending operation

toast.promise(save(), {
  loading: "Saving",
  success: "Saved",
  error: (err) => err.message,
});

Reading the open toasts

const { toasts } = useSonner();

Props

The API below is sonner's.

toast

CallReturnsDescription
toast(message, data?)string | numberA default toast.
toast.message(message, data?)string | numberSame as calling toast directly.
toast.success(message, data?)string | numberSuccess variant.
toast.info(message, data?)string | numberInfo variant.
toast.warning(message, data?)string | numberWarning variant.
toast.error(message, data?)string | numberError variant.
toast.loading(message, data?)string | numberLoading variant. Never auto-closes.
toast.custom(jsx, data?)string | numberRenders your own element. jsx receives the toast id.
toast.promise(promise, data)id with unwrap()Swaps through loading, success, and error.
toast.dismiss(id?)string | numberCloses one toast, or all of them with no argument.
toast.getToasts()(ToastT | ToastToDismiss)[]The toasts that are open now.
toast.getHistory()(ToastT | ToastToDismiss)[]Open and dismissed toasts. Dismissed ones drop past 100.

message is a React node or a function returning one. data is ExternalToast.

ExternalToast

PropTypeDescription
idnumber | stringStable identity. A second call with the same id updates in place.
descriptionReact.ReactNode | (() => React.ReactNode)Second line under the title.
durationnumberMilliseconds before it closes on its own.
iconReact.ReactNodeOverrides the variant icon for this toast.
action{ label, onClick, actionButtonStyle? } | React.ReactNodeTrailing button.
cancel{ label, onClick, actionButtonStyle? } | React.ReactNodeDismiss button beside the action.
dismissiblebooleanWhether the user can swipe it away. Defaults to true.
closeButtonbooleanShows the close button for this toast.
onDismiss(toast: ToastT) => voidFires when the user closes it.
onAutoClose(toast: ToastT) => voidFires when the duration runs out.
positionPositionOverrides the toaster position for this toast.
richColorsbooleanVariant-tinted background.
invertbooleanInverts the theme for this toast.
unstyledbooleanDrops sonner's own toast CSS.
classNamestringClass on the toast element.
classNamesToastClassnamesPer-part classes.
descriptionClassNamestringClass on the description.
styleReact.CSSPropertiesInline style on the toast.
actionButtonStyleReact.CSSPropertiesInline style on the action button.
cancelButtonStyleReact.CSSPropertiesInline style on the cancel button.
toasterIdstringRoutes the toast to a specific Toaster.
testIdstringSets data-testid on the toast element.

ToasterProps

PropTypeDefaultDescription
idstringNames this toaster, for toasterId on a toast.
positionPosition"bottom-right"Corner the stack grows from.
theme"light" | "dark" | "system""light"Color scheme sonner applies.
offsetOffsetDistance from the viewport edge.
mobileOffsetOffsetSame, at small viewports.
gapnumber14Space between stacked toasts.
expandbooleanShows the stack expanded instead of collapsed.
visibleToastsnumber3How many toasts render at once.
durationnumber4000Default milliseconds for every toast.
closeButtonbooleanShows a close button on every toast.
richColorsbooleanVariant-tinted backgrounds.
invertbooleanInverts the theme.
iconsToastIconsYour icons for success, info, warning, error, loading, and close.
toastOptionsToastOptionsDefaults applied to every toast, including unstyled and classNames.
hotkeystring[]["altKey", "KeyT"]Keys that expand the stack and move focus to it.
swipeDirections("top" | "right" | "bottom" | "left")[]Directions a toast can be swiped away.
dir"rtl" | "ltr" | "auto"document directionText direction.
containerAriaLabelstring"Notifications"Names the list. Sonner appends the hotkey.
customAriaLabelstringReplaces the whole list name, hotkey included.
classNamestringClass on the list container.
styleReact.CSSPropertiesInline style on the list container.

Shapes

@nyte-ai/ui/sonner exports the types ExternalToast and ToasterProps. The names below appear in those types and are not exported.

NameShape
Position"top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center"
Offsetnumber | string | { top?, right?, bottom?, left? }
ToastIconssuccess, info, warning, error, loading, close, each a React node
ToastOptionsclassName, closeButton, descriptionClassName, style, cancelButtonStyle, actionButtonStyle, duration, unstyled, classNames, closeButtonAriaLabel, toasterId
ToastClassnamestoast, title, description, content, icon, loader, closeButton, cancelButton, actionButton, success, error, info, warning, loading, default
ToastTThe open toast, with its id, title, type, and the options it was given
ToastToDismiss{ id, dismiss }

Accessibility

  • The toaster renders a region with aria-live="polite". A new toast is announced without moving focus.
  • The region's accessible name is containerAriaLabel plus the hotkey, so a screen reader user hears how to reach the stack. customAriaLabel replaces that whole name.
  • The hotkey expands the stack and moves focus to the list. Escape collapses it again while focus is still inside.
  • A close button needs a name. Set closeButtonAriaLabel in toastOptions.
  • A loading toast carries no close button and no timer. Replace it or dismiss it by id.
  • A toast is not a dialog. Do not put the only path to an action in one, since it closes on a timer.