import React, { FC, ReactNode, RefObject, useEffect, useRef, useState } from 'react' import { appendVariantClasses, formatClassList, joinStrings } from '../../utils' type ToastTypes = { className?: string, dismissAfter?: number, variant?: string, title?: string, children: ReactNode, [other:string]: unknown } const TOAST: string = ` border-l-4 font-sans overflow-hidden p-4 relative rounded-sm shadow-md transition-all duration-300 ease-in-out ` const TIME: string = ` absolute bottom-0 float-right inline-block right-0 rounded-bottom ` const WRAPPER: string = ` fixed top-0 mt-10 mr-10 right-0 sm:max-w-md z-50 ` const CLOSE_ICON: string = ` absolute cursor-pointer fa-times fas focus:outline-none focus:shadow-outline m-2 right-0 text-2xl top-0 ` const RED_TIME: string = ` bg-bscs-red-800 ` const YELLOW_TIME: string = ` bg-bscs-yellow-800 ` const GREEN_TIME: string = ` bg-bscs-green-800 ` const INDIGO_TIME: string = ` bg-bscs-indigo-800 ` const RED: string = ` bg-bscs-red-100 border-bscs-red-800 text-bscs-red-800 ` const YELLOW: string = ` bg-bscs-yellow-200 border-bscs-yellow-800 text-bscs-yellow-800 ` const GREEN: string = ` bg-bscs-green-100 border-bscs-green-800 text-bscs-green-800 ` const INDIGO: string = ` bg-bscs-indigo-100 border-bscs-indigo-800 text-bscs-indigo-800 ` const RED_ICON: string = ` fa-exclamation-circle fas mr-3 text-base ` const YELLOW_ICON: string = ` fa-exclamation-triangle fas mr-3 text-base ` const GREEN_ICON: string = ` fa-check-circle fas mr-3 text-base ` const INDIGO_ICON: string = ` fa-info-circle fas mr-3 text-base ` const VARIANTS: Record = { 'green': GREEN, 'indigo': INDIGO, 'red': RED, 'yellow': YELLOW } const ICON_VARIANTS: Record = { 'green': GREEN_ICON, 'indigo': INDIGO_ICON, 'red': RED_ICON, 'yellow': YELLOW_ICON } const TIME_VARIANTS: Record = { 'green': GREEN_TIME, 'indigo': INDIGO_TIME, 'red': RED_TIME, 'yellow': YELLOW_TIME } const hideWrapper = (ref: RefObject | null): void => { setTimeout(() => { if (!ref || !ref.current) { return } ref.current.style.display = 'none' }, 300) } const Toast:FC = ({ className, children, dismissAfter=5, title, variant='indigo', ...other }: ToastTypes) => { const [show, setShow] = useState(true) const [timeElapsed, setTimeElapsed] = useState(0) const wrapperRef: RefObject | null = useRef(null) variant = variant.toLowerCase() const classList: string = formatClassList( appendVariantClasses(TOAST, VARIANTS, variant) ) const closeIconClassList: string = formatClassList(CLOSE_ICON) const iconClassList: string = formatClassList( appendVariantClasses('', ICON_VARIANTS, variant) ) const timeClassList: string = formatClassList( appendVariantClasses(TIME, TIME_VARIANTS, variant) ) const wrapperClassList: string = formatClassList(WRAPPER) useEffect(() => { const timer = setInterval(() => { setTimeElapsed(timeElapsed => { if ((timeElapsed + 10) / 1000 === dismissAfter) { clearInterval(timer) setShow(false) hideWrapper(wrapperRef) } return timeElapsed + 10 }) }, 10) return () => { clearInterval(timer) } // eslint-disable-next-line }, []) return (

{title}

{children}

) } export default Toast