/** * ToastContext.tsx * Sistema minimalista de Toast Notifications. */ import { createContext, useContext, useState, useCallback, type ReactNode } from 'react'; import { createPortal } from 'react-dom'; import styles from './Toast.module.css'; type ToastType = 'info' | 'success' | 'error'; interface ToastData { id: string; message: string; type: ToastType; } interface ToastContextValue { addToast: (message: string, type?: ToastType) => void; } const ToastContext = createContext(null); export function ToastProvider({ children }: { children: ReactNode }) { const [toasts, setToasts] = useState([]); const addToast = useCallback((message: string, type: ToastType = 'info') => { const id = Math.random().toString(36).substring(2, 9); setToasts((prev) => [...prev, { id, message, type }]); // Remove automaticamente após 4 segundos setTimeout(() => { setToasts((prev) => prev.filter((t) => t.id !== id)); }, 4000); }, []); const removeToast = (id: string) => { setToasts((prev) => prev.filter((t) => t.id !== id)); }; return ( {children} {/* Portal renderiza os toasts no final do */} {createPortal(
{toasts.map((toast) => (
{toast.message}
))}
, document.body )}
); } export function useToast() { const ctx = useContext(ToastContext); if (!ctx) throw new Error('useToast deve ser usado dentro do ToastProvider'); return ctx; }