mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-31 04:38:11 +00:00
Replace Sonner with custom Sera UI-inspired toast system (#296)
* refactor(ui): replace Sonner with custom Sera UI-inspired toast system Replace the Sonner toast library with a custom implementation inspired by Sera UI's glassmorphism design. The new system uses an external store pattern with useSyncExternalStore for React integration, keeping the same toast.success()/error()/warning() API so all 172 call sites required only an import path change. Key changes: - New toast-store.ts: singleton store with identical API to Sonner - New toast.tsx: Sera UI-faithful Notification component with Framer Motion animations, frosted glass (backdrop-blur-xl), type gradient overlays, animated progress bar (green→blue→sky gradient), and hover:scale-105 - Removed sonner and next-themes dependencies - Rewired all 19 consumer files to import from the new store * fix(ui): resolve ESLint errors in toast system - Use const for listeners Set (prefer-const) - Initialize startRef with 0 instead of Date.now() to satisfy react-hooks/purity rule, set actual value inside useEffect
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { useSyncExternalStore } from 'react';
|
||||
|
||||
export type ToastType = 'success' | 'error' | 'warning' | 'info';
|
||||
|
||||
export interface Toast {
|
||||
id: string;
|
||||
type: ToastType;
|
||||
message: string;
|
||||
createdAt: number;
|
||||
}
|
||||
|
||||
let toasts: Toast[] = [];
|
||||
const listeners: Set<() => void> = new Set();
|
||||
let idCounter = 0;
|
||||
|
||||
function notify() {
|
||||
listeners.forEach((fn) => fn());
|
||||
}
|
||||
|
||||
function addToast(type: ToastType, message: string) {
|
||||
const id = `toast-${++idCounter}-${Date.now()}`;
|
||||
toasts = [...toasts, { id, type, message, createdAt: Date.now() }];
|
||||
notify();
|
||||
}
|
||||
|
||||
export function removeToast(id: string) {
|
||||
toasts = toasts.filter((t) => t.id !== id);
|
||||
notify();
|
||||
}
|
||||
|
||||
function subscribe(callback: () => void) {
|
||||
listeners.add(callback);
|
||||
return () => {
|
||||
listeners.delete(callback);
|
||||
};
|
||||
}
|
||||
|
||||
function getSnapshot() {
|
||||
return toasts;
|
||||
}
|
||||
|
||||
export function useToasts() {
|
||||
return useSyncExternalStore(subscribe, getSnapshot);
|
||||
}
|
||||
|
||||
export const toast = {
|
||||
success: (message: string) => addToast('success', message),
|
||||
error: (message: string) => addToast('error', message),
|
||||
warning: (message: string) => addToast('warning', message),
|
||||
info: (message: string) => addToast('info', message),
|
||||
};
|
||||
Reference in New Issue
Block a user