1
0
forked from baron/baron-sso
Files
baron-sso/adminfront/src/components/ui/use-toast.ts
2026-03-24 14:22:05 +09:00

67 lines
1.6 KiB
TypeScript

import * as React from "react";
type ToastType = "success" | "error" | "info";
interface Toast {
id: string;
message: string;
type: ToastType;
}
let subscribers: ((toasts: Toast[]) => void)[] = [];
let toasts: Toast[] = [];
const notify = () => {
for (const sub of subscribers) {
sub(toasts);
}
};
const toastBase = (message: string, type: ToastType = "success") => {
const id = Math.random().toString(36).substring(2, 9);
toasts = [...toasts, { id, message, type }];
notify();
setTimeout(() => {
toasts = toasts.filter((t) => t.id !== id);
notify();
}, 3000);
};
export const toast = Object.assign(toastBase, {
success: (message: string, options?: { description?: string }) => {
const finalMessage = options?.description
? `${message}
${options.description}`
: message;
toastBase(finalMessage, "success");
},
error: (message: string, options?: { description?: string }) => {
const finalMessage = options?.description
? `${message}
${options.description}`
: message;
toastBase(finalMessage, "error");
},
info: (message: string, options?: { description?: string }) => {
const finalMessage = options?.description
? `${message}
${options.description}`
: message;
toastBase(finalMessage, "info");
},
});
export const useToastState = () => {
const [state, setState] = React.useState<Toast[]>(toasts);
React.useEffect(() => {
subscribers.push(setState);
return () => {
subscribers = subscribers.filter((sub) => sub !== setState);
};
}, []);
return state;
};