sigilUI

Toast

A non-intrusive notification popup with auto-dismiss, action buttons, and swipe-to-dismiss. Built on Radix Toast.

@sigil-ui/componentsReact

Preview

Live preview Interactive

Import

import { Toaster, toast } from "@sigil-ui/components";

Setup

Add <Toaster /> to your root layout:

<Toaster />

Usage

"use client";

import { useState } from "react";
import { Button, Sonner, Toaster, ToastPromise, sonnerToast, toast } from "@sigil-ui/components";

const TRAFFIC = [
  { month: "Apr", desktop: 186, mobile: 80 },
  { month: "May", desktop: 224, mobile: 112 },
  { month: "Jun", desktop: 208, mobile: 132 },
  { month: "Jul", desktop: 278, mobile: 166 },
  { month: "Aug", desktop: 305, mobile: 184 },
  { month: "Sep", desktop: 342, mobile: 218 },
];

function ToastPreview({ engine = "radix" }: { engine?: "radix" | "sonner" | "promise" }) {
  const [pending, setPending] = useState(false);
  async function save(fail = false) {
    setPending(true);
    const request = new Promise<void>((resolve, reject) => {
      window.setTimeout(() => fail ? reject(new Error("Demo request failed")) : resolve(), 800);
    });
    try {
      await ToastPromise(request, { loading: "Saving project…", success: "Project saved", error: "Could not save. Try again." });
    } catch {
      // The toast displays the demo failure; keep the button available for retry.
    } finally { setPending(false); }
  }
  return (
    <div className="grid gap-[var(--s-space-16)] w-full">
      {engine === "radix" ? <Toaster position="top-right" /> : <Sonner position="top-right" closeButton />}
      <div className="flex flex-wrap gap-[var(--s-space-12)]">
        {engine === "promise" ? <>
          <Button disabled={pending} onClick={() => save()}>Save project</Button>
          <Button variant="outline" disabled={pending} onClick={() => save(true)}>Try a failed request</Button>
        </> : <>
          <Button onClick={() => engine === "sonner" ? sonnerToast.success("Project saved", { description: "Your changes are ready." }) : toast({ title: "Project saved", description: "Your changes are ready.", variant: "success" })}>Show success</Button>
          <Button variant="outline" onClick={() => engine === "sonner" ? sonnerToast.error("Could not save", { description: "Check your connection and try again." }) : toast({ title: "Could not save", description: "Check your connection and try again.", variant: "error" })}>Show error</Button>
        </>}
      </div>
      <p className="text-[var(--s-text-muted)] text-[length:var(--s-size-sm)]">Notifications appear in the top right. Dismiss them with the close button.</p>
    </div>
  );
}

Variants

toast.success("File uploaded.");
toast.error("Something went wrong.");
toast.warning("Storage almost full.");
toast.info("New version available.");

With action

toast("Message deleted.", {
  action: { label: "Undo", onClick: () => restore() },
});

With description

toast("Deployment complete", {
  description: "Your changes are now live in production.",
});

Custom duration

toast("Quick flash", { duration: 2000 });
toast("Sticky notice", { duration: Infinity });

Token integration

CSS VariableUsed for
--s-surfaceToast background
--s-textToast message color
--s-text-mutedDescription color
--s-borderToast border
--s-successSuccess variant accent
--s-errorError variant accent
--s-warningWarning variant accent
--s-card-radiusBorder radius
--s-shadow-lgToast elevation
--s-duration-normalEnter/exit animation

Props

toast()

ParamTypeDefaultDescription
messagestring—Toast message
options.descriptionstring—Secondary text
options.action{ label: string; onClick: () => void }—Action button
options.durationnumber5000Auto-dismiss time in ms

Toaster

PropTypeDefaultDescription
position"top-right" | "top-left" | "bottom-right" | "bottom-left""bottom-right"Toast position
classNamestring—Additional CSS classes

Accessibility

  • Uses role="status" with aria-live="polite" for non-urgent toasts
  • Error toasts use aria-live="assertive"
  • Swipe-to-dismiss works on touch devices
  • Focus moves to action button when present