Toast
Overlay & FeedbackTemporary notification message with auto-dismiss.
Preview
Usage
example.jsx
import { ToastProvider } from "@/components/ui/toast";
export default function Example() {
return <ToastProvider />;
}Source Code
Copy this file into components/ui/toast.jsx in your project.
toast.jsx
"use client";
import { createContext, useContext, useState, useCallback } from "react";
import { cn } from "@/lib/utils";
const ToastContext = createContext({ toasts: [], addToast: () => {}, removeToast: () => {} });
export function ToastProvider({ children }) {
const [toasts, setToasts] = useState([]);
const addToast = useCallback((toast) => {
const id = Date.now();
setToasts((prev) => [...prev, { ...toast, id }]);
setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), toast.duration || 5000);
return id;
}, []);
const removeToast = useCallback((id) => setToasts((prev) => prev.filter((t) => t.id !== id)), []);
return (
<ToastContext.Provider value={{ toasts, addToast, removeToast }}>
{children}
<div className="fixed bottom-4 right-4 z-[100] flex flex-col gap-2">
{toasts.map((toast) => (
<div key={toast.id} className={cn("flex items-center justify-between gap-4 rounded-lg border bg-background px-4 py-3 shadow-lg animate-in slide-in-from-bottom-5",
toast.variant === "destructive" && "border-destructive bg-destructive text-destructive-foreground"
)}>
<div>
{toast.title && <div className="text-sm font-semibold">{toast.title}</div>}
{toast.description && <div className="text-sm text-muted-foreground">{toast.description}</div>}
</div>
<button onClick={() => removeToast(toast.id)} className="shrink-0 rounded-sm opacity-70 hover:opacity-100">
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
))}
</div>
</ToastContext.Provider>
);
}
export function useToast() {
const ctx = useContext(ToastContext);
return { toast: ctx.addToast, dismiss: ctx.removeToast, toasts: ctx.toasts };
}
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge