Toast

Non-blocking feedback messages used to confirm actions or display short system messages.

The Toast component displays short, non-blocking feedback messages.

It confirms actions, communicates results, or provides lightweight system feedback — without interrupting the user flow.

Toast is intentionally minimal in PyColors UI: it provides structure + accessibility, not a full notification system (queues, global store, deduping).


Import

import {
  Toast,
  ToastProvider,
  ToastViewport,
  ToastTitle,
  ToastDescription,
} from "@/components/ui/toast";

Usage

Toast is controlled explicitly by the page or component. Wrap your app (or a layout subtree) with ToastProvider and render one ToastViewport per scope.

Loading preview…
<ToastProvider>
  <Button onClick={() => setOpen(true)}>Trigger toast</Button>

  <Toast open={open} onOpenChange={setOpen}>
    <ToastTitle>Action completed</ToastTitle>
  </Toast>

  <ToastViewport className="fixed bottom-4 right-4 z-50" />
</ToastProvider>
"use client";

import * as React from "react";
import {
  Toast,
  ToastProvider,
  ToastViewport,
  ToastTitle,
  ToastDescription,
} from "@/components/ui/toast";
import { Button } from '@repo/ui';

export function ToastExample() {
  const [open, setOpen] = React.useState(false);

  return (
    <ToastProvider>
      <Button onClick={() => setOpen(true)} variant="outline" size="sm">
        Trigger toast
      </Button>

      <Toast
        open={open}
        onOpenChange={setOpen}
        variant="success"
        duration={2500}
      >
        <ToastTitle>Changes saved</ToastTitle>
        <ToastDescription>Your settings were updated.</ToastDescription>
      </Toast>

      <ToastViewport className="fixed bottom-4 right-4 z-50 flex max-w-sm flex-col gap-2 outline-none" />
    </ToastProvider>
  );
}

Variants

Toast supports a small set of visual variants. Keep them limited to avoid semantic overload.

Loading preview…
<Toast variant="default">
  <ToastTitle>Default</ToastTitle>
</Toast>

<Toast variant="success">
  <ToastTitle>Success</ToastTitle>
</Toast>

<Toast variant="warning">
  <ToastTitle>Warning</ToastTitle>
</Toast>

<Toast variant="destructive">
  <ToastTitle>Error</ToastTitle>
  <ToastDescription>Something went wrong.</ToastDescription>
</Toast>

Available variants

VariantPurpose
defaultNeutral confirmation / info
successPositive confirmation
warningAttention needed, still non-blocking
destructiveError feedback (non-blocking)

With description

Use ToastDescription for additional context when needed.

<Toast variant="warning">
  <ToastTitle>Unsaved changes</ToastTitle>
  <ToastDescription>
    Make sure to save before leaving the page.
  </ToastDescription>
</Toast>

API

Toast

PropTypeDefaultDescription
variant"default" | "success" | "warning" | "destructive""default"Visual style
openbooleanControlled open state
onOpenChange(open: boolean) => voidState handler
durationnumberRadix defaultAuto-close delay (ms)
classNamestringTailwind override

Toast extends Radix props:

React.ComponentPropsWithoutRef<typeof ToastPrimitive.Root>

ToastProvider

Wraps the area where toasts are used.

<ToastProvider>{/* ... */}</ToastProvider>

ToastViewport

Defines where toasts appear on screen. Render once per provider scope.

<ToastViewport className="fixed bottom-4 right-4 z-50" />

Accessibility

  • Built on Radix Toast primitives (keyboard + focus-safe by default).
  • Uses appropriate live regions for announcements.
  • Non-blocking: it should not trap focus or interrupt input.

Design guidelines

  • Keep messages short and explicit.
  • Prefer one toast at a time (avoid stacking).
  • Use destructive sparingly, and don’t rely on toasts for critical errors.
  • If a user must act, prefer Alert (inline) or Dialog (blocking confirmation).

When not to use Toast

Do not use Toast for:

  • Blocking errors
  • Field-level form validation
  • Onboarding flows
  • Persistent notification centers

Use Alert, EmptyState, or dedicated patterns instead.