| 12345678910111213141516171819202122232425262728293031323334353637383940414243 |
- type NotificationType = 'success' | 'error' | 'info' | 'loading';
- type Notification = {
- id: string;
- type: NotificationType;
- message: string;
- href?: string;
- durationMs?: number;
- };
- class NotificationsStore {
- items = $state<Notification[]>([]);
- push(n: Omit<Notification, 'id'>): string {
- const item: Notification = { ...n, id: crypto.randomUUID() };
- this.items = [...this.items, item];
- const duration = n.durationMs ?? 4000;
- if (duration > 0) setTimeout(() => this.dismiss(item.id), duration);
- return item.id;
- }
- /** Replace fields on an existing notification by id. If type changes away from
- * 'loading', schedules auto-dismiss using the updated durationMs (default 4000). */
- update(id: string, partial: Partial<Omit<Notification, 'id'>>) {
- this.items = this.items.map((n) => (n.id === id ? { ...n, ...partial } : n));
- if (partial.type && partial.type !== 'loading') {
- const item = this.items.find((n) => n.id === id);
- if (item) {
- const duration = item.durationMs ?? 4000;
- if (duration > 0) setTimeout(() => this.dismiss(id), duration);
- }
- }
- }
- dismiss(id: string) {
- this.items = this.items.filter((n) => n.id !== id);
- }
- }
- const notificationsStore = new NotificationsStore();
- export type { Notification, NotificationType };
- export { notificationsStore };
|