Spaces:
Sleeping
Sleeping
| import React, { createContext, useContext, useMemo, useState, useCallback } from 'react'; | |
| const ToastCtx = createContext(null); | |
| export function ToastProvider({ children }) { | |
| const [toasts, setToasts] = useState([]); | |
| const push = useCallback((msg, tone = 'good', ttl = 3200) => { | |
| const id = Math.random().toString(36).slice(2); | |
| setToasts(t => [...t, { id, msg, tone }]); | |
| setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), ttl); | |
| }, []); | |
| const api = useMemo(() => ({ push }), [push]); | |
| return ( | |
| <ToastCtx.Provider value={api}> | |
| {children} | |
| <div className="toast-wrap"> | |
| {toasts.map(t => ( | |
| <div key={t.id} className={`toast ${t.tone}`}> | |
| {t.msg} | |
| </div> | |
| ))} | |
| </div> | |
| </ToastCtx.Provider> | |
| ); | |
| } | |
| export function useToasts() { | |
| const ctx = useContext(ToastCtx); | |
| if (!ctx) throw new Error('useToasts must be used inside <ToastProvider>'); | |
| return ctx; | |
| } | |