From 18cf3e83533b56531c516faeb2acfa950ef6a4d4 Mon Sep 17 00:00:00 2001 From: notshop Date: Sun, 26 Apr 2026 16:35:03 +0000 Subject: [PATCH] chore: add client/src/hooks/use-toast.ts --- client/src/hooks/use-toast.ts | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 client/src/hooks/use-toast.ts diff --git a/client/src/hooks/use-toast.ts b/client/src/hooks/use-toast.ts new file mode 100644 index 0000000..8e9d1be --- /dev/null +++ b/client/src/hooks/use-toast.ts @@ -0,0 +1,40 @@ +import { useState, useCallback } from "react"; + +type ToastVariant = "default" | "destructive" | "success"; + +interface Toast { + id: string; + title?: string; + description?: string; + variant?: ToastVariant; +} + +let listeners: Array<(toasts: Toast[]) => void> = []; +let toastList: Toast[] = []; + +function notify() { + listeners.forEach((l) => l([...toastList])); +} + +export function toast(options: Omit) { + const id = Math.random().toString(36).slice(2); + toastList = [...toastList, { id, ...options }]; + notify(); + setTimeout(() => { + toastList = toastList.filter((t) => t.id !== id); + notify(); + }, 4000); +} + +export function useToast() { + const [toasts, setToasts] = useState([]); + + const subscribe = useCallback(() => { + listeners.push(setToasts); + return () => { + listeners = listeners.filter((l) => l !== setToasts); + }; + }, []); + + return { toasts, toast, subscribe }; +}