Toast

The toast system has two parts: a ToastProvider mounted once near the app root, and the useToast hook called from anywhere in the tree. Call show() from any component to push a notification onto the stack.

  • Four variants — info, success, warning, error — each with a matching icon and ARIA role.
  • Optional primaryAction and/or secondaryAction add buttons below the description (and disable auto-dismiss).
  • duration controls auto-dismiss (default 5000ms; pass 0 to disable).
  • dismiss(id) removes a toast programmatically using the id returned from show().
  • ToastProvider exposes position (six placements) and maxToasts (FIFO eviction).

Import

import { ToastProvider } from "h2o-library";
import { useToast } from "h2o-library/hooks";

Setup

Wrap your app or layout root with ToastProvider:

// app/layout.tsx
import { ToastProvider } from "h2o-library";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ToastProvider>{children}</ToastProvider>
      </body>
    </html>
  );
}

Usage

Triggering a Toast

Call show() from any descendant of ToastProvider. It returns the new toast's id.

"use client";
import { Button } from "h2o-library";
import { useToast } from "h2o-library/hooks";

function SaveButton() {
  const { show } = useToast();

  return (
    <Button
      label="Save"
      onClick={() =>
        show({
          variant: "success",
          title: "Saved",
          description: "Your changes have been saved.",
        })
      }
    />
  );
}

Variants

Each variant sets the icon, color, and ARIA role: error / warning use role="alert", info / success use role="status".

show({ variant: "info", title: "Heads up", description: "Just so you know…" });
show({ variant: "success", title: "Done", description: "Operation complete." });
show({
  variant: "warning",
  title: "Careful",
  description: "This action is destructive.",
});
show({
  variant: "error",
  title: "Failed",
  description: "Something went wrong.",
});

With Actions

Add primaryAction and/or secondaryAction. Action buttons disable auto-dismiss so the user has time to react.

show({
  variant: "success",
  title: "Record updated",
  description: "Patient record has been updated.",
  primaryAction: { label: "View", action: () => router.push("/records/123") },
  secondaryAction: { label: "Undo", action: undoChange },
});

Custom Duration

duration is in milliseconds. Pass 0 to disable auto-dismiss — useful for blocking states or "uploading…" toasts that resolve later.

{
  /* Auto-dismiss after 2 seconds */
}
show({ variant: "success", title: "Copied!", duration: 2000 });

{
  /* Never auto-dismiss */
}
show({ variant: "warning", title: "Action required", duration: 0 });

Programmatic Dismiss

show() returns the toast id; pass it to dismiss(id) to remove the toast manually. Pair with duration: 0 for "loading…" toasts that resolve later.

const { show, dismiss } = useToast();

const id = show({ variant: "info", title: "Uploading…", duration: 0 });

uploadFile().then(() => {
  dismiss(id);
  show({ variant: "success", title: "Upload complete" });
});

Position

Configure where the stack is anchored on the provider. bottom-right is the default.

<ToastProvider position="top-center" maxToasts={3}>
  {children}
</ToastProvider>;

Playground

Loading playground…

API

useToast(){ show, dismiss }

show(options) → id

PropTypeDefaultDescription
variant*"info" | "success" | "warning" | "error"Visual style and icon. Also tunes the ARIA role (alert vs. status).
title*stringBold heading of the notification.
descriptionstringundefinedSupporting text below the title.
durationnumber5000Auto-dismiss delay in ms. Pass 0 to never auto-dismiss. Ignored when actions are present.
primaryAction{ label: string; action: () => void }undefinedPrimary action button. Prevents auto-dismiss.
secondaryAction{ label: string; action: () => void }undefinedSecondary action button. Prevents auto-dismiss.

* Required

Returns the new toast's id (string).

dismiss(id)

Programmatically removes the toast with the given id.

ToastProvider

PropTypeDefaultDescription
children*React.ReactNodeApp tree that should have access to useToast().
position"top-right" | "top-left" | "bottom-right" | "bottom-left" | "top-center" | "bottom-center""bottom-right"Where on screen the toast stack is anchored.
maxToastsnumber5Maximum number of toasts shown at once. Oldest are evicted first.

* Required

Design Guidelines

  • Use toast for ephemeral feedback about background operations (save, delete, export, copy-to-clipboard).
  • Keep title short (2–4 words) and description to one sentence.
  • Use primaryAction for an immediately actionable step ("View", "Undo"); pair with a secondaryAction only when both are equally relevant.
  • Don't use toast for errors that require user input — surface those inline (Message) or in a Modal.
  • Use position="bottom-right" for desktop dashboards; top-center works well on mobile / shorter pages where the bottom may be visually busy.

Accessibility

  • error and warning toasts use role="alert" so screen readers announce them assertively.
  • info and success toasts use role="status" for polite announcement.
  • Action buttons are keyboard accessible and the close button has aria-label="Close toast".
  • For very short auto-dismiss durations (under 4–5 seconds), users with assistive tech may not have time to read — prefer longer durations or rely on actions to keep the toast visible.