Toast
Transient notification.
Preview
Code
import { Button } from "@/components/ui/button";
import { toast } from "@/components/ui/toast";
export function Example() {
return (
<div className="flex flex-wrap gap-2">
<Button
variant="outline"
size="sm"
onClick={() =>
toast.add({
title: "Saved",
description: "Your changes have been saved.",
type: "success",
})
}
>
Success
</Button>
<Button
variant="outline"
size="sm"
onClick={() =>
toast.add({
title: "Couldn't save",
description: "Network error. Try again.",
type: "error",
})
}
>
Error
</Button>
<Button
variant="outline"
size="sm"
onClick={() =>
toast.add({
title: "Heads up",
description: "A new version is available.",
type: "info",
})
}
>
Info
</Button>
</div>
);
}
// <ToastProvider> must wrap your app in app/layout.tsx.Props
No props on the root — see sub-components below.
Sub-components
ToastProvider— Wraps the app. Required for `toast.add()` calls to render.ToastViewport— Where toasts appear. Rendered inside ToastProvider by default.Built on Base UI Toast. Trigger via the imperative `toast.add({ title, description, variant })` singleton from `components/ui/toast.tsx`. `<ToastProvider>` must be in `app/layout.tsx` for toasts to render.
All components also accept standard HTML attributes for their root element (e.g. `id`, `aria-*`, `data-*`, event handlers) and forward `ref` where applicable.
Source
The full implementation of components/ui/toast.tsx is below — copy it into your project and own it. Some components import the cn helper from lib/utils or other primitives; copy those too.
"use client";
import { cn } from "@/lib/utils";
import { Toast as BaseToast } from "@base-ui-components/react/toast";
import { AlertCircle, CheckCircle, Info, X } from "lucide-react";
import type { ComponentPropsWithoutRef, ReactNode } from "react";
// Singleton manager — import `toast` and call toast.add(), toast.promise(), etc.
export const toast = BaseToast.createToastManager();
const typeIcons: Record<string, ReactNode> = {
success: <CheckCircle className="h-4 w-4 text-success" />,
error: <AlertCircle className="h-4 w-4 text-danger" />,
info: <Info className="h-4 w-4 text-info" />,
};
function ToastViewportInner() {
const { toasts } = BaseToast.useToastManager();
return (
<BaseToast.Viewport
className={cn(
"fixed bottom-4 right-4 z-50 flex max-h-screen w-full max-w-sm flex-col-reverse gap-2",
"sm:bottom-4 sm:right-4",
)}
>
{toasts.map((t) => (
<BaseToast.Root
key={t.id}
toast={t}
className={cn(
"relative flex w-full items-start gap-3 overflow-hidden rounded-lg border border-border",
"bg-surface-elevated p-4 shadow-lg",
"data-[starting-style]:translate-y-2 data-[starting-style]:opacity-0",
"data-[ending-style]:translate-y-2 data-[ending-style]:opacity-0",
"transition-all duration-200",
)}
>
{t.type && typeIcons[t.type] && (
<div className="mt-0.5 shrink-0">{typeIcons[t.type]}</div>
)}
<div className="flex flex-1 flex-col gap-0.5">
{t.title && <BaseToast.Title className="text-sm font-semibold text-fg" />}
{t.description && <BaseToast.Description className="text-sm text-fg-muted" />}
</div>
<BaseToast.Close
className={cn(
"mt-0.5 shrink-0 rounded-sm text-fg-muted opacity-70 transition-opacity",
"hover:opacity-100 focus-visible:outline-1 focus-visible:outline-offset-0 focus-visible:outline-accent",
)}
aria-label="Dismiss"
>
<X className="h-4 w-4" />
</BaseToast.Close>
</BaseToast.Root>
))}
</BaseToast.Viewport>
);
}
export function ToastProvider({
children,
timeout = 5000,
}: {
children: ReactNode;
timeout?: number;
}) {
return (
<BaseToast.Provider toastManager={toast} timeout={timeout}>
{children}
<ToastViewportInner />
</BaseToast.Provider>
);
}JavaFX
Ships in the PRIZM JavaFX library for thick-client C3 apps as PrizmToast (extends HBox). Run the gallery to see it natively.
import design.prizm.fx.controls.PrizmToast;
PrizmToast(Variant variant, String title, String message)| Prop | Type | Default | Description |
|---|---|---|---|
| Variant | enum { DEFAULT, INFO, SUCCESS, WARNING, ERROR } | DEFAULT | Status; colours the leading dot (a small dot stands in for the web's per-type icon). |
| PrizmToaster(StackPane host) | manager | — | Bind one to a host StackPane; the bottom-right overlay that stacks toasts. |
| PrizmToaster.show | (Variant, String title, String message[, Duration timeout]) → PrizmToast | — | Show a toast; slides + fades in, auto-dismisses after the timeout (default 5s). |
| PrizmToaster.dismiss | (PrizmToast) → void | — | Dismiss early (also on the toast's ✕). |
PrizmToast is one notification card (styled by .prizm-toast); PrizmToaster manages a bottom-right stack on a host StackPane (slide+fade, 5s auto-dismiss) — the instance-bound equivalent of the web `toast` singleton + ToastProvider. Mirrors components/ui/toast.tsx.