{"version":3,"file":"imperative.mjs","names":["BaseToast"],"sources":["../../../src/base-ui/Toast/imperative.tsx"],"sourcesContent":["'use client';\n\nimport { Toast as BaseToast } from '@base-ui/react/toast';\nimport { cx } from 'antd-style';\nimport { memo, useEffect, useId, useState, useSyncExternalStore } from 'react';\n\nimport { useIsClient } from '@/hooks/useIsClient';\nimport { useAppElement } from '@/ThemeProvider';\n\nimport { acquireLayerZIndex } from '../zIndex';\nimport { ToastContext } from './context';\nimport { isActiveToastHost, registerToastHost, subscribeToastHost } from './hostGuard';\nimport {\n  __resetPendingToastQueueForTests,\n  markToastHostNotReady,\n  markToastHostReady,\n  runWhenToastHostReady,\n} from './pendingQueue';\nimport { viewportVariants } from './style';\nimport ToastItem from './Toast';\nimport {\n  type ToastAPI,\n  type ToastInstance,\n  type ToastOptions,\n  type ToastPosition,\n  type ToastPromiseOptions,\n  type ToastType,\n} from './type';\n\n// All possible positions\nconst ALL_POSITIONS: ToastPosition[] = [\n  'top',\n  'top-left',\n  'top-right',\n  'bottom',\n  'bottom-left',\n  'bottom-right',\n];\n\n// Global state management\ninterface ToastState {\n  duration: number;\n  limit: number;\n  position: ToastPosition;\n  swipeDirection: ('left' | 'right' | 'up' | 'down') | ('left' | 'right' | 'up' | 'down')[];\n}\n\nlet globalState: ToastState = {\n  duration: 5000,\n  limit: 5,\n  position: 'bottom-right',\n  swipeDirection: ['down', 'right'],\n};\n\n// Toast managers for each position\nconst toastManagers: Record<ToastPosition, ReturnType<typeof BaseToast.createToastManager>> = {\n  'bottom': BaseToast.createToastManager(),\n  'bottom-left': BaseToast.createToastManager(),\n  'bottom-right': BaseToast.createToastManager(),\n  'top': BaseToast.createToastManager(),\n  'top-left': BaseToast.createToastManager(),\n  'top-right': BaseToast.createToastManager(),\n};\n\ninterface ActiveToast {\n  superseded: boolean;\n}\n\nconst activeToasts: Record<ToastPosition, Map<string, ActiveToast>> = {\n  'bottom': new Map(),\n  'bottom-left': new Map(),\n  'bottom-right': new Map(),\n  'top': new Map(),\n  'top-left': new Map(),\n  'top-right': new Map(),\n};\n\nconst getManager = (position: ToastPosition) => toastManagers[position];\n\nlet toastIdCounter = 0;\nconst generateToastId = (): string =>\n  `toast-${Date.now().toString(36)}-${(toastIdCounter++).toString(36)}`;\n\nconst findActivePosition = (id: string) => ALL_POSITIONS.find((pos) => activeToasts[pos].has(id));\n\n// Base UI prepends every new toast, so the last entry we registered is the one\n// currently rendered at the front of the stack.\nconst isFrontMost = (position: ToastPosition, id: string) =>\n  Array.from(activeToasts[position].keys()).at(-1) === id;\n\nconst normalizeOptions = (\n  optionsOrMessage: Omit<ToastOptions, 'type'> | string,\n  type: ToastType,\n): ToastOptions => {\n  if (typeof optionsOrMessage === 'string') {\n    return {\n      description: optionsOrMessage,\n      type,\n    };\n  }\n  return {\n    ...optionsOrMessage,\n    type,\n  };\n};\n\nconst createToastInstance = (id: string, position: ToastPosition): ToastInstance => ({\n  close: () => runWhenToastHostReady(() => getManager(position).close(id)),\n  id,\n  update: (options) => {\n    runWhenToastHostReady(() =>\n      getManager(position).update(id, {\n        data: options,\n        description: options.description,\n        title: options.title,\n      }),\n    );\n  },\n});\n\n// createToastManager() is a stateless emitter (see @base-ui/react/toast/createToastManager):\n// add/close/update just broadcast to whatever is currently subscribed, and the\n// ToastProvider that owns the real toast state only subscribes from a passive\n// useEffect. Calls made while no host is ready (e.g. mid-handoff between the\n// previously-active ToastHost unmounting and its successor's Provider\n// subscribing) would otherwise be silently dropped, so every manager call is\n// routed through runWhenToastHostReady to queue until a host is listening.\nconst addToast = (options: ToastOptions): ToastInstance => {\n  const position = options.placement ?? globalState.position;\n  const manager = getManager(position);\n  const { id: dedupeId, onClose, onRemove } = options;\n\n  if (dedupeId) {\n    const prevPosition = findActivePosition(dedupeId);\n    // Already the front-most toast: let Base UI upsert it in place so it only\n    // refreshes its content and timer, without replaying the slide-in animation.\n    const shouldPromote =\n      prevPosition && !(prevPosition === position && isFrontMost(position, dedupeId));\n\n    if (shouldPromote) {\n      // Closing marks the toast as `ending`, which makes the following `add`\n      // drop it and prepend a fresh one — Base UI's own upsert keeps the\n      // original slot instead.\n      activeToasts[prevPosition].get(dedupeId)!.superseded = true;\n      activeToasts[prevPosition].delete(dedupeId);\n      runWhenToastHostReady(() => getManager(prevPosition).close(dedupeId));\n    }\n  }\n\n  const id = dedupeId ?? generateToastId();\n  const active: ActiveToast = { superseded: false };\n  activeToasts[position].set(id, active);\n  runWhenToastHostReady(() => {\n    manager.add({\n      id,\n      data: options,\n      description: options.description,\n      onClose: () => {\n        if (active.superseded) return;\n        onClose?.();\n      },\n      onRemove: () => {\n        if (active.superseded) return;\n        activeToasts[position].delete(id);\n        onRemove?.();\n      },\n      timeout: options.duration ?? globalState.duration,\n      title: options.title,\n    });\n  });\n  return createToastInstance(id, position);\n};\n\nconst dismissToast = (id?: string) => {\n  if (id) {\n    // Try to close from all managers since we don't know which position the toast is in\n    for (const [position, manager] of Object.entries(toastManagers)) {\n      activeToasts[position as ToastPosition].delete(id);\n      runWhenToastHostReady(() => manager.close(id));\n    }\n  } else {\n    // Clear all toasts\n    for (const [position, manager] of Object.entries(toastManagers)) {\n      const ids = Array.from(activeToasts[position as ToastPosition].keys());\n      activeToasts[position as ToastPosition].clear();\n      runWhenToastHostReady(() => {\n        for (const toastId of ids) {\n          manager.close(toastId);\n        }\n      });\n    }\n  }\n};\n\nconst createSuccessToast = (\n  optionsOrMessage: Omit<ToastOptions, 'type'> | string,\n): ToastInstance => {\n  return addToast(normalizeOptions(optionsOrMessage, 'success'));\n};\n\nconst createErrorToast = (optionsOrMessage: Omit<ToastOptions, 'type'> | string): ToastInstance => {\n  return addToast(normalizeOptions(optionsOrMessage, 'error'));\n};\n\nconst createInfoToast = (optionsOrMessage: Omit<ToastOptions, 'type'> | string): ToastInstance => {\n  return addToast(normalizeOptions(optionsOrMessage, 'info'));\n};\n\nconst createWarningToast = (\n  optionsOrMessage: Omit<ToastOptions, 'type'> | string,\n): ToastInstance => {\n  return addToast(normalizeOptions(optionsOrMessage, 'warning'));\n};\n\nconst createLoadingToast = (\n  optionsOrMessage: Omit<ToastOptions, 'type'> | string,\n): ToastInstance => {\n  const options = normalizeOptions(optionsOrMessage, 'loading');\n  // Loading toasts don't auto-dismiss by default\n  return addToast({ duration: 0, ...options });\n};\n\nasync function promiseToast<T>(promise: Promise<T>, options: ToastPromiseOptions<T>): Promise<T> {\n  const loadingOptions =\n    typeof options.loading === 'string'\n      ? { description: options.loading }\n      : (options.loading as ToastOptions);\n\n  const loadingToast = addToast({\n    closable: false,\n    duration: 0,\n    type: 'loading',\n    ...loadingOptions,\n  });\n\n  try {\n    const result = await promise;\n\n    loadingToast.close();\n\n    const successOptions = (() => {\n      if (typeof options.success === 'string') {\n        return { description: options.success };\n      }\n      if (typeof options.success === 'function') {\n        return { description: options.success(result) };\n      }\n      return options.success as ToastOptions;\n    })();\n\n    addToast({ type: 'success', ...successOptions });\n\n    return result;\n  } catch (error) {\n    loadingToast.close();\n\n    const errorOptions = (() => {\n      if (typeof options.error === 'string') {\n        return { description: options.error };\n      }\n      if (typeof options.error === 'function') {\n        return { description: options.error(error as Error) };\n      }\n      return options.error as ToastOptions;\n    })();\n\n    addToast({ type: 'error', ...errorOptions });\n\n    throw error;\n  }\n}\n\n// Base toast function\nconst baseToast = (options: ToastOptions): ToastInstance => {\n  return addToast({ type: 'default', ...options });\n};\n\n// Toast API\nexport const toast: ToastAPI = Object.assign(baseToast, {\n  dismiss: dismissToast,\n  error: createErrorToast,\n  info: createInfoToast,\n  loading: createLoadingToast,\n  promise: promiseToast,\n  success: createSuccessToast,\n  warning: createWarningToast,\n});\n\n// Toast List Component\nconst ToastList = memo(() => {\n  const { toasts } = BaseToast.useToastManager();\n  return toasts.map((t) => <ToastItem key={t.id} toast={t} />);\n});\n\nToastList.displayName = 'ToastList';\n\nexport interface ToastHostProps {\n  className?: string;\n  /**\n   * Default duration for toasts\n   * @default 5000\n   */\n  duration?: number;\n  /**\n   * Maximum number of toasts\n   * @default 5\n   */\n  limit?: number;\n  /**\n   * Toast position\n   * @default 'bottom-right'\n   */\n  position?: ToastPosition;\n  /**\n   * Root element for portal\n   */\n  root?: HTMLElement | ShadowRoot | null;\n  /**\n   * Swipe direction to dismiss\n   * @default ['down', 'right']\n   */\n  swipeDirection?: ('left' | 'right' | 'up' | 'down') | ('left' | 'right' | 'up' | 'down')[];\n}\n\nexport const ToastHost = memo(\n  ({\n    root,\n    className,\n    duration = 5000,\n    limit = 5,\n    position = 'bottom-right',\n    swipeDirection = ['down', 'right'],\n  }: ToastHostProps) => {\n    const isClient = useIsClient();\n    const appElement = useAppElement();\n    const [viewportZIndex, setViewportZIndex] = useState<number | undefined>(undefined);\n    const hostId = useId();\n\n    useEffect(() => registerToastHost(hostId), [hostId]);\n\n    const isActive = useSyncExternalStore(\n      subscribeToastHost,\n      () => isActiveToastHost(hostId),\n      () => false,\n    );\n\n    useEffect(() => {\n      if (!isActive) return;\n      globalState = {\n        duration,\n        limit,\n        position,\n        swipeDirection,\n      };\n    }, [duration, limit, position, swipeDirection, isActive]);\n\n    useEffect(() => {\n      if (!isActive) return;\n      setViewportZIndex(acquireLayerZIndex('toast'));\n    }, [isActive]);\n\n    useEffect(() => {\n      if (!isActive || !isClient) return undefined;\n      // Runs after the six BaseToast.Provider children below have committed\n      // and subscribed (child effects run before the parent's), so the\n      // managers are guaranteed to have a live listener once this fires.\n      markToastHostReady();\n      return () => {\n        markToastHostNotReady();\n      };\n    }, [isActive, isClient]);\n\n    if (!isClient || !isActive) return null;\n\n    const container = root ?? appElement ?? document.body;\n\n    return ALL_POSITIONS.map((pos) => (\n      <ToastContext key={pos} value={{ position: pos, swipeDirection }}>\n        <BaseToast.Provider limit={limit} timeout={duration} toastManager={getManager(pos)}>\n          <BaseToast.Portal container={container}>\n            <BaseToast.Viewport\n              className={cx(viewportVariants({ position: pos }), className)}\n              style={{ zIndex: viewportZIndex }}\n            >\n              <ToastList />\n            </BaseToast.Viewport>\n          </BaseToast.Portal>\n        </BaseToast.Provider>\n      </ToastContext>\n    ));\n  },\n);\n\nToastHost.displayName = 'ToastHost';\n\n// Hook to use toast manager\nexport const useToast = () => toast;\n\nexport const __resetToastStateForTests = (): void => {\n  globalState = {\n    duration: 5000,\n    limit: 5,\n    position: 'bottom-right',\n    swipeDirection: ['down', 'right'],\n  };\n  for (const position of ALL_POSITIONS) {\n    toastManagers[position] = BaseToast.createToastManager();\n    activeToasts[position].clear();\n  }\n  __resetPendingToastQueueForTests();\n};\n"],"mappings":"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"}