import type { Toast as ToastPropType } from './types' import { CheckCircleFilledIcon, ClearCircleFilledIcon } from '@standardnotes/icons' import { dismissToast } from './toastStore' import { ToastType } from './enums' import { ForwardedRef, forwardRef, RefObject, useEffect } from 'react' const prefersReducedMotion = () => { const mediaQuery = matchMedia('(prefers-reduced-motion: reduce)') return mediaQuery.matches } const colorForToastType = (type: ToastType) => { switch (type) { case ToastType.Success: return 'bg-success text-info-contrast md:text-success' case ToastType.Error: return 'bg-danger text-info-contrast md:text-danger' default: return 'bg-info text-info-contrast md:text-info' } } const iconForToastType = (type: ToastType) => { switch (type) { case ToastType.Success: return case ToastType.Error: return case ToastType.Progress: case ToastType.Loading: return
default: return null } } type Props = { toast: ToastPropType index: number } export const Toast = forwardRef(({ toast, index }: Props, ref: ForwardedRef) => { const icon = iconForToastType(toast.type) const hasActions = toast.actions && toast.actions.length > 0 const hasProgress = toast.type === ToastType.Progress && toast.progress !== undefined && toast.progress > -1 const shouldReduceMotion = prefersReducedMotion() const enterAnimation = shouldReduceMotion ? 'fade-in-animation' : 'slide-in-right-animation' const exitAnimation = shouldReduceMotion ? 'fade-out-animation' : 'slide-out-left-animation' const currentAnimation = toast.dismissed ? exitAnimation : enterAnimation useEffect(() => { if (!ref) { return } const element = (ref as RefObject).current if (element && toast.dismissed) { const { scrollHeight, style } = element requestAnimationFrame(() => { style.minHeight = 'initial' style.height = scrollHeight + 'px' style.transition = 'all 200ms' requestAnimationFrame(() => { style.height = '0' style.padding = '0' style.margin = '0' }) }) } }, [ref, toast.dismissed]) return (
{ if (toast.type !== ToastType.Loading && toast.type !== ToastType.Progress) { dismissToast(toast.id) } }} ref={ref} >
{icon ?
{icon}
: null}
{toast.message}
{hasActions && ( <> {toast.actions?.map((action, index) => ( ))} )}
{hasProgress && (
)}
) })