Spaces:
Sleeping
Sleeping
| /** | |
| * Tiny toast store - a single Snackbar at a time. Replaces v1's | |
| * `views/components/modal.toast()` helper. | |
| * | |
| * Auto-hide is owned by the renderer (`<ToastBridge>`); the store is | |
| * just the queue + current message. | |
| */ | |
| import { create } from "zustand"; | |
| export type ToastSeverity = "info" | "success" | "warning" | "error"; | |
| interface Toast { | |
| id: number; | |
| message: string; | |
| severity: ToastSeverity; | |
| durationMs: number; | |
| } | |
| interface ToastState { | |
| current: Toast | null; | |
| push: ( | |
| message: string, | |
| severity?: ToastSeverity, | |
| durationMs?: number, | |
| ) => void; | |
| dismiss: () => void; | |
| } | |
| let nextId = 1; | |
| export const useToast = create<ToastState>((set) => ({ | |
| current: null, | |
| push(message, severity = "info", durationMs = 3000) { | |
| set({ current: { id: nextId++, message, severity, durationMs } }); | |
| }, | |
| dismiss() { | |
| set({ current: null }); | |
| }, | |
| })); | |
| /** Imperative shortcut for code paths that can't easily use the hook. */ | |
| export const toast = { | |
| info: (m: string): void => useToast.getState().push(m, "info"), | |
| success: (m: string): void => useToast.getState().push(m, "success"), | |
| warn: (m: string): void => useToast.getState().push(m, "warning"), | |
| error: (m: string): void => useToast.getState().push(m, "error", 4500), | |
| }; | |