Toast

A notification system for displaying temporary messages at the bottom of the screen. Toasts support multiple variants, optional action buttons, auto-dismiss timeouts, and keyboard navigation. Render the Toasts container once in your app and use addToast() to trigger notifications.

import { Button } from "@tenstorrent/vesper/button";
import { addToast } from "@tenstorrent/vesper/toast";

export default function ToastDemo() {
  return (
    <Button
      onClick={() => addToast({ content: "Hello from Vesper!", timeout: 5000 })}
    >
      Show toast
    </Button>
  );
}

Options

Toasts (Container)

PropTypeDescriptionDefault
ariaLabelstringThe accessible label for the toast region. The keyboard shortcut is automatically appended."Notifications"
shortcutstring | { key: string; alt?: boolean; ctrl?: boolean; shift?: boolean; meta?: boolean }A keyboard shortcut that moves focus to the oldest active toast."F8"
containerElement | DocumentFragmentThe DOM element to portal the toast container into.document.body

addToast (Options)

PropTypeDescriptionDefault
contentReactNodeThe message content displayed inside the toast.—
variant"default" | "success" | "warning" | "danger" | "loading"The visual variant of the toast, which determines its icon and color."default"
timeoutnumber | falseDuration in milliseconds before the toast auto-dismisses. Set to false to disable.false
actionToastActionAn optional action to render a button at the bottom of the toast.—
dismissTextstringCustomizes the aria-label text for the dismiss button."Dismiss"

Examples

Basic usage

To enable usage of toasts in your application, you must first render the Toasts component once at the root level of your application. In a Next.js application, for example, you would render the Toasts component in your app's root layout.tsx.

import { Toasts } from "@tenstorrent/vesper/toast";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        {children}
        <Toasts />
      </body>
    </html>
  );
}

Once you have rendered the Toasts component in your application, you can spawn toasts by calling the addToast function:

addToast({ content: "Changes saved.", timeout: 5000 });

addToast can be called with the following set of options:

interface ToastOptions {
  content: ReactNode;
  action?: {
    handler: () => void;
    content: ReactNode;
    altText?: string;
  };
  timeout?: number | false;
  variant?: ToastVariant;
  dismissText?: string;
}

Toast variants

Toasts can be spawned with one of five variants: "default", "loading", "success", "warning", or "danger".

For example, to spawn a warning variant toast that self-dismisses after 5 seconds, you would call addToast like so:

import { Button } from "@tenstorrent/vesper/button";
import { addToast } from "@tenstorrent/vesper/toast";

export default function WarningToast() {
  return (
    <Button
      onClick={() =>
        addToast({
          content: "Resistance is futile.",
          variant: "warning",
          timeout: 5000,
        })
      }
    >
      Show toast
    </Button>
  );
}

Self-dismissing toasts

Toasts by default do not dismiss themselves; you must specify a timeout duration if you want a toast to disappear on its own. If a user interacts with a toast by moving their cursor or keyboard focus into the toast, the timeout will stop, and restart once the user ceases to interact with the toast.

To spawn a self-dismissing toast, you must provide a timeout, which represents the duration in milliseconds the toast will be visible for:

import { Button } from "@tenstorrent/vesper/button";
import { addToast } from "@tenstorrent/vesper/toast";

export default function SelfDismissingToast() {
  return (
    <Button
      onClick={() =>
        addToast({
          content: "This toast will dismiss itself!",
          timeout: 5000,
        })
      }
    >
      Show toast
    </Button>
  );
}

Toasts with actions

You may spawn a toast with an associated call-to-action by passing an action object in the toast options:

import { Button } from "@tenstorrent/vesper/button";
import { addToast } from "@tenstorrent/vesper/toast";

export default function ToastWithAction() {
  return (
    <Button
      onClick={() =>
        addToast({
          content: "Conversation archived.",
          timeout: 5000,
          variant: "success",
          action: {
            handler: () => console.log("You clicked the toast action button!"),
            content: "Undo",
            altText: "Go to archive to restore conversations.",
          },
        })
      }
    >
      Archive conversation
    </Button>
  );
}

Action objects have three properties:

  1. handler – a callback function that fires when the call-to-action is clicked.
  2. content – what appears inside the call-to-action (usually this will just be text, though any ReactNode is supported)
  3. altText – short description of an alternative way for users to achieve the desired action. This field is important for screen reader users who may not be able to access the toast easily, especially if it is time-sensitive.

Updating toasts

There may be situations where you want to update a toast while it's active. addToast will return a handle to the toast it spawned, which has the following type signature:

interface ToastHandle {
  dismiss(): void;
  update(options: Partial<ToastOptions>): void;
}

Calling dismiss() will dismiss the toast, and calling update() will update the toast. For example, you could have a "loading" variant toast show while a network request is being made, then transition to either a "success" or "warning" variant and dismiss itself after a 5 second timeout when the request completes:

import { Button } from "@tenstorrent/vesper/button";
import { addToast } from "@tenstorrent/vesper/toast";

export default function UpdatingToastDemo() {
  return (
    <Button
      onClick={async () => {
        // Spawn the toast
        const toast = addToast({
          content: "Fetching updates...",
          variant: "loading",
        });

        // Await something asynchronous, like a timeout or network request
        await new Promise((resolve) => setTimeout(resolve, 3000));

        // Update the toast
        toast.update({
          content: "Updates fetched!",
          variant: "success",
          timeout: 3000,
        });
      }}
    >
      Refresh feed
    </Button>
  );
}