Feedback

toast

Shows a toast: a short message that appears at the bottom of the screen, is read to screen readers once, and dismisses itself. Call it from anywhere, such as an event handler or an action's result, after rendering <Toaster /> once. Returns the toast's id; toast.dismiss(id) closes it, and toast.dismiss() closes them all.

import { toast } from "@/lib/ouro/toast";

Example

toast("Recipe saved", { tone: "success" });
toast("Recipe deleted", { action: { label: "Undo", onClick: restore } });
toast("Couldn't save", { tone: "destructive", description: "Check your connection." });

Usage

A toast called before the Toaster mounts waits for it. Up to three show at once, the newest in front; later ones wait their turn, a destructive toast ahead of the others, and each one's countdown starts when it shows. Hovering or focusing them (or pressing F6) pauses the countdown, and a swipe down or sideways dismisses one. A toast with an action stays until it is dismissed unless you pass a duration.

Use instead when

  • Use Alert instead when the message must stay on the page, such as a form's errors, and Dialog when the user must answer before going on.

Parameters

message
Type: string
options
Type: ToastOptions
{}

Returns

string

Types

ToastAction

A button in a toast: { label: "Undo", onClick: undo }. Pressing it runs onClick, then dismisses the toast.

interface ToastAction {
  /** The button's text: a short verb, such as "Undo" or "View". */
  label: string;
  /** Runs when the button is pressed, before the toast is dismissed. */
  onClick: () => void;
}

ToastOptions

Options for toast.

interface ToastOptions {
  /**
   * Color role from the theme, named after its token, shown as an icon: `success` for
   * a check, `warning` and `destructive` for a problem, `primary` for information.
   * `secondary`, the default, has no icon. Sonner's `error` is `destructive` and its
   * `info` is `primary`.
   * @default "secondary"
   */
  tone?:
    | "primary"
    | "secondary"
    | "destructive"
    | "success"
    | "warning"
    | (string & { 'error is "destructive"; info is "primary"; danger is "destructive"': never })
    | undefined;
  /** A second line under the message. */
  description?: ReactNode;
  /** A button in the toast, such as Undo: `{ label: "Undo", onClick: undo }`. Pressing it dismisses the toast. */
  action?: ToastAction | undefined;
  /**
   * How long the toast stays once it shows, in milliseconds. Hovering or focusing the
   * toasts pauses the countdown. `0` or `Infinity` keeps it until it is dismissed.
   *
   * A toast with an `action` stays until it is dismissed unless you pass a duration: a
   * timed Undo can run out before a keyboard or screen reader user reaches it (WCAG 2.2.1).
   * @default 5000, or until dismissed with an action
   */
  duration?: number | undefined;
  /** An id of your own. A toast with the id of one still showing replaces it in place. */
  id?: string | undefined;

  /** Not an option. Ouro UI uses `tone`: `toast("Saved", { tone: "success" })`. */
  type?: { 'Use toast("Saved", { tone: "success" })': never };
  /** Not an option. Ouro UI uses `tone`: `toast("Saved", { tone: "success" })`. */
  variant?: { 'Use toast("Saved", { tone: "success" })': never };
  /** Not an option. Ouro UI uses `duration`, in milliseconds: `toast("Saved", { duration: 8000 })`. */
  timeout?: { 'Use toast("Saved", { duration: 8000 })': never };
  /** Not an option. The message is the first argument: `toast("Saved", { description: "…" })`. */
  title?: { 'The message is the first argument: toast("Saved")': never };
}