{"version":3,"sources":["../src/events/eventBus.ts","../src/events/addPortal.ts","../src/events/removePortal.ts","../src/helpers/common.ts","../src/useModal.tsx","../src/ModalContainer.tsx","../src/index.tsx"],"names":["useEffect","blockBodyScroll","onResolve","createPortal","jsx","useState","useCallback","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * A minimal module-scoped pub/sub bus used to hand portals created by\n * `useModal` (which runs outside of React's render cycle) to the mounted\n * `<ModalContainer />`.\n *\n * This is a direct TypeScript port of the `eventelo` package\n * (https://github.com/Harasz/eventelo, MIT © Jakub Sydor), which this library\n * previously depended on. It was inlined because `eventelo` only publishes an\n * ES5 CommonJS build with no `exports` map, which forces ESM-first bundlers\n * into dynamic-require/interop shims — the exact problem this package's dual\n * ESM/CJS build exists to remove. Behaviour is unchanged.\n */\n\nexport type EventName = string;\n\nexport type Callback<CallbackData = unknown> = (data: CallbackData) => void;\n\ninterface Subscriber<CallbackData = unknown> {\n  key: symbol;\n  eventName: EventName;\n  callback: Callback<CallbackData>;\n}\n\nconst eventMap: Record<EventName, Subscriber[]> = {};\n\n/** Registers `callback` for `eventName`. Returns the key needed to unsubscribe. */\nexport function subscribe<DataType = unknown>(\n  eventName: EventName,\n  callback: Callback<DataType>,\n): symbol {\n  const key = Symbol(eventName);\n\n  (eventMap[eventName] ??= []).push({\n    key,\n    eventName,\n    callback: callback as Callback<unknown>,\n  });\n\n  return key;\n}\n\n/** Removes the subscriber registered under `key`, if it is still present. */\nexport function unsubscribe(key: symbol): void {\n  for (const eventName of Object.keys(eventMap)) {\n    eventMap[eventName] = eventMap[eventName].filter((subscriber) => subscriber.key !== key);\n  }\n}\n\n/** Notifies every subscriber of `eventName`. Returns how many were notified. */\nexport function emit<DataType = unknown>(eventName: EventName, data: DataType): number {\n  const subscribers = eventMap[eventName];\n\n  if (!subscribers) {\n    return 0;\n  }\n\n  // Iterate a copy so a subscriber unsubscribing mid-emit cannot skip a peer.\n  for (const subscriber of [...subscribers]) {\n    subscriber.callback(data);\n  }\n\n  return subscribers.length;\n}\n","import { useEffect } from \"react\";\nimport type { UseModalContainerRef } from \"../useModal.interface\";\nimport { emit, subscribe, unsubscribe } from \"./eventBus\";\n\nexport const ADD_PORTAL_EVENT = \"ADD_PORTAL_EVENT\";\n\ntype ReturnType = (container: UseModalContainerRef) => void;\n\nexport const useAddPortal = (): ReturnType => {\n  return (container: UseModalContainerRef) => {\n    emit(ADD_PORTAL_EVENT, container);\n  };\n};\n\n/**\n * Subscribes to portal-added events for the lifetime of the calling component.\n *\n * `callback` must be referentially stable (wrap it in `useCallback`), otherwise\n * every render tears the subscription down and sets it back up. StrictMode's\n * double-invoked effects are safe here: the cleanup unsubscribes the exact key\n * its own setup created, so the pair nets out to a single subscriber.\n */\nexport const useSubscribeAddPortal = (callback: ReturnType): void => {\n  useEffect(() => {\n    const key = subscribe<UseModalContainerRef>(ADD_PORTAL_EVENT, callback);\n    return () => {\n      unsubscribe(key);\n    };\n  }, [callback]);\n};\n","import { useEffect } from \"react\";\nimport { emit, subscribe, unsubscribe } from \"./eventBus\";\n\nexport const REMOVE_PORTAL_EVENT = \"REMOVE_PORTAL_EVENT\";\n\ntype ReturnType = (id: string) => void;\n\nexport const useRemovePortal = (): ReturnType => {\n  return (id: string) => {\n    emit(REMOVE_PORTAL_EVENT, id);\n  };\n};\n\n/** See `useSubscribeAddPortal` — `callback` must be referentially stable. */\nexport const useSubscribeRemovePortal = (callback: ReturnType): void => {\n  useEffect(() => {\n    const key = subscribe<string>(REMOVE_PORTAL_EVENT, callback);\n    return () => {\n      unsubscribe(key);\n    };\n  }, [callback]);\n};\n","import type { CSSProperties } from \"react\";\n\nexport const getRandomPostfix = (): string => Math.random().toString(36).substring(2);\n\nexport const cssPropertiesToString = (properties: CSSProperties): string => {\n  return Object.keys(properties).reduce((inlineCss: string, key: string) => {\n    const cssPropertiesKey = key\n      .split(/(?=[A-Z])/)\n      .join(\"-\")\n      .toLowerCase();\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    const cssPropertiesValue = properties[key];\n\n    return inlineCss + `${cssPropertiesKey}: ${cssPropertiesValue};`;\n  }, \"\");\n};\n\nexport const getModalContainerById = (containerIdPostfix: string): HTMLDivElement | null =>\n  document.querySelector<HTMLDivElement>(`div#modal__${containerIdPostfix}`);\n\nexport const addClassesToModalContainer = (\n  modalContainer: HTMLDivElement | null,\n  classes?: string,\n): void => {\n  if (!modalContainer) return;\n\n  if (classes) modalContainer.classList.add(...classes.split(\" \"));\n};\n\nexport const removeClassesFromModalContainer = (\n  modalContainer: HTMLDivElement | null,\n  classes?: string,\n): void => {\n  if (!modalContainer) return;\n\n  if (classes) modalContainer.classList.remove(...classes.split(\" \"));\n};\n\nexport const blockBodyScroll = (block: boolean): void => {\n  const prop = block ? \"hidden\" : \"\";\n  document.body.style.overflow = prop;\n};\n","import { createPortal } from \"react-dom\";\nimport { useAddPortal, useRemovePortal } from \"./events\";\nimport {\n  cssPropertiesToString,\n  getRandomPostfix,\n  getModalContainerById,\n  addClassesToModalContainer,\n  removeClassesFromModalContainer,\n} from \"./helpers\";\nimport type {\n  UseModalContainerRef,\n  UseModalReturnType,\n  UseModalOptions,\n  ResolveFunction,\n  UseModalOnOpenOptions,\n} from \"./useModal.interface\";\n\nexport function useModal<ResultType, ModalProps>({\n  Component,\n  overlayStyles,\n  overlayClassName,\n  closeOnEsc,\n  closeOnOverlayClick,\n  defaultResolved,\n  overlayClassNameOnClose,\n  overlayClassNameOnOpen,\n  closeTimeoutMs,\n  blockBodyScroll,\n  onOpen,\n  onClose,\n}: UseModalOptions<ResultType>): UseModalReturnType<ResultType, ModalProps> {\n  const addPortal = useAddPortal();\n  const removePortal = useRemovePortal();\n\n  const onResolve = (resolve: ResolveFunction<ResultType>, containerIdPostfix: string) => {\n    return (result: ResultType) => {\n      const beforeCloseActions = () => {\n        onClose?.({ resolved: result });\n\n        const modalContainer = getModalContainerById(containerIdPostfix);\n        removeClassesFromModalContainer(modalContainer, overlayClassNameOnOpen);\n        addClassesToModalContainer(modalContainer, overlayClassNameOnClose);\n      };\n\n      const afterCloseActions = () => {\n        cleanupContainer(containerIdPostfix);\n        resolve(result);\n      };\n\n      beforeCloseActions();\n      if (closeTimeoutMs) {\n        setTimeout(afterCloseActions, closeTimeoutMs);\n      } else {\n        afterCloseActions();\n      }\n    };\n  };\n\n  const showModal = (props?: ModalProps) => {\n    return new Promise<ResultType>((resolve) => {\n      createModal(resolve, props);\n    });\n  };\n\n  const addEscListener = (containerIdPostfix: string, onResolve: (x: ResultType) => void) => {\n    const container = getModalContainerById(containerIdPostfix);\n\n    // TODO: Find method to not shown error while ResultType is void\n    // if (!defaultResolved) {\n    //   console.warn(\n    //     \"use-async-modal: when options `closeOnEsc` is true, `defaultResolved` must be set!\",\n    //   );\n    // }\n\n    if (!container) {\n      return;\n    }\n\n    container.addEventListener(\"keydown\", function _onEsc(e) {\n      if (e.key === \"Escape\") {\n        onResolve(defaultResolved!);\n        container.removeEventListener(\"keydown\", _onEsc);\n      }\n    });\n  };\n\n  const addClickListener = (containerIdPostfix: string, onResolve: (x: ResultType) => void) => {\n    const container = getModalContainerById(containerIdPostfix);\n\n    // TODO: Find method to not shown error while ResultType is void\n    // if (!defaultResolved) {\n    //   console.warn(\n    //     \"use-async-modal: when options `closeOnOverlayClick` is true, `defaultResolved` must be set!\",\n    //   );\n    // }\n\n    if (!container) {\n      return;\n    }\n\n    container.addEventListener(\"click\", function _onClick(e) {\n      if (e.target === container) {\n        onResolve(defaultResolved!);\n        container.removeEventListener(\"click\", _onClick);\n      }\n    });\n  };\n\n  const createModal = (resolve: ResolveFunction<ResultType>, props?: ModalProps) => {\n    const containerIdPostfix = getRandomPostfix();\n    const body = document.querySelector(\"body\");\n    const modalContainer = document.createElement(\"div\");\n\n    modalContainer.setAttribute(\"id\", `modal__${containerIdPostfix}`);\n    modalContainer.setAttribute(\"role\", \"dialog\");\n    modalContainer.setAttribute(\"aria-modal\", \"true\");\n    modalContainer.tabIndex = -1;\n\n    // Apply styles\n    modalContainer.classList.add(\"useModal__overlay\");\n    if (overlayStyles) {\n      modalContainer.setAttribute(\"style\", cssPropertiesToString(overlayStyles));\n    }\n    addClassesToModalContainer(modalContainer, overlayClassName);\n    addClassesToModalContainer(modalContainer, overlayClassNameOnOpen);\n\n    body?.appendChild(modalContainer);\n\n    const onOpenOptions: UseModalOnOpenOptions = {\n      containerRef: modalContainer,\n      containerId: containerIdPostfix,\n      blockBodyScroll: blockBodyScroll ?? true,\n    };\n\n    const handleResolve = onResolve(resolve, containerIdPostfix);\n\n    const containerRef: UseModalContainerRef = {\n      ...onOpenOptions,\n      portal: createPortal(\n        <Component onResolve={handleResolve} {...props} />,\n        modalContainer,\n        containerIdPostfix,\n      ),\n    };\n\n    addPortal(containerRef);\n\n    if (closeOnEsc) addEscListener(onOpenOptions.containerId, handleResolve);\n    if (closeOnOverlayClick) addClickListener(onOpenOptions.containerId, handleResolve);\n\n    onOpen?.(onOpenOptions);\n  };\n\n  const cleanupContainer = (containerIdPostfix: string) => {\n    const body = document.querySelector(\"body\");\n    const modalContainer = getModalContainerById(containerIdPostfix);\n\n    removePortal(containerIdPostfix);\n\n    if (!modalContainer || !body) {\n      return;\n    }\n\n    body.removeChild(modalContainer);\n  };\n\n  return showModal;\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { FC } from \"react\";\nimport { useSubscribeAddPortal, useSubscribeRemovePortal } from \"./events\";\nimport { blockBodyScroll } from \"./helpers/common\";\nimport type { UseModalContainerRef } from \"./useModal.interface\";\n\nexport const ModalContainer: FC = () => {\n  const [containers, setContainers] = useState<UseModalContainerRef[]>([]);\n\n  // Both handlers are stable so `useSubscribe*` subscribes exactly once per\n  // mount, and both update state functionally so they never close over a stale\n  // `containers`.\n  const handleAddPortal = useCallback((container: UseModalContainerRef) => {\n    setContainers((prev) => [...prev, container]);\n\n    if (container.blockBodyScroll) {\n      blockBodyScroll(true);\n    }\n  }, []);\n\n  const handleRemovePortal = useCallback((containerId: string) => {\n    setContainers((prev) => prev.filter((container) => container.containerId !== containerId));\n  }, []);\n\n  useSubscribeAddPortal(handleAddPortal);\n  useSubscribeRemovePortal(handleRemovePortal);\n\n  useEffect(() => {\n    const hasBodyScroll = containers.reduce((has, container) => {\n      return has || container.blockBodyScroll;\n    }, false);\n\n    if (!hasBodyScroll) blockBodyScroll(false);\n  }, [containers]);\n\n  const modalPortals = containers.map((container) => container.portal);\n\n  return <>{modalPortals}</>;\n};\n","import { useModal } from \"./useModal\";\nexport { useModal } from \"./useModal\";\nexport { ModalContainer } from \"./ModalContainer\";\nexport default useModal;\n\nexport type {\n  UseModalComponentProps,\n  UseModalOnCloseOptions,\n  UseModalOnOpenOptions,\n  UseModalOptions,\n  UseModalReturnType,\n} from \"./useModal.interface\";\n"]}