{"version":3,"file":"static/chunks/3999-9d8128757d0e9e11.js","mappings":"0KAAgXA,EAAxH,WAAgB,QAAAC,EAAAC,EAAAC,EAAA,EAAAC,EAAA,GAAAC,EAAAC,UAAAC,MAAA,CAAwCJ,EAAAE,EAAIF,IAAA,CAAAF,EAAAK,SAAA,CAAAH,EAAA,GAAAD,CAAAA,EAAAM,SAApTA,EAAAP,CAAA,EAAc,IAAAC,EAAAC,EAAAC,EAAA,GAAa,oBAAAH,GAAA,iBAAAA,EAAAG,GAAAH,OAA+C,oBAAAA,GAAA,GAAAQ,MAAAC,OAAA,CAAAT,GAAA,CAAgD,IAAAI,EAAAJ,EAAAM,MAAA,CAAe,IAAAL,EAAA,EAAQA,EAAAG,EAAIH,IAAAD,CAAA,CAAAC,EAAA,EAAAC,CAAAA,EAAAK,EAAAP,CAAA,CAAAC,EAAA,IAAAE,CAAAA,GAAAA,CAAAA,GAAA,KAAAA,GAAAD,CAAAA,CAAA,MAA0C,IAAAA,KAAAF,EAAAA,CAAA,CAAAE,EAAA,EAAAC,CAAAA,GAAAA,CAAAA,GAAA,KAAAA,GAAAD,CAAAA,EAAyC,OAAAC,CAAA,EAA4EH,EAAA,GAAAG,CAAAA,GAAAA,CAAAA,GAAA,KAAAA,GAAAF,CAAAA,EAAmD,OAAAE,CAAA","sources":["webpack://_N_E/./node_modules/react-toastify/node_modules/clsx/dist/clsx.mjs","webpack://_N_E/../src/utils/propValidator.ts","webpack://_N_E/../src/utils/collapseToast.ts","webpack://_N_E/../src/utils/cssTransition.tsx","webpack://_N_E/../src/utils/mapper.ts","webpack://_N_E/../src/core/store.ts","webpack://_N_E/../src/hooks/useToastContainer.ts","webpack://_N_E/../src/core/containerObserver.ts","webpack://_N_E/../src/hooks/useToast.ts","webpack://_N_E/../src/components/ProgressBar.tsx","webpack://_N_E/../src/core/genToastId.ts","webpack://_N_E/../src/core/toast.ts","webpack://_N_E/../src/hooks/useIsomorphicLayoutEffect.ts","webpack://_N_E/../src/components/Icons.tsx","webpack://_N_E/../src/components/Toast.tsx","webpack://_N_E/../src/components/CloseButton.tsx","webpack://_N_E/../src/components/Transitions.tsx","webpack://_N_E/../src/components/ToastContainer.tsx"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t\n typeof v === 'number' && !isNaN(v);\n\nexport const isStr = (v: any): v is String => typeof v === 'string';\n\nexport const isFn = (v: any): v is Function => typeof v === 'function';\n\nexport const isId = (v: unknown): v is Id => isStr(v) || isNum(v);\n\nexport const parseClassName = (v: any) => (isStr(v) || isFn(v) ? v : null);\n\nexport const getAutoCloseDelay = (\n toastAutoClose?: false | number,\n containerAutoClose?: false | number\n) =>\n toastAutoClose === false || (isNum(toastAutoClose) && toastAutoClose > 0)\n ? toastAutoClose\n : containerAutoClose;\n\nexport const canBeRendered = (content: T): boolean =>\n isValidElement(content) || isStr(content) || isFn(content) || isNum(content);\n","import { Default } from './constant';\n\n/**\n * Used to collapse toast after exit animation\n */\nexport function collapseToast(\n node: HTMLElement,\n done: () => void,\n duration = Default.COLLAPSE_DURATION\n) {\n const { scrollHeight, style } = node;\n\n requestAnimationFrame(() => {\n style.minHeight = 'initial';\n style.height = scrollHeight + 'px';\n style.transition = `all ${duration}ms`;\n\n requestAnimationFrame(() => {\n style.height = '0';\n style.padding = '0';\n style.margin = '0';\n setTimeout(done, duration as number);\n });\n });\n}\n","import React, { useEffect, useLayoutEffect, useRef } from 'react';\nimport { collapseToast } from './collapseToast';\nimport { Default } from './constant';\n\nimport { ToastTransitionProps } from '../types';\n\nexport interface CSSTransitionProps {\n /**\n * Css class to apply when toast enter\n */\n enter: string;\n\n /**\n * Css class to apply when toast leave\n */\n exit: string;\n\n /**\n * Append current toast position to the classname.\n * If multiple classes are provided, only the last one will get the position\n * For instance `myclass--top-center`...\n * `Default: false`\n */\n appendPosition?: boolean;\n\n /**\n * Collapse toast smoothly when exit animation end\n * `Default: true`\n */\n collapse?: boolean;\n\n /**\n * Collapse transition duration\n * `Default: 300`\n */\n collapseDuration?: number;\n}\n\nconst enum AnimationStep {\n Enter,\n Exit\n}\n\n/**\n * Css animation that just work.\n * You could use animate.css for instance\n *\n *\n * ```\n * cssTransition({\n * enter: \"animate__animated animate__bounceIn\",\n * exit: \"animate__animated animate__bounceOut\"\n * })\n * ```\n *\n */\nexport function cssTransition({\n enter,\n exit,\n appendPosition = false,\n collapse = true,\n collapseDuration = Default.COLLAPSE_DURATION\n}: CSSTransitionProps) {\n return function ToastTransition({\n children,\n position,\n preventExitTransition,\n done,\n nodeRef,\n isIn,\n playToast\n }: ToastTransitionProps) {\n const enterClassName = appendPosition ? `${enter}--${position}` : enter;\n const exitClassName = appendPosition ? `${exit}--${position}` : exit;\n const animationStep = useRef(AnimationStep.Enter);\n\n useLayoutEffect(() => {\n const node = nodeRef.current!;\n const classToToken = enterClassName.split(' ');\n\n const onEntered = (e: AnimationEvent) => {\n if (e.target !== nodeRef.current) return;\n\n playToast();\n node.removeEventListener('animationend', onEntered);\n node.removeEventListener('animationcancel', onEntered);\n if (\n animationStep.current === AnimationStep.Enter &&\n e.type !== 'animationcancel'\n ) {\n node.classList.remove(...classToToken);\n }\n };\n\n const onEnter = () => {\n node.classList.add(...classToToken);\n node.addEventListener('animationend', onEntered);\n node.addEventListener('animationcancel', onEntered);\n };\n\n onEnter();\n }, []);\n\n useEffect(() => {\n const node = nodeRef.current!;\n\n const onExited = () => {\n node.removeEventListener('animationend', onExited);\n collapse ? collapseToast(node, done, collapseDuration) : done();\n };\n\n const onExit = () => {\n animationStep.current = AnimationStep.Exit;\n node.className += ` ${exitClassName}`;\n node.addEventListener('animationend', onExited);\n };\n\n if (!isIn) preventExitTransition ? onExited() : onExit();\n }, [isIn]);\n\n return <>{children};\n };\n}\n","import { Toast, ToastItem, ToastItemStatus } from '../types';\n\nexport function toToastItem(toast: Toast, status: ToastItemStatus): ToastItem {\n return toast != null\n ? {\n content: toast.content,\n containerId: toast.props.containerId,\n id: toast.props.toastId,\n theme: toast.props.theme,\n type: toast.props.type,\n data: toast.props.data || {},\n isLoading: toast.props.isLoading,\n icon: toast.props.icon,\n status\n }\n : // monkey patch for now\n ({} as ToastItem);\n}\n","import {\n Id,\n NotValidatedToastProps,\n OnChangeCallback,\n ToastContainerProps,\n ToastContent,\n ToastItem,\n ToastOptions\n} from '../types';\nimport { Default, canBeRendered, isId } from '../utils';\nimport {\n ContainerObserver,\n createContainerObserver\n} from './containerObserver';\n\ninterface EnqueuedToast {\n content: ToastContent;\n options: NotValidatedToastProps;\n}\n\ninterface ClearWaitingQueueParams {\n containerId?: Id;\n}\n\ninterface RemoveParams {\n id?: Id;\n containerId: Id;\n}\n\nconst containers = new Map();\nlet renderQueue: EnqueuedToast[] = [];\nconst listeners = new Set();\n\nconst dispatchChanges = (data: ToastItem) => listeners.forEach(cb => cb(data));\n\nconst hasContainers = () => containers.size > 0;\n\nfunction flushRenderQueue() {\n renderQueue.forEach(v => pushToast(v.content, v.options));\n renderQueue = [];\n}\n\nexport const getToast = (id: Id, { containerId }: ToastOptions) =>\n containers.get(containerId || Default.CONTAINER_ID)?.toasts.get(id);\n\nexport function isToastActive(id: Id, containerId?: Id) {\n if (containerId) return !!containers.get(containerId)?.isToastActive(id);\n\n let isActive = false;\n containers.forEach(c => {\n if (c.isToastActive(id)) isActive = true;\n });\n\n return isActive;\n}\n\nexport function removeToast(params?: Id | RemoveParams) {\n if (!hasContainers()) {\n renderQueue = renderQueue.filter(\n v => params != null && v.options.toastId !== params\n );\n return;\n }\n\n if (params == null || isId(params)) {\n containers.forEach(c => {\n c.removeToast(params as Id);\n });\n } else if (params && ('containerId' in params || 'id' in params)) {\n const container = containers.get(params.containerId);\n container\n ? container.removeToast(params.id)\n : containers.forEach(c => {\n c.removeToast(params.id);\n });\n }\n}\n\nexport function clearWaitingQueue(p: ClearWaitingQueueParams = {}) {\n containers.forEach(c => {\n if (c.props.limit && (!p.containerId || c.id === p.containerId)) {\n c.clearQueue();\n }\n });\n}\n\nexport function pushToast(\n content: ToastContent,\n options: NotValidatedToastProps\n) {\n if (!canBeRendered(content)) return;\n if (!hasContainers()) renderQueue.push({ content, options });\n\n containers.forEach(c => {\n c.buildToast(content, options);\n });\n}\n\ninterface ToggleToastParams {\n id?: Id;\n containerId?: Id;\n}\n\ntype RegisterToggleOpts = {\n id: Id;\n containerId?: Id;\n fn: (v: boolean) => void;\n};\n\nexport function registerToggle(opts: RegisterToggleOpts) {\n containers\n .get(opts.containerId || Default.CONTAINER_ID)\n ?.setToggle(opts.id, opts.fn);\n}\n\nexport function toggleToast(v: boolean, opt?: ToggleToastParams) {\n containers.forEach(c => {\n if (opt == null || !opt?.containerId) {\n c.toggle(v, opt?.id);\n } else if (opt?.containerId === c.id) {\n c.toggle(v, opt?.id);\n }\n });\n}\n\nexport function registerContainer(props: ToastContainerProps) {\n const id = props.containerId || Default.CONTAINER_ID;\n return {\n subscribe(notify: () => void) {\n const container = createContainerObserver(id, props, dispatchChanges);\n\n containers.set(id, container);\n const unobserve = container.observe(notify);\n flushRenderQueue();\n\n return () => {\n unobserve();\n containers.delete(id);\n };\n },\n setProps(p: ToastContainerProps) {\n containers.get(id)?.setProps(p);\n },\n getSnapshot() {\n return containers.get(id)?.getSnapshot();\n }\n };\n}\n\nexport function onChange(cb: OnChangeCallback) {\n listeners.add(cb);\n\n return () => {\n listeners.delete(cb);\n };\n}\n","import { useRef, useSyncExternalStore } from 'react';\nimport { isToastActive, registerContainer } from '../core/store';\nimport { Toast, ToastContainerProps, ToastPosition } from '../types';\n\nexport function useToastContainer(props: ToastContainerProps) {\n const { subscribe, getSnapshot, setProps } = useRef(\n registerContainer(props)\n ).current;\n setProps(props);\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n function getToastToRender(\n cb: (position: ToastPosition, toastList: Toast[]) => T\n ) {\n if (!snapshot) return [];\n\n const toRender = new Map();\n\n snapshot.forEach(toast => {\n const { position } = toast.props;\n toRender.has(position) || toRender.set(position, []);\n toRender.get(position)!.push(toast);\n });\n\n return Array.from(toRender, p => cb(p[0], p[1]));\n }\n\n return {\n getToastToRender,\n isToastActive,\n count: snapshot?.length\n };\n}\n","import { ReactElement, cloneElement, isValidElement } from 'react';\nimport {\n Id,\n NotValidatedToastProps,\n OnChangeCallback,\n Toast,\n ToastContainerProps,\n ToastContent,\n ToastProps\n} from '../types';\nimport {\n canBeRendered,\n getAutoCloseDelay,\n isFn,\n isNum,\n isStr,\n parseClassName,\n toToastItem\n} from '../utils';\n\ninterface QueuedToast {\n content: ToastContent;\n props: ToastProps;\n staleId?: Id;\n}\n\ntype Notify = () => void;\n\ninterface ActiveToast {\n content: ToastContent;\n props: ToastProps;\n staleId?: Id;\n}\n\nexport type ContainerObserver = ReturnType;\n\nexport function createContainerObserver(\n id: Id,\n containerProps: ToastContainerProps,\n dispatchChanges: OnChangeCallback\n) {\n let toastKey = 1;\n let toastCount = 0;\n let queue: QueuedToast[] = [];\n let activeToasts: Id[] = [];\n let snapshot: Toast[] = [];\n let props = containerProps;\n const toasts = new Map();\n const listeners = new Set();\n\n const observe = (notify: Notify) => {\n listeners.add(notify);\n return () => listeners.delete(notify);\n };\n\n const notify = () => {\n snapshot = Array.from(toasts.values());\n listeners.forEach(cb => cb());\n };\n\n const shouldIgnoreToast = ({\n containerId,\n toastId,\n updateId\n }: NotValidatedToastProps) => {\n const containerMismatch = containerId ? containerId !== id : id !== 1;\n const isDuplicate = toasts.has(toastId) && updateId == null;\n\n return containerMismatch || isDuplicate;\n };\n\n const toggle = (v: boolean, id?: Id) => {\n toasts.forEach(t => {\n if (id == null || id === t.props.toastId) isFn(t.toggle) && t.toggle(v);\n });\n };\n\n const removeToast = (id?: Id) => {\n activeToasts = id == null ? [] : activeToasts.filter(v => v !== id);\n notify();\n };\n\n const clearQueue = () => {\n toastCount -= queue.length;\n queue = [];\n };\n\n const addActiveToast = (toast: ActiveToast) => {\n const { toastId, onOpen, updateId, children } = toast.props;\n const isNew = updateId == null;\n\n if (toast.staleId) toasts.delete(toast.staleId);\n\n toasts.set(toastId, toast);\n activeToasts = [...activeToasts, toast.props.toastId].filter(\n v => v !== toast.staleId\n );\n notify();\n dispatchChanges(toToastItem(toast, isNew ? 'added' : 'updated'));\n\n if (isNew && isFn(onOpen))\n onOpen(isValidElement(children) && children.props);\n };\n\n const buildToast = (\n content: ToastContent,\n options: NotValidatedToastProps\n ) => {\n if (shouldIgnoreToast(options)) return;\n\n const { toastId, updateId, data, staleId, delay } = options;\n const closeToast = () => {\n removeToast(toastId);\n };\n\n const isNotAnUpdate = updateId == null;\n\n if (isNotAnUpdate) toastCount++;\n\n const toastProps = {\n ...props,\n style: props.toastStyle,\n key: toastKey++,\n ...Object.fromEntries(\n Object.entries(options).filter(([_, v]) => v != null)\n ),\n toastId,\n updateId,\n data,\n closeToast,\n isIn: false,\n className: parseClassName(options.className || props.toastClassName),\n bodyClassName: parseClassName(\n options.bodyClassName || props.bodyClassName\n ),\n progressClassName: parseClassName(\n options.progressClassName || props.progressClassName\n ),\n autoClose: options.isLoading\n ? false\n : getAutoCloseDelay(options.autoClose, props.autoClose),\n deleteToast() {\n const toastToRemove = toasts.get(toastId)!;\n const { onClose, children } = toastToRemove.props;\n if (isFn(onClose)) onClose(isValidElement(children) && children.props);\n\n dispatchChanges(toToastItem(toastToRemove, 'removed'));\n toasts.delete(toastId);\n\n toastCount--;\n if (toastCount < 0) toastCount = 0;\n\n if (queue.length > 0) {\n addActiveToast(queue.shift() as ActiveToast);\n return;\n }\n\n notify();\n }\n } as ToastProps;\n\n toastProps.closeButton = props.closeButton;\n\n if (options.closeButton === false || canBeRendered(options.closeButton)) {\n toastProps.closeButton = options.closeButton;\n } else if (options.closeButton === true) {\n toastProps.closeButton = canBeRendered(props.closeButton)\n ? props.closeButton\n : true;\n }\n\n let toastContent = content;\n\n if (isValidElement(content) && !isStr(content.type)) {\n toastContent = cloneElement(content as ReactElement, {\n closeToast,\n toastProps,\n data\n });\n } else if (isFn(content)) {\n toastContent = content({ closeToast, toastProps, data: data as TData });\n }\n\n const activeToast = {\n content: toastContent,\n props: toastProps,\n staleId\n };\n\n // not handling limit + delay by design. Waiting for user feedback first\n if (\n props.limit &&\n props.limit > 0 &&\n toastCount > props.limit &&\n isNotAnUpdate\n ) {\n queue.push(activeToast);\n } else if (isNum(delay)) {\n setTimeout(() => {\n addActiveToast(activeToast);\n }, delay);\n } else {\n addActiveToast(activeToast);\n }\n };\n\n return {\n id,\n props,\n observe,\n toggle,\n removeToast,\n toasts,\n clearQueue,\n buildToast,\n setProps(p: ToastContainerProps) {\n props = p;\n },\n setToggle: (id: Id, fn: (v: boolean) => void) => {\n toasts.get(id)!.toggle = fn;\n },\n isToastActive: (id: Id) => activeToasts.some(v => v === id),\n getSnapshot: () => (props.newestOnTop ? snapshot.reverse() : snapshot)\n };\n}\n","import { DOMAttributes, useEffect, useRef, useState } from 'react';\n\nimport { ToastProps } from '../types';\nimport { Default, Direction } from '../utils';\nimport { registerToggle } from '../core/store';\n\ninterface Draggable {\n start: number;\n delta: number;\n removalDistance: number;\n canCloseOnClick: boolean;\n canDrag: boolean;\n didMove: boolean;\n}\n\nexport function useToast(props: ToastProps) {\n const [isRunning, setIsRunning] = useState(false);\n const [preventExitTransition, setPreventExitTransition] = useState(false);\n const toastRef = useRef(null);\n const drag = useRef({\n start: 0,\n delta: 0,\n removalDistance: 0,\n canCloseOnClick: true,\n canDrag: false,\n didMove: false\n }).current;\n const { autoClose, pauseOnHover, closeToast, onClick, closeOnClick } = props;\n\n registerToggle({\n id: props.toastId,\n containerId: props.containerId,\n fn: setIsRunning\n });\n\n useEffect(() => {\n if (props.pauseOnFocusLoss) {\n bindFocusEvents();\n\n return () => {\n unbindFocusEvents();\n };\n }\n }, [props.pauseOnFocusLoss]);\n\n function bindFocusEvents() {\n if (!document.hasFocus()) pauseToast();\n\n window.addEventListener('focus', playToast);\n window.addEventListener('blur', pauseToast);\n }\n\n function unbindFocusEvents() {\n window.removeEventListener('focus', playToast);\n window.removeEventListener('blur', pauseToast);\n }\n\n function onDragStart(e: React.PointerEvent) {\n if (props.draggable === true || props.draggable === e.pointerType) {\n bindDragEvents();\n const toast = toastRef.current!;\n drag.canCloseOnClick = true;\n drag.canDrag = true;\n toast.style.transition = 'none';\n\n if (props.draggableDirection === Direction.X) {\n drag.start = e.clientX;\n drag.removalDistance =\n toast.offsetWidth * (props.draggablePercent / 100);\n } else {\n drag.start = e.clientY;\n drag.removalDistance =\n (toast.offsetHeight *\n (props.draggablePercent === Default.DRAGGABLE_PERCENT\n ? props.draggablePercent * 1.5\n : props.draggablePercent)) /\n 100;\n }\n }\n }\n\n function onDragTransitionEnd(e: React.PointerEvent) {\n const { top, bottom, left, right } =\n toastRef.current!.getBoundingClientRect();\n\n if (\n e.nativeEvent.type !== 'touchend' &&\n props.pauseOnHover &&\n e.clientX >= left &&\n e.clientX <= right &&\n e.clientY >= top &&\n e.clientY <= bottom\n ) {\n pauseToast();\n } else {\n playToast();\n }\n }\n\n function playToast() {\n setIsRunning(true);\n }\n\n function pauseToast() {\n setIsRunning(false);\n }\n\n function bindDragEvents() {\n drag.didMove = false;\n document.addEventListener('pointermove', onDragMove);\n document.addEventListener('pointerup', onDragEnd);\n }\n\n function unbindDragEvents() {\n document.removeEventListener('pointermove', onDragMove);\n document.removeEventListener('pointerup', onDragEnd);\n }\n\n function onDragMove(e: PointerEvent) {\n const toast = toastRef.current!;\n if (drag.canDrag && toast) {\n drag.didMove = true;\n if (isRunning) pauseToast();\n if (props.draggableDirection === Direction.X) {\n drag.delta = e.clientX - drag.start;\n } else {\n drag.delta = e.clientY - drag.start;\n }\n\n // prevent false positive during a toast click\n if (drag.start !== e.clientX) drag.canCloseOnClick = false;\n const translate =\n props.draggableDirection === 'x'\n ? `${drag.delta}px, var(--y)`\n : `0, calc(${drag.delta}px + var(--y))`;\n toast.style.transform = `translate3d(${translate},0)`;\n toast.style.opacity = `${\n 1 - Math.abs(drag.delta / drag.removalDistance)\n }`;\n }\n }\n\n function onDragEnd() {\n unbindDragEvents();\n const toast = toastRef.current!;\n if (drag.canDrag && drag.didMove && toast) {\n drag.canDrag = false;\n if (Math.abs(drag.delta) > drag.removalDistance) {\n setPreventExitTransition(true);\n props.closeToast();\n props.collapseAll();\n return;\n }\n\n toast.style.transition = 'transform 0.2s, opacity 0.2s';\n toast.style.removeProperty('transform');\n toast.style.removeProperty('opacity');\n }\n }\n\n const eventHandlers: DOMAttributes = {\n onPointerDown: onDragStart,\n onPointerUp: onDragTransitionEnd\n };\n\n if (autoClose && pauseOnHover) {\n eventHandlers.onMouseEnter = pauseToast;\n\n // progress control is delegated to the container\n if (!props.stacked) eventHandlers.onMouseLeave = playToast;\n }\n\n // prevent toast from closing when user drags the toast\n if (closeOnClick) {\n eventHandlers.onClick = (e: React.MouseEvent) => {\n onClick && onClick(e);\n drag.canCloseOnClick && closeToast();\n };\n }\n\n return {\n playToast,\n pauseToast,\n isRunning,\n preventExitTransition,\n toastRef,\n eventHandlers\n };\n}\n","import React from 'react';\nimport cx from 'clsx';\n\nimport { Default, isFn, Type } from './../utils';\nimport { TypeOptions, ToastClassName, Theme } from '../types';\n\nexport interface ProgressBarProps {\n /**\n * The animation delay which determine when to close the toast\n */\n delay: number;\n\n /**\n * Whether or not the animation is running or paused\n */\n isRunning: boolean;\n\n /**\n * Func to close the current toast\n */\n closeToast: () => void;\n\n /**\n * Optional type : info, success ...\n */\n type?: TypeOptions;\n\n /**\n * The theme that is currently used\n */\n theme: Theme;\n\n /**\n * Hide or not the progress bar\n */\n hide?: boolean;\n\n /**\n * Optional className\n */\n className?: ToastClassName;\n\n /**\n * Optional inline style\n */\n style?: React.CSSProperties;\n\n /**\n * Tell wether or not controlled progress bar is used\n */\n controlledProgress?: boolean;\n\n /**\n * Controlled progress value\n */\n progress?: number | string;\n\n /**\n * Support rtl content\n */\n rtl?: boolean;\n\n /**\n * Tell if the component is visible on screen or not\n */\n isIn?: boolean;\n}\n\nexport function ProgressBar({\n delay,\n isRunning,\n closeToast,\n type = Type.DEFAULT,\n hide,\n className,\n style: userStyle,\n controlledProgress,\n progress,\n rtl,\n isIn,\n theme\n}: ProgressBarProps) {\n const isHidden = hide || (controlledProgress && progress === 0);\n const style: React.CSSProperties = {\n ...userStyle,\n animationDuration: `${delay}ms`,\n animationPlayState: isRunning ? 'running' : 'paused'\n };\n\n if (controlledProgress) style.transform = `scaleX(${progress})`;\n const defaultClassName = cx(\n `${Default.CSS_NAMESPACE}__progress-bar`,\n controlledProgress\n ? `${Default.CSS_NAMESPACE}__progress-bar--controlled`\n : `${Default.CSS_NAMESPACE}__progress-bar--animated`,\n `${Default.CSS_NAMESPACE}__progress-bar-theme--${theme}`,\n `${Default.CSS_NAMESPACE}__progress-bar--${type}`,\n {\n [`${Default.CSS_NAMESPACE}__progress-bar--rtl`]: rtl\n }\n );\n const classNames = isFn(className)\n ? className({\n rtl,\n type,\n defaultClassName\n })\n : cx(defaultClassName, className);\n\n // 🧐 controlledProgress is derived from progress\n // so if controlledProgress is set\n // it means that this is also the case for progress\n const animationEvent = {\n [controlledProgress && (progress as number)! >= 1\n ? 'onTransitionEnd'\n : 'onAnimationEnd']:\n controlledProgress && (progress as number)! < 1\n ? null\n : () => {\n isIn && closeToast();\n }\n };\n\n // TODO: add aria-valuenow, aria-valuemax, aria-valuemin\n\n return (\n \n \n \n \n );\n}\n","let TOAST_ID = 1;\n\nexport const genToastId = () => `${TOAST_ID++}`;\n","import {\n Id,\n IdOpts,\n NotValidatedToastProps,\n ToastContent,\n ToastOptions,\n ToastProps,\n TypeOptions,\n UpdateOptions\n} from '../types';\nimport { Type, isFn, isNum, isStr } from '../utils';\nimport { genToastId } from './genToastId';\nimport {\n clearWaitingQueue,\n getToast,\n isToastActive,\n onChange,\n pushToast,\n removeToast,\n toggleToast\n} from './store';\n\n/**\n * Generate a toastId or use the one provided\n */\nfunction getToastId(options?: ToastOptions) {\n return options && (isStr(options.toastId) || isNum(options.toastId))\n ? options.toastId\n : genToastId();\n}\n\n/**\n * If the container is not mounted, the toast is enqueued\n */\nfunction dispatchToast(\n content: ToastContent,\n options: NotValidatedToastProps\n): Id {\n pushToast(content, options);\n return options.toastId;\n}\n\n/**\n * Merge provided options with the defaults settings and generate the toastId\n */\nfunction mergeOptions(type: string, options?: ToastOptions) {\n return {\n ...options,\n type: (options && options.type) || type,\n toastId: getToastId(options)\n } as NotValidatedToastProps;\n}\n\nfunction createToastByType(type: string) {\n return (\n content: ToastContent,\n options?: ToastOptions\n ) => dispatchToast(content, mergeOptions(type, options));\n}\n\nfunction toast(\n content: ToastContent,\n options?: ToastOptions\n) {\n return dispatchToast(content, mergeOptions(Type.DEFAULT, options));\n}\n\ntoast.loading = (\n content: ToastContent,\n options?: ToastOptions\n) =>\n dispatchToast(\n content,\n mergeOptions(Type.DEFAULT, {\n isLoading: true,\n autoClose: false,\n closeOnClick: false,\n closeButton: false,\n draggable: false,\n ...options\n })\n );\n\nexport interface ToastPromiseParams<\n TData = unknown,\n TError = unknown,\n TPending = unknown\n> {\n pending?: string | UpdateOptions;\n success?: string | UpdateOptions;\n error?: string | UpdateOptions;\n}\n\nfunction handlePromise(\n promise: Promise | (() => Promise),\n { pending, error, success }: ToastPromiseParams,\n options?: ToastOptions\n) {\n let id: Id;\n\n if (pending) {\n id = isStr(pending)\n ? toast.loading(pending, options)\n : toast.loading(pending.render, {\n ...options,\n ...(pending as ToastOptions)\n } as ToastOptions);\n }\n\n const resetParams = {\n isLoading: null,\n autoClose: null,\n closeOnClick: null,\n closeButton: null,\n draggable: null\n };\n\n const resolver = (\n type: TypeOptions,\n input: string | UpdateOptions | undefined,\n result: T\n ) => {\n // Remove the toast if the input has not been provided. This prevents the toast from hanging\n // in the pending state if a success/error toast has not been provided.\n if (input == null) {\n toast.dismiss(id);\n return;\n }\n\n const baseParams = {\n type,\n ...resetParams,\n ...options,\n data: result\n };\n const params = isStr(input) ? { render: input } : input;\n\n // if the id is set we know that it's an update\n if (id) {\n toast.update(id, {\n ...baseParams,\n ...params\n } as UpdateOptions);\n } else {\n // using toast.promise without loading\n toast(params!.render, {\n ...baseParams,\n ...params\n } as ToastOptions);\n }\n\n return result;\n };\n\n const p = isFn(promise) ? promise() : promise;\n\n //call the resolvers only when needed\n p.then(result => resolver('success', success, result)).catch(err =>\n resolver('error', error, err)\n );\n\n return p;\n}\n\n/**\n * Supply a promise or a function that return a promise and the notification will be updated if it resolves or fails.\n * When the promise is pending a spinner is displayed by default.\n * `toast.promise` returns the provided promise so you can chain it.\n *\n * Simple example:\n *\n * ```\n * toast.promise(MyPromise,\n * {\n * pending: 'Promise is pending',\n * success: 'Promise resolved 👌',\n * error: 'Promise rejected 🤯'\n * }\n * )\n *\n * ```\n *\n * Advanced usage:\n * ```\n * toast.promise<{name: string}, {message: string}, undefined>(\n * resolveWithSomeData,\n * {\n * pending: {\n * render: () => \"I'm loading\",\n * icon: false,\n * },\n * success: {\n * render: ({data}) => `Hello ${data.name}`,\n * icon: \"🟢\",\n * },\n * error: {\n * render({data}){\n * // When the promise reject, data will contains the error\n * return \n * }\n * }\n * }\n * )\n * ```\n */\ntoast.promise = handlePromise;\ntoast.success = createToastByType(Type.SUCCESS);\ntoast.info = createToastByType(Type.INFO);\ntoast.error = createToastByType(Type.ERROR);\ntoast.warning = createToastByType(Type.WARNING);\ntoast.warn = toast.warning;\ntoast.dark = (content: ToastContent, options?: ToastOptions) =>\n dispatchToast(\n content,\n mergeOptions(Type.DEFAULT, {\n theme: 'dark',\n ...options\n })\n );\n\ninterface RemoveParams {\n id?: Id;\n containerId: Id;\n}\n\nfunction dismiss(params: RemoveParams): void;\nfunction dismiss(params?: Id): void;\nfunction dismiss(params?: Id | RemoveParams) {\n removeToast(params);\n}\n\n/**\n * Remove toast programmatically\n *\n * - Remove all toasts:\n * ```\n * toast.dismiss()\n * ```\n *\n * - Remove all toasts that belongs to a given container\n * ```\n * toast.dismiss({ container: \"123\" })\n * ```\n *\n * - Remove toast that has a given id regardless the container\n * ```\n * toast.dismiss({ id: \"123\" })\n * ```\n *\n * - Remove toast that has a given id for a specific container\n * ```\n * toast.dismiss({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.dismiss = dismiss;\n\n/**\n * Clear waiting queue when limit is used\n */\ntoast.clearWaitingQueue = clearWaitingQueue;\n\n/**\n * Check if a toast is active\n *\n * - Check regardless the container\n * ```\n * toast.isActive(\"123\")\n * ```\n *\n * - Check in a specific container\n * ```\n * toast.isActive(\"123\", \"containerId\")\n * ```\n */\ntoast.isActive = isToastActive;\n\n/**\n * Update a toast, see https://fkhadra.github.io/react-toastify/update-toast/ for more\n *\n * Example:\n * ```\n * // With a string\n * toast.update(toastId, {\n * render: \"New content\",\n * type: \"info\",\n * });\n *\n * // Or with a component\n * toast.update(toastId, {\n * render: MyComponent\n * });\n *\n * // Or a function\n * toast.update(toastId, {\n * render: () =>
New content
\n * });\n *\n * // Apply a transition\n * toast.update(toastId, {\n * render: \"New Content\",\n * type: toast.TYPE.INFO,\n * transition: Rotate\n * })\n * ```\n */\ntoast.update = (\n toastId: Id,\n options: UpdateOptions = {}\n) => {\n const toast = getToast(toastId, options as ToastOptions);\n\n if (toast) {\n const { props: oldOptions, content: oldContent } = toast;\n\n const nextOptions = {\n delay: 100,\n ...oldOptions,\n ...options,\n toastId: options.toastId || toastId,\n updateId: genToastId()\n } as ToastProps & UpdateOptions;\n\n if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId;\n\n const content = nextOptions.render || oldContent;\n delete nextOptions.render;\n\n dispatchToast(content, nextOptions);\n }\n};\n\n/**\n * Used for controlled progress bar. It will automatically close the notification.\n *\n * If you don't want your notification to be clsoed when the timer is done you should use `toast.update` instead as follow instead:\n *\n * ```\n * toast.update(id, {\n * progress: null, // remove controlled progress bar\n * render: \"ok\",\n * type: \"success\",\n * autoClose: 5000 // set autoClose to the desired value\n * });\n * ```\n */\ntoast.done = (id: Id) => {\n toast.update(id, {\n progress: 1\n });\n};\n\n/**\n * Subscribe to change when a toast is added, removed and updated\n *\n * Usage:\n * ```\n * const unsubscribe = toast.onChange((payload) => {\n * switch (payload.status) {\n * case \"added\":\n * // new toast added\n * break;\n * case \"updated\":\n * // toast updated\n * break;\n * case \"removed\":\n * // toast has been removed\n * break;\n * }\n * })\n * ```\n */\ntoast.onChange = onChange;\n\n/**\n * Play a toast(s) timer progammatically\n *\n * Usage:\n *\n * - Play all toasts\n * ```\n * toast.play()\n * ```\n *\n * - Play all toasts for a given container\n * ```\n * toast.play({ containerId: \"123\" })\n * ```\n *\n * - Play toast that has a given id regardless the container\n * ```\n * toast.play({ id: \"123\" })\n * ```\n *\n * - Play toast that has a given id for a specific container\n * ```\n * toast.play({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.play = (opts?: IdOpts) => toggleToast(true, opts);\n\n/**\n * Pause a toast(s) timer progammatically\n *\n * Usage:\n *\n * - Pause all toasts\n * ```\n * toast.pause()\n * ```\n *\n * - Pause all toasts for a given container\n * ```\n * toast.pause({ containerId: \"123\" })\n * ```\n *\n * - Pause toast that has a given id regardless the container\n * ```\n * toast.pause({ id: \"123\" })\n * ```\n *\n * - Pause toast that has a given id for a specific container\n * ```\n * toast.pause({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.pause = (opts?: IdOpts) => toggleToast(false, opts);\n\nexport { toast };\n","import { useEffect, useLayoutEffect } from 'react';\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n","import React, { cloneElement, isValidElement } from 'react';\n\nimport { Theme, ToastProps, TypeOptions } from '../types';\nimport { Default, isFn } from '../utils';\n\n/**\n * Used when providing custom icon\n */\nexport interface IconProps {\n theme: Theme;\n type: TypeOptions;\n isLoading?: boolean;\n}\n\nexport type BuiltInIconProps = React.SVGProps & IconProps;\n\nconst Svg: React.FC = ({\n theme,\n type,\n isLoading,\n ...rest\n}) => (\n \n);\n\nfunction Warning(props: BuiltInIconProps) {\n return (\n \n \n \n );\n}\n\nfunction Info(props: BuiltInIconProps) {\n return (\n \n \n \n );\n}\n\nfunction Success(props: BuiltInIconProps) {\n return (\n \n \n \n );\n}\n\nfunction Error(props: BuiltInIconProps) {\n return (\n \n \n \n );\n}\n\nfunction Spinner() {\n return
;\n}\n\nexport const Icons = {\n info: Info,\n warning: Warning,\n success: Success,\n error: Error,\n spinner: Spinner\n};\n\nconst maybeIcon = (type: string): type is keyof typeof Icons => type in Icons;\n\nexport type IconParams = Pick<\n ToastProps,\n 'theme' | 'icon' | 'type' | 'isLoading'\n>;\n\nexport function getIcon({ theme, type, isLoading, icon }: IconParams) {\n let Icon: React.ReactNode = null;\n const iconProps = { theme, type };\n\n if (icon === false) {\n // hide\n } else if (isFn(icon)) {\n Icon = icon({ ...iconProps, isLoading });\n } else if (isValidElement(icon)) {\n Icon = cloneElement(icon, iconProps);\n } else if (isLoading) {\n Icon = Icons.spinner();\n } else if (maybeIcon(type)) {\n Icon = Icons[type](iconProps);\n }\n\n return Icon;\n}\n","import cx from 'clsx';\nimport React, { cloneElement, isValidElement, ReactNode } from 'react';\n\nimport { useToast } from '../hooks/useToast';\nimport { ToastProps } from '../types';\nimport { Default, isFn } from '../utils';\nimport { CloseButton } from './CloseButton';\nimport { ProgressBar } from './ProgressBar';\nimport { getIcon } from './Icons';\n\nexport const Toast: React.FC = props => {\n const {\n isRunning,\n preventExitTransition,\n toastRef,\n eventHandlers,\n playToast\n } = useToast(props);\n const {\n closeButton,\n children,\n autoClose,\n onClick,\n type,\n hideProgressBar,\n closeToast,\n transition: Transition,\n position,\n className,\n style,\n bodyClassName,\n bodyStyle,\n progressClassName,\n progressStyle,\n updateId,\n role,\n progress,\n rtl,\n toastId,\n deleteToast,\n isIn,\n isLoading,\n closeOnClick,\n theme\n } = props;\n const defaultClassName = cx(\n `${Default.CSS_NAMESPACE}__toast`,\n `${Default.CSS_NAMESPACE}__toast-theme--${theme}`,\n `${Default.CSS_NAMESPACE}__toast--${type}`,\n {\n [`${Default.CSS_NAMESPACE}__toast--rtl`]: rtl\n },\n {\n [`${Default.CSS_NAMESPACE}__toast--close-on-click`]: closeOnClick\n }\n );\n const cssClasses = isFn(className)\n ? className({\n rtl,\n position,\n type,\n defaultClassName\n })\n : cx(defaultClassName, className);\n const icon = getIcon(props);\n const isProgressControlled = !!progress || !autoClose;\n\n const closeButtonProps = { closeToast, type, theme };\n let Close: React.ReactNode = null;\n\n if (closeButton === false) {\n // hide\n } else if (isFn(closeButton)) {\n Close = closeButton(closeButtonProps);\n } else if (isValidElement(closeButton)) {\n Close = cloneElement(closeButton, closeButtonProps);\n } else {\n Close = CloseButton(closeButtonProps);\n }\n\n return (\n \n \n \n {icon != null && (\n \n {icon}\n
\n )}\n
{children as ReactNode}
\n \n {Close}\n \n \n \n );\n};\n","import React from 'react';\nimport { Default } from '../utils';\nimport { Theme, TypeOptions } from '../types';\n\nexport interface CloseButtonProps {\n closeToast: (e: React.MouseEvent) => void;\n type: TypeOptions;\n ariaLabel?: string;\n theme: Theme;\n}\n\nexport function CloseButton({\n closeToast,\n theme,\n ariaLabel = 'close'\n}: CloseButtonProps) {\n return (\n {\n e.stopPropagation();\n closeToast(e);\n }}\n aria-label={ariaLabel}\n >\n \n \n \n \n );\n}\n","import { Default, cssTransition } from '../utils';\n\nconst getConfig = (animationName: string, appendPosition = false) => ({\n enter: `${Default.CSS_NAMESPACE}--animate ${Default.CSS_NAMESPACE}__${animationName}-enter`,\n exit: `${Default.CSS_NAMESPACE}--animate ${Default.CSS_NAMESPACE}__${animationName}-exit`,\n appendPosition\n});\n\nconst Bounce = cssTransition(getConfig('bounce', true));\n\nconst Slide = cssTransition(getConfig('slide', true));\n\nconst Zoom = cssTransition(getConfig('zoom'));\n\nconst Flip = cssTransition(getConfig('flip'));\n\nexport { Bounce, Slide, Zoom, Flip };\n","import cx from 'clsx';\nimport React, { useRef, useState } from 'react';\n\nimport { toast } from '../core';\nimport { useToastContainer } from '../hooks/useToastContainer';\nimport { useIsomorphicLayoutEffect } from '../hooks/useIsomorphicLayoutEffect';\nimport { ToastContainerProps, ToastPosition } from '../types';\nimport { Default, Direction, isFn, parseClassName } from '../utils';\nimport { Toast } from './Toast';\nimport { Bounce } from './Transitions';\n\nexport const defaultProps: ToastContainerProps = {\n position: 'top-right',\n transition: Bounce,\n autoClose: 5000,\n closeButton: true,\n pauseOnHover: true,\n pauseOnFocusLoss: true,\n draggable: 'touch',\n draggablePercent: Default.DRAGGABLE_PERCENT as number,\n draggableDirection: Direction.X,\n role: 'alert',\n theme: 'light'\n};\n\nexport function ToastContainer(props: ToastContainerProps) {\n let containerProps: ToastContainerProps = {\n ...defaultProps,\n ...props\n };\n const stacked = props.stacked;\n const [collapsed, setIsCollapsed] = useState(true);\n const containerRef = useRef(null);\n const { getToastToRender, isToastActive, count } =\n useToastContainer(containerProps);\n const { className, style, rtl, containerId } = containerProps;\n\n function getClassName(position: ToastPosition) {\n const defaultClassName = cx(\n `${Default.CSS_NAMESPACE}__toast-container`,\n `${Default.CSS_NAMESPACE}__toast-container--${position}`,\n { [`${Default.CSS_NAMESPACE}__toast-container--rtl`]: rtl }\n );\n return isFn(className)\n ? className({\n position,\n rtl,\n defaultClassName\n })\n : cx(defaultClassName, parseClassName(className));\n }\n\n function collapseAll() {\n if (stacked) {\n setIsCollapsed(true);\n toast.play();\n }\n }\n\n useIsomorphicLayoutEffect(() => {\n if (stacked) {\n const nodes = containerRef.current!.querySelectorAll('[data-in=\"true\"]');\n const gap = 12;\n const isTop = containerProps.position?.includes('top');\n let usedHeight = 0;\n let prevS = 0;\n\n Array.from(nodes)\n .reverse()\n .forEach((n, i) => {\n const node = n as HTMLElement;\n node.classList.add(`${Default.CSS_NAMESPACE}__toast--stacked`);\n\n if (i > 0) node.dataset.collapsed = `${collapsed}`;\n\n if (!node.dataset.pos) node.dataset.pos = isTop ? 'top' : 'bot';\n\n const y =\n usedHeight * (collapsed ? 0.2 : 1) + (collapsed ? 0 : gap * i);\n\n node.style.setProperty('--y', `${isTop ? y : y * -1}px`);\n node.style.setProperty('--g', `${gap}`);\n node.style.setProperty('--s', `${1 - (collapsed ? prevS : 0)}`);\n\n usedHeight += node.offsetHeight;\n prevS += 0.025;\n });\n }\n }, [collapsed, count, stacked]);\n\n return (\n {\n if (stacked) {\n setIsCollapsed(false);\n toast.pause();\n }\n }}\n onMouseLeave={collapseAll}\n >\n {getToastToRender((position, toastList) => {\n const containerStyle: React.CSSProperties = !toastList.length\n ? { ...style, pointerEvents: 'none' }\n : { ...style };\n\n return (\n \n {toastList.map(({ content, props: toastProps }) => {\n return (\n \n {content}\n \n );\n })}\n \n );\n })}\n \n );\n}\n"],"names":["dist_clsx","e","t","f","n","o","arguments","length","r","Array","isArray"],"sourceRoot":""}