mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-21 16:26:41 +02:00
- Add toast module to @manacore/shared-ui (toastStore, ToastContainer) - Remove local toast implementations from: - calendar/web - chat/web - clock/web - contacts/web - picture/web - storage/web - Update all apps to import toast from shared-ui - Consistent toast API: toast.success(), toast.error(), toast.info() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
146 lines
3.3 KiB
TypeScript
146 lines
3.3 KiB
TypeScript
/**
|
|
* Toast Store - Centralized notification system using Svelte 5 runes
|
|
*
|
|
* Usage:
|
|
* ```ts
|
|
* import { toastStore } from '@manacore/shared-ui';
|
|
*
|
|
* // Show notifications
|
|
* toastStore.success('Saved successfully');
|
|
* toastStore.error('Something went wrong');
|
|
* toastStore.warning('Please check your input');
|
|
* toastStore.info('New update available');
|
|
*
|
|
* // Manual control
|
|
* const id = toastStore.show('Custom message', 'info', 5000);
|
|
* toastStore.dismiss(id);
|
|
* toastStore.dismissAll();
|
|
* ```
|
|
*/
|
|
|
|
export type ToastType = 'success' | 'error' | 'warning' | 'info';
|
|
|
|
export interface Toast {
|
|
id: string;
|
|
type: ToastType;
|
|
message: string;
|
|
duration: number;
|
|
}
|
|
|
|
// State
|
|
let toasts = $state<Toast[]>([]);
|
|
|
|
// Auto-incrementing ID with timestamp for uniqueness
|
|
let nextId = 0;
|
|
|
|
function generateId(): string {
|
|
return `toast-${++nextId}-${Date.now()}`;
|
|
}
|
|
|
|
export const toastStore = {
|
|
/**
|
|
* Get all active toasts (reactive)
|
|
*/
|
|
get toasts() {
|
|
return toasts;
|
|
},
|
|
|
|
/**
|
|
* Show a toast notification
|
|
* @param message - The message to display
|
|
* @param type - Toast type: 'success' | 'error' | 'warning' | 'info'
|
|
* @param duration - Duration in ms (0 = permanent, default: 4000)
|
|
* @returns The toast ID for manual dismissal
|
|
*/
|
|
show(message: string, type: ToastType = 'info', duration = 4000): string {
|
|
const id = generateId();
|
|
const toast: Toast = { id, type, message, duration };
|
|
|
|
toasts = [...toasts, toast];
|
|
|
|
// Auto-remove after duration (unless permanent)
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
this.dismiss(id);
|
|
}, duration);
|
|
}
|
|
|
|
return id;
|
|
},
|
|
|
|
/**
|
|
* Show a success toast (green)
|
|
* @param message - The message to display
|
|
* @param duration - Duration in ms (default: 4000)
|
|
*/
|
|
success(message: string, duration?: number): string {
|
|
return this.show(message, 'success', duration);
|
|
},
|
|
|
|
/**
|
|
* Show an error toast (red) - longer default duration
|
|
* @param message - The message to display
|
|
* @param duration - Duration in ms (default: 6000)
|
|
*/
|
|
error(message: string, duration = 6000): string {
|
|
return this.show(message, 'error', duration);
|
|
},
|
|
|
|
/**
|
|
* Show a warning toast (amber)
|
|
* @param message - The message to display
|
|
* @param duration - Duration in ms (default: 4000)
|
|
*/
|
|
warning(message: string, duration?: number): string {
|
|
return this.show(message, 'warning', duration);
|
|
},
|
|
|
|
/**
|
|
* Show an info toast (blue)
|
|
* @param message - The message to display
|
|
* @param duration - Duration in ms (default: 4000)
|
|
*/
|
|
info(message: string, duration?: number): string {
|
|
return this.show(message, 'info', duration);
|
|
},
|
|
|
|
/**
|
|
* Dismiss a specific toast by ID
|
|
* @param id - The toast ID to dismiss
|
|
*/
|
|
dismiss(id: string): void {
|
|
toasts = toasts.filter((t) => t.id !== id);
|
|
},
|
|
|
|
/**
|
|
* Dismiss all active toasts
|
|
*/
|
|
dismissAll(): void {
|
|
toasts = [];
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Helper function for API error handling
|
|
* Shows an error toast and returns the error message
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* try {
|
|
* await api.save(data);
|
|
* } catch (error) {
|
|
* handleApiError(error, 'Could not save data');
|
|
* }
|
|
* ```
|
|
*/
|
|
export function handleApiError(
|
|
error: unknown,
|
|
fallbackMessage = 'Ein Fehler ist aufgetreten'
|
|
): string {
|
|
const message = error instanceof Error ? error.message : fallbackMessage;
|
|
toastStore.error(message);
|
|
return message;
|
|
}
|
|
|
|
// Backwards compatible alias
|
|
export const toast = toastStore;
|