Clawscale

Toast

A Toast is a short message about the result of an action. Toasts stack at an edge of the window and close on their own. An OverlayToaster shows them.

Usage#

Create one toaster for the whole app with OverlayToaster.create. It returns a promise that resolves to a Toaster.

// toaster.tsx
import { OverlaysProvider, OverlayToaster, type Toaster } from "@clawscale/react";
import { createRoot } from "react-dom/client";

let toaster: Promise<Toaster> | undefined;

export function getToaster() {
  toaster ??= OverlayToaster.create(
    { position: "top" },
    {
      domRenderer: (element, container) =>
        createRoot(container).render(<OverlaysProvider>{element}</OverlaysProvider>),
    },
  );
  return toaster;
}
const toaster = await getToaster();
toaster.show({ intent: "success", message: "Saved the view." });
  • Call getToaster from event handlers, not during render. OverlayToaster.create needs document, so it cannot run on the server.
  • The toaster renders in its own React root, outside ClawscaleProvider. domRenderer wraps it in an OverlaysProvider. Without one, Blueprint logs an error in development.
  • Each create call adds an element to the page. Create one toaster and share it.

The examples below import getToaster from a file like this one.

Examples#

Basic#

show displays a toast and returns its key.

import { Button } from "@clawscale/react";
import { getToaster } from "./_toaster";

export default function ToastBasic() {
  const saveView = async () => {
    const toaster = await getToaster();
    toaster.show({ icon: "tick", intent: "success", message: "Saved the view Orders by region." });
  };
  return <Button icon="floppy-disk" text="Save view" onClick={saveView} />;
}

Intent#

intent colors the toast. Pair it with an icon.

import { Button, type ToastProps } from "@clawscale/react";
import { getToaster } from "./_toaster";

const toasts: [string, ToastProps][] = [
  ["Primary", { intent: "primary", icon: "cloud-upload", message: "Deploying api-gateway v2.14.0 to 8 regions." }],
  ["Success", { intent: "success", icon: "tick", message: "Backfill finished: 90 partitions of orders_daily." }],
  ["Warning", { intent: "warning", icon: "warning-sign", message: "eu-west-1 uses 85% of its storage quota." }],
  ["Danger", { intent: "danger", icon: "error", message: "Run 4811 failed: schema mismatch in events_raw." }],
];

export default function ToastIntent() {
  const show = async (toast: ToastProps) => (await getToaster()).show(toast);
  return (
    <>
      {toasts.map(([label, toast]) => (
        <Button intent={toast.intent} key={label} text={label} onClick={() => show(toast)} />
      ))}
    </>
  );
}

Action#

action adds one button, for example Undo. A click on it runs onClick and closes the toast.

import { Button } from "@clawscale/react";
import { getToaster } from "./_toaster";

export default function ToastAction() {
  const archive = async () => {
    const toaster = await getToaster();
    toaster.show({
      icon: "archive",
      message: "Archived 3 pipelines.",
      action: {
        text: "Undo",
        onClick: () => toaster.show({ icon: "undo", message: "Restored 3 pipelines." }),
      },
    });
  };
  return <Button icon="archive" text="Archive selected" onClick={archive} />;
}

Timeout#

A toast closes after 5 seconds. timeout sets another delay in milliseconds. 0 keeps the toast open until the user closes it. Hover and focus pause the timer.

import { Button } from "@clawscale/react";
import { getToaster } from "./_toaster";

export default function ToastTimeout() {
  const showShort = async () => {
    (await getToaster()).show({ icon: "clipboard", message: "Copied the table path.", timeout: 2000 });
  };
  const showSticky = async () => {
    (await getToaster()).show({
      icon: "warning-sign",
      intent: "warning",
      message: "Maintenance window starts at 22:00 UTC. Runs pause for 30 min.",
      timeout: 0,
    });
  };
  return (
    <>
      <Button text="2 second timeout" onClick={showShort} />
      <Button text="No timeout" onClick={showSticky} />
    </>
  );
}

Update a toast#

Pass the key that show returned to update that toast in place, for example to report progress.

import { Button, ProgressBar } from "@clawscale/react";
import { getToaster } from "./_toaster";

