2024-06-15 01:25:00 +09:00

101 lines
1.9 KiB
TypeScript

import { ToastBody } from "./Variant";
export interface ToastOption {
closeButton: boolean;
closeTimeout: number | null;
}
export const defaultToastOption: ToastOption = {
closeButton: true,
closeTimeout: 3000,
};
let index = 0;
export const toasts: Record<
`${number}`,
ToastBody & Partial<ToastOption> & { subscribers: (() => void)[] }
> = {};
let subscribers: (() => void)[] = [];
/**
* ====
* Controls
* ====
*/
export function subscribe(callback: () => void) {
subscribers.push(callback);
return () => {
subscribers = subscribers.filter((subscriber) => subscriber !== callback);
};
}
export function getSnapshot() {
return { ...toasts };
}
export function subscribeSingle(id: `${number}`) {
return (callback: () => void) => {
toasts[id].subscribers.push(callback);
return () => {
toasts[id].subscribers = toasts[id].subscribers.filter(
(subscriber) => subscriber !== callback,
);
};
};
}
export function getSingleSnapshot(id: `${number}`) {
return () => {
return {
...toasts[id],
};
};
}
export function notify() {
subscribers.forEach((subscriber) => subscriber());
}
export function notifySingle(id: `${number}`) {
toasts[id].subscribers.forEach((subscriber) => subscriber());
}
export function close(id: `${number}`) {
toasts[id] = {
...toasts[id],
life: "dead",
};
notifySingle(id);
}
export function update(
id: `${number}`,
toast: Partial<Omit<ToastBody, "life"> & Partial<ToastOption>>,
) {
toasts[id] = {
...toasts[id],
...toast,
};
notifySingle(id);
}
export function addToast(
toast: Omit<ToastBody, "life"> & Partial<ToastOption>,
) {
const id: `${number}` = `${index}`;
toasts[id] = {
...toast,
subscribers: [],
life: "born",
};
index += 1;
notify();
return {
update: (toast: Partial<Omit<ToastBody, "life"> & Partial<ToastOption>>) =>
update(id, toast),
close: () => close(id),
};
}