The Node.js® Website
at main 1.5 kB view raw
1import * as Toast from '@radix-ui/react-toast'; 2import type { 3 Dispatch, 4 FC, 5 PropsWithChildren, 6 ReactNode, 7 SetStateAction, 8} from 'react'; 9import { createContext, useEffect, useState } from 'react'; 10 11import Notification from '@/components/Common/Notification'; 12 13type NotificationContextType = { 14 message: string | ReactNode; 15 duration: number; 16} | null; 17 18type NotificationProps = { viewportClassName?: string }; 19 20const NotificationContext = createContext<NotificationContextType>(null); 21 22export const NotificationDispatch = createContext< 23 Dispatch<SetStateAction<NotificationContextType>> 24>(() => {}); 25 26export const NotificationProvider: FC<PropsWithChildren<NotificationProps>> = ({ 27 viewportClassName, 28 children, 29}) => { 30 const [notification, dispatch] = useState<NotificationContextType>(null); 31 32 useEffect(() => { 33 const timeout = setTimeout(() => dispatch(null), notification?.duration); 34 35 return () => clearTimeout(timeout); 36 }, [notification]); 37 38 return ( 39 <NotificationContext.Provider value={notification}> 40 <NotificationDispatch.Provider value={dispatch}> 41 <Toast.Provider> 42 {children} 43 44 <Toast.Viewport className={viewportClassName} /> 45 46 {notification && ( 47 <Notification duration={notification.duration}> 48 {notification.message} 49 </Notification> 50 )} 51 </Toast.Provider> 52 </NotificationDispatch.Provider> 53 </NotificationContext.Provider> 54 ); 55};