import type { ToastProps } from '@blueprintjs/core'; import { Classes, OverlayToaster, Position, Spinner } from '@blueprintjs/core'; import type { ReactNode } from 'react'; import { createContext, useContext, useMemo, useRef } from 'react'; interface ToasterContextProps { toaster: OverlayToaster | null; showLoading: (options: ToastProps) => () => void; showAsyncLoading: (options: ToastProps) => Promise<() => void>; show: (options: ToastProps) => void; } const ToasterContext = createContext(null); export function useToaster() { const context = useContext(ToasterContext); if (!context) { throw new Error('Toaster context was not found'); } return context; } interface ToasterProviderProps { children: ReactNode; } export function ToasterProvider({ children }: ToasterProviderProps) { const toasterRef = useRef(null); const toaster = useMemo(() => { function show(options: ToastProps) { toasterRef.current?.show(options); } function showLoading(options: ToastProps) { const { message, ...otherProps } = options; const toastKey = toasterRef.current?.show({ message: (
{message}
), timeout: 0, ...otherProps, }); function dismiss() { if (toastKey) { toasterRef.current?.dismiss(toastKey); } } return dismiss; } function showAsyncLoading(options: ToastProps) { return new Promise<() => void>((resolve) => { const hideLoading = showLoading(options); setTimeout(() => { resolve(hideLoading); }, 100); }); } return { toaster: toasterRef.current, showLoading, showAsyncLoading, show }; }, []); return ( <> {children} ); }