UNPKG

@backpackapp-io/react-native-toast

Version:

A toasting library for React Native. Built in features such as swipe to dismiss, multiple toasts, & no context power this library.

101 lines (90 loc) 2.52 kB
import { useEffect, useMemo } from 'react'; import { ActionType, dispatch, useStore } from './store'; import { toast } from './toast'; import { DefaultToastOptions, DismissReason, Toast, ToastPosition, } from './types'; export const useToaster = (toastOptions?: DefaultToastOptions) => { const { toasts, pausedAt } = useStore(toastOptions); useEffect(() => { if (pausedAt) { return; } const now = Date.now(); const timeouts = toasts.map((t) => { if (t.duration === Infinity) { return; } const durationLeft = (t.duration || 0) + t.pauseDuration - (now - t.createdAt); if (durationLeft < 0) { if (t.visible) { toast.dismiss(t.id, DismissReason.TIMEOUT); } return; } return setTimeout( () => toast.dismiss(t.id, DismissReason.TIMEOUT), durationLeft ); }); return () => { timeouts.forEach((timeout) => timeout && clearTimeout(timeout)); }; }, [toasts, pausedAt]); const handlers = useMemo( () => ({ startPause: () => { dispatch({ type: ActionType.START_PAUSE, time: Date.now(), }); }, endPause: () => { if (pausedAt) { dispatch({ type: ActionType.END_PAUSE, time: Date.now() }); } }, updateHeight: (toastId: string, height: number) => dispatch({ type: ActionType.UPDATE_TOAST, toast: { id: toastId, height }, }), calculateOffset: ( toast: Toast, opts?: { reverseOrder?: boolean; gutter?: number; defaultPosition?: ToastPosition; } ) => { const { reverseOrder = false, gutter = 8, defaultPosition, } = opts || {}; const relevantToasts = toasts.filter( (t) => (t.position || defaultPosition) === (toast.position || defaultPosition) && t.height ); const toastIndex = relevantToasts.findIndex((t) => t.id === toast.id); const toastsBefore = relevantToasts.filter( (toast, i) => i < toastIndex && toast.visible ).length; return relevantToasts .filter((t) => t.visible) .slice(...(reverseOrder ? [toastsBefore + 1] : [0, toastsBefore])) .reduce((acc, t) => acc + (t.height || 0) + gutter, 0); }, }), [toasts, pausedAt] ); return { toasts, handlers, }; };