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 && (
)}
)
})