export default function ToastUpdate() {
  const exportCsv = async () => {
    const toaster = await getToaster();
    const key = toaster.show({ icon: "export", message: <ProgressBar intent="primary" value={0} />, timeout: 0 });
    let progress = 0;
    const timer = setInterval(() => {
      progress += 0.25;
      if (progress < 1) {
        toaster.show({ icon: "export", message: <ProgressBar intent="primary" value={progress} />, timeout: 0 }, key);
        return;
      }
      clearInterval(timer);
      toaster.show({ icon: "tick", intent: "success", message: "Exported orders_daily.csv (412 MB)." }, key);
    }, 600);
  };
  return <Button icon="export" text="Export CSV" onClick={exportCsv} />;
}

Toaster methods#

MethodDescription
show(props, key?)Shows a toast, or updates the toast with that key. Returns the key.
dismiss(key)Closes one toast.
clear()Closes every toast.
getToasts()Returns the open toasts as ToastOptions.

position places the toaster at the top (default), top-left, top-right, bottom, bottom-left or bottom-right of the window. Use one toaster per position.

Props interface#

interface ToastProps extends Props, IntentProps@clawscale/react
PropsDescription
action
ActionProps & LinkProps
Action rendered as a minimal AnchorButton. The toast is dismissed automatically when the user clicks the action button. Note that the intent prop is ignored (the action button cannot have its own intent color that might conflict with the toast's intent). Omit this prop to omit the action button.
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
icon
IconName | MaybeElement
Name of a Blueprint UI icon (or an icon element) to render before the message.
intent
Intent
Visual intent color to apply to element.
Inherited from IntentProps
isCloseButtonShown
boolean = true
Whether to show the close button in the toast.
messagerequired
React.ReactNode
Message to display in the body of the toast.
onDismiss
(didTimeoutExpire: boolean) => void
Callback invoked when the toast is dismissed, either by the user or by the timeout. The value of the argument indicates whether the toast was closed because the timeout expired.
timeout
number = 5000
Milliseconds to wait before automatically dismissing toast. Providing a value less than or equal to 0 will disable the timeout (this is discouraged).
interface OverlayToasterProps extends Props@clawscale/react

Props supported by the <OverlayToaster> component. These props can be passed as an argument to the static Toaster.create(props?, container?) method.

PropsDescription
autoFocus
boolean = false
Whether a toast should acquire application focus when it first opens. This is disabled by default so that toasts do not interrupt the user's flow. Note that enforceFocus is always disabled for Toasters.
canEscapeKeyClear
boolean = true
Whether pressing the esc key should clear all active toasts.
children
React.ReactNode
Toasts to display inside the Overlay2.
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
maxToasts
number = undefined
The maximum number of active toasts that can be displayed at once.
position
ToasterPosition = Position.TOP
Position of Toaster within its container.
usePortal
boolean = true
Whether the toaster should be rendered into a new element attached to document.body. If false, then positioning will be relative to the parent element.
interface OverlayToasterCreateOptions@clawscale/react
PropsDescription
container
HTMLElement = document.body
A new DOM element will be created and appended to this container.
domRenderer
OverlayToasterDOMRenderer
A function to render the React component onto a newly created DOM element. By default, this creates a ReactDOM client root at the passed container and renders the element into that React tree.

ToastOptions are the props of an open toast plus its key.

type ToastOptions@clawscale/react
PropsDescription
action
ActionProps & LinkProps
Action rendered as a minimal AnchorButton. The toast is dismissed automatically when the user clicks the action button. Note that the intent prop is ignored (the action button cannot have its own intent color that might conflict with the toast's intent). Omit this prop to omit the action button.
Inherited from ToastProps
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
icon
IconName | MaybeElement
Name of a Blueprint UI icon (or an icon element) to render before the message.
Inherited from ToastProps
intent
Intent
Visual intent color to apply to element.
Inherited from IntentProps
isCloseButtonShown
boolean = true
Whether to show the close button in the toast.
Inherited from ToastProps
keyrequired
string
messagerequired
React.ReactNode
Message to display in the body of the toast.
Inherited from ToastProps
onDismiss
(didTimeoutExpire: boolean) => void
Callback invoked when the toast is dismissed, either by the user or by the timeout. The value of the argument indicates whether the toast was closed because the timeout expired.
Inherited from ToastProps
timeout
number = 5000
Milliseconds to wait before automatically dismissing toast. Providing a value less than or equal to 0 will disable the timeout (this is discouraged).
Inherited from ToastProps