marionette / src /shared /useToast.ts
Thibaud Frère
feat: initial marionette v2 release
44aec57
/**
* 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),
};