{"version":3,"file":"toastHost.mjs","names":[],"sources":["../../../../package/common/toast/toastHost.tsx"],"sourcesContent":["import React, { useCallback, useInsertionEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './toast.module.pcss';\nimport Toast from './toast';\nimport { _registerToastHandler, _unregisterToastHandler } from './toastService';\nimport type {\n  ToastContextConfig,\n  ToastItem,\n  ToastOptions,\n  ResolvedToastOptions,\n  ToastPosition,\n  ToastLabels,\n  ToastHostProps,\n} from './toast.types';\nimport type { ReactNode } from 'react';\nimport { ThemeColor } from '../themeProvider/color.types';\n\nconst DEFAULTS: Required<ToastContextConfig> = {\n  position: 'top-right',\n  duration: 4000,\n  showRemainingTime: true,\n  showCloseButton: true,\n  allowStacking: true,\n  pauseOnHover: true,\n  labels: { close: 'Close' },\n};\n\nconst DISMISS_ANIMATION_MS = 220;\n\nfunction positionToClass(position: ToastPosition): string {\n  return styles[`container-${position}`];\n}\n\nfunction ToastHost({\n  children,\n  position = DEFAULTS.position,\n  duration = DEFAULTS.duration,\n  showRemainingTime = DEFAULTS.showRemainingTime,\n  showCloseButton = DEFAULTS.showCloseButton,\n  allowStacking = DEFAULTS.allowStacking,\n  pauseOnHover = DEFAULTS.pauseOnHover,\n  labels,\n}: ToastHostProps) {\n  const [toasts, setToasts] = useState<ToastItem[]>([]);\n  const counterRef = useRef(0);\n\n  const dismiss = useCallback((id: string) => {\n    setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, dismissing: true } : t)));\n    setTimeout(() => {\n      setToasts((prev) => prev.filter((t) => t.id !== id));\n    }, DISMISS_ANIMATION_MS);\n  }, []);\n\n  const addToast = useCallback(\n    (content: ReactNode, options?: ToastOptions) => {\n      const resolved: ResolvedToastOptions = {\n        position: options?.position ?? position,\n        duration: options?.duration ?? duration,\n        showRemainingTime: options?.showRemainingTime ?? showRemainingTime,\n        showCloseButton: options?.showCloseButton ?? showCloseButton,\n        pauseOnHover: options?.pauseOnHover ?? pauseOnHover,\n        color: options?.color ?? ThemeColor.Primary,\n        classNames: options?.classNames,\n        styles: options?.styles,\n      };\n\n      counterRef.current += 1;\n      const id = `toast-${counterRef.current}`;\n      const newToast: ToastItem = { id, content, options: resolved, dismissing: false, labels: options?.labels };\n\n      setToasts((prev) => {\n        if (!allowStacking && prev.length > 0) {\n          // Mark all existing as dismissing, then replace\n          setTimeout(() => {\n            setToasts([newToast]);\n          }, DISMISS_ANIMATION_MS);\n          return prev.map((t) => ({ ...t, dismissing: true }));\n        }\n        return [...prev, newToast];\n      });\n    },\n    [position, duration, showRemainingTime, showCloseButton, allowStacking, pauseOnHover],\n  );\n\n  // Insertion effects run before every layout and passive effect, including the app's, which as\n  // this host's descendants would otherwise run first. Registered once, so that a settings change\n  // does not move this host to the end of the list.\n  const latestAddToast = useRef(addToast);\n  useInsertionEffect(() => {\n    latestAddToast.current = addToast;\n  }, [addToast]);\n\n  useInsertionEffect(() => {\n    const show: typeof addToast = (content, options) => latestAddToast.current(content, options);\n    _registerToastHandler(show);\n    return () => _unregisterToastHandler(show);\n  }, []);\n\n  // Group toasts by position so per-toast position overrides work correctly\n  const byPosition = toasts.reduce<Record<string, ToastItem[]>>((acc, t) => {\n    const pos = t.options.position;\n    if (!acc[pos]) acc[pos] = [];\n    acc[pos].push(t);\n    return acc;\n  }, {});\n\n  return (\n    <>\n      {children}\n      <BodyEnd>\n        {Object.entries(byPosition).map(([pos, items]) => (\n          <div key={pos} className={cx(styles.container, positionToClass(pos as typeof position))}>\n            {items.map((item) => (\n              <Toast\n                key={item.id}\n                item={item}\n                isBottom={pos.startsWith('bottom')}\n                onDismiss={dismiss}\n                labels={{ ...DEFAULTS.labels, ...labels, ...item.labels } as Required<ToastLabels>}\n              />\n            ))}\n          </div>\n        ))}\n      </BodyEnd>\n    </>\n  );\n}\n\nexport default ToastHost;\n"],"mappings":"sbAmBA,IAAM,EAAyC,CAC7C,SAAU,YACV,SAAU,IACV,kBAAmB,GACnB,gBAAiB,GACjB,cAAe,GACf,aAAc,GACd,OAAQ,CAAE,MAAO,OAAQ,CAC3B,EAEM,EAAuB,IAE7B,SAAS,EAAgB,EAAiC,CACxD,OAAO,EAAO,aAAa,IAC7B,CAEA,SAAS,EAAU,CACjB,WACA,WAAW,EAAS,SACpB,WAAW,EAAS,SACpB,oBAAoB,EAAS,kBAC7B,kBAAkB,EAAS,gBAC3B,gBAAgB,EAAS,cACzB,eAAe,EAAS,aACxB,UACiB,CACjB,GAAM,CAAC,EAAQ,GAAa,EAAsB,CAAC,CAAC,EAC9C,EAAa,EAAO,CAAC,EAErB,EAAU,EAAa,GAAe,CAC1C,EAAW,GAAS,EAAK,IAAK,GAAO,EAAE,KAAO,EAAK,CAAE,GAAG,EAAG,WAAY,EAAK,EAAI,CAAE,CAAC,EACnF,eAAiB,CACf,EAAW,GAAS,EAAK,OAAQ,GAAM,EAAE,KAAO,CAAE,CAAC,CACrD,EAAG,CAAoB,CACzB,EAAG,CAAC,CAAC,EAEC,EAAW,GACd,EAAoB,IAA2B,CAC9C,IAAM,EAAiC,CACrC,SAAU,GAAS,UAAY,EAC/B,SAAU,GAAS,UAAY,EAC/B,kBAAmB,GAAS,mBAAqB,EACjD,gBAAiB,GAAS,iBAAmB,EAC7C,aAAc,GAAS,cAAgB,EACvC,MAAO,GAAS,OAAS,EAAW,QACpC,WAAY,GAAS,WACrB,OAAQ,GAAS,MACnB,EAEA,EAAW,SAAW,EAEtB,IAAM,EAAsB,CAAE,GAAA,SADV,EAAW,UACG,UAAS,QAAS,EAAU,WAAY,GAAO,OAAQ,GAAS,MAAO,EAEzG,EAAW,GACL,CAAC,GAAiB,EAAK,OAAS,GAElC,eAAiB,CACf,EAAU,CAAC,CAAQ,CAAC,CACtB,EAAG,CAAoB,EAChB,EAAK,IAAK,IAAO,CAAE,GAAG,EAAG,WAAY,EAAK,EAAE,GAE9C,CAAC,GAAG,EAAM,CAAQ,CAC1B,CACH,EACA,CAAC,EAAU,EAAU,EAAmB,EAAiB,EAAe,CAAY,CACtF,EAKM,EAAiB,EAAO,CAAQ,EACtC,MAAyB,CACvB,EAAe,QAAU,CAC3B,EAAG,CAAC,CAAQ,CAAC,EAEb,MAAyB,CACvB,IAAM,GAAyB,EAAS,IAAY,EAAe,QAAQ,EAAS,CAAO,EAE3F,OADA,EAAsB,CAAI,MACb,EAAwB,CAAI,CAC3C,EAAG,CAAC,CAAC,EAGL,IAAM,EAAa,EAAO,QAAqC,EAAK,IAAM,CACxE,IAAM,EAAM,EAAE,QAAQ,SAGtB,OAFK,EAAI,KAAM,EAAI,GAAO,CAAC,GAC3B,EAAI,EAAI,CAAC,KAAK,CAAC,EACR,CACT,EAAG,CAAC,CAAC,EAEL,OACE,EAAA,EAAA,CAAA,SAAA,CACG,EACD,EAAC,EAAD,CAAA,SACG,OAAO,QAAQ,CAAU,CAAC,CAAC,KAAK,CAAC,EAAK,KACrC,EAAC,MAAD,CAAe,UAAW,EAAG,EAAO,UAAW,EAAgB,CAAsB,CAAC,EACnF,SAAA,EAAM,IAAK,GACV,EAAC,EAAD,CAEQ,OACN,SAAU,EAAI,WAAW,QAAQ,EACjC,UAAW,EACX,OAAQ,CAAE,GAAG,EAAS,OAAQ,GAAG,EAAQ,GAAG,EAAK,MAAO,CACzD,EALM,EAAK,EAKX,CACF,CACE,EAVK,CAUL,CACN,CACM,CAAA,CACT,CAAA,CAAA,CAEN"}