branch:
useToast.ts
1149 bytesRaw
import {
createContext,
useCallback,
useContext,
useState,
type ReactNode
} from "react";
import { nanoid } from "nanoid";
import { createElement } from "react";
export interface Toast {
id: string;
message: string;
kind: "success" | "error" | "info";
}
interface ToastContextValue {
toasts: Toast[];
toast: (message: string, kind?: Toast["kind"]) => void;
}
const ToastContext = createContext<ToastContextValue | null>(null);
export function ToastProvider({ children }: { children: ReactNode }) {
const [toasts, setToasts] = useState<Toast[]>([]);
const toast = useCallback((message: string, kind: Toast["kind"] = "info") => {
const id = nanoid();
setToasts((prev) => [...prev.slice(-2), { id, message, kind }]);
setTimeout(() => {
setToasts((prev) => prev.filter((t) => t.id !== id));
}, 3000);
}, []);
return createElement(
ToastContext.Provider,
{ value: { toasts, toast } },
children
);
}
export function useToast() {
const context = useContext(ToastContext);
if (!context) {
throw new Error("useToast must be used within a ToastProvider");
}
return context;
}