@okyrychenko-dev/react-modal-manager 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +143 -49
- package/dist/index.cjs +234 -275
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +235 -276
- package/dist/index.js.map +1 -1
- package/package.json +43 -28
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/registry/createModal.ts","../src/registry/createModalController.constants.ts","../src/registry/createModalController.ts","../src/registry/createModalRegistry.constants.ts","../src/registry/modalRegistryBinding.ts","../src/registry/createModalRegistry.ts","../src/confirm/ConfirmModal.constants.ts","../src/confirm/ConfirmModal.utils.ts","../src/confirm/ConfirmModal.tsx","../src/confirm/builtInConfirmModal.ts","../src/errors/ModalDismissError.ts","../src/errors/ModalRejectError.ts","../src/store/ModalStoreContext.ts","../src/store/useModalStore.ts","../src/store/modalStore.actions.ts","../src/store/modalStore.constants.ts","../src/store/modalStore.ts","../src/store/ModalStoreProvider.tsx","../src/store/modalStore.selectors.ts","../src/runtime/ModalRuntimeConfigContext.ts","../src/hooks/useModalRuntimeConfig.ts","../src/hooks/useModalManager/useModalManager.constants.ts","../src/hooks/useModalManager/useModalManager.tsx","../src/viewport/ModalViewport.tsx","../src/provider/ModalRegistryBinder.tsx","../src/provider/ModalStoreCleanup.constants.ts","../src/provider/ModalStoreCleanup.tsx","../src/provider/ModalProvider.tsx"],"names":["jsx","createContext","useContext","confirmModal","useEffect","useMemo","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ModalOptions,\n RegisteredModalDefinition,\n} from \"./createModal.types\";\n\nfunction createGeneratedModalId(): string {\n return `modal-definition-${crypto.randomUUID()}`;\n}\n\nexport function createModal<TInput, TResult>(\n options: ModalOptions<TInput, TResult>,\n): RegisteredModalDefinition<TInput, TResult> {\n const definition = {\n ...options,\n id: options.id ?? createGeneratedModalId(),\n };\n\n return {\n ...definition,\n open: (manager, input) => manager.open(definition, input),\n };\n}\n","export const MODAL_CONTROLLER_UNBOUND_ERROR =\n \"Modal registry is not bound to a mounted ModalProvider\";\n","import { MODAL_CONTROLLER_UNBOUND_ERROR } from \"./createModalController.constants\";\nimport type { ConfirmModalParams, ConfirmModalResult } from \"../confirm\";\nimport type { ModalHandle, ModalManager } from \"../hooks\";\nimport type {\n ModalDefinition,\n ModalDismissReason,\n ModalInstanceId,\n} from \"../types\";\nimport type { ModalController } from \"./createModalController.types\";\n\nexport function createModalController(): ModalController {\n // A shared registry targets the most recently mounted provider and falls back on unmount.\n const managerStack: Array<ModalManager> = [];\n\n const getActiveManager = (): ModalManager => {\n if (managerStack.length === 0) {\n throw new Error(MODAL_CONTROLLER_UNBOUND_ERROR);\n }\n\n return managerStack[managerStack.length - 1];\n };\n\n return {\n bind: (manager) => {\n managerStack.push(manager);\n\n return () => {\n const managerIndex = managerStack.lastIndexOf(manager);\n\n if (managerIndex >= 0) {\n managerStack.splice(managerIndex, 1);\n }\n };\n },\n\n closeAll: (reason?: ModalDismissReason) => {\n getActiveManager().closeAll(reason);\n },\n\n confirm: (params: ConfirmModalParams): Promise<ConfirmModalResult> =>\n getActiveManager().confirm(params),\n\n dismiss: (\n instanceId: ModalInstanceId,\n reason?: ModalDismissReason,\n ): void => {\n getActiveManager().dismiss(instanceId, reason);\n },\n\n isReady: () => managerStack.length > 0,\n\n open: <TInput, TResult>(\n modal: ModalDefinition<TInput, TResult>,\n input: TInput,\n ): ModalHandle<TResult> => getActiveManager().open(modal, input),\n };\n}\n","export const MODAL_REGISTRY_UNKNOWN_KEY_ERROR =\n \"Modal registry does not contain modal\";\n","import type { ModalController } from \"./createModalController.types\";\nimport type { ModalRegistryBinding } from \"./createModalRegistry.types\";\n\nconst registryControllers = new WeakMap<\n ModalRegistryBinding,\n ModalController\n>();\n\nexport function bindModalRegistry(\n registry: ModalRegistryBinding,\n controller: ModalController,\n): void {\n registryControllers.set(registry, controller);\n}\n\nexport function getModalRegistryController(\n registry: ModalRegistryBinding,\n): ModalController | undefined {\n return registryControllers.get(registry);\n}\n","import { createModalController } from \"./createModalController\";\nimport { MODAL_REGISTRY_UNKNOWN_KEY_ERROR } from \"./createModalRegistry.constants\";\nimport { bindModalRegistry } from \"./modalRegistryBinding\";\nimport type { ModalHandle } from \"../hooks\";\nimport type {\n ModalRegistry,\n ModalRegistryDefinitions,\n ModalRegistryInput,\n} from \"./createModalRegistry.types\";\n\nexport function createModalRegistry<\n const TDefinitions extends ModalRegistryDefinitions,\n>(definitions: TDefinitions): ModalRegistry<TDefinitions> {\n const controller = createModalController();\n\n function open<TKey extends keyof TDefinitions & string>(\n key: TKey,\n input: ModalRegistryInput<TDefinitions[TKey]>,\n ): ReturnType<TDefinitions[TKey][\"open\"]>;\n function open(key: string, input: unknown): ModalHandle<unknown> {\n if (!Object.prototype.hasOwnProperty.call(definitions, key)) {\n throw new Error(`${MODAL_REGISTRY_UNKNOWN_KEY_ERROR}: ${key}`);\n }\n\n return definitions[key].open(controller, input);\n }\n\n const registry: ModalRegistry<TDefinitions> = {\n closeAll: controller.closeAll,\n confirm: controller.confirm,\n dismiss: controller.dismiss,\n isReady: controller.isReady,\n open,\n };\n\n bindModalRegistry(registry, controller);\n\n return registry;\n}\n","export const DEFAULT_CANCEL_TEXT = \"Cancel\";\nexport const DEFAULT_CONFIRM_TEXT = \"Confirm\";\n\nexport const CONFIRM_MODAL_FOCUSABLE_SELECTOR = [\n \"a[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(\", \");\n","import { CONFIRM_MODAL_FOCUSABLE_SELECTOR } from \"./ConfirmModal.constants\";\n\nexport function getFocusableElements(\n container: HTMLElement,\n): Array<HTMLElement> {\n return Array.from(\n container.querySelectorAll<HTMLElement>(CONFIRM_MODAL_FOCUSABLE_SELECTOR),\n );\n}\n","import { useEffect, useId, useRef } from \"react\";\nimport {\n DEFAULT_CANCEL_TEXT,\n DEFAULT_CONFIRM_TEXT,\n} from \"./ConfirmModal.constants\";\nimport { getFocusableElements } from \"./ConfirmModal.utils\";\nimport type { KeyboardEvent, ReactNode } from \"react\";\nimport type { ModalComponentProps } from \"../types\";\nimport type {\n ConfirmModalParams,\n ConfirmModalResult,\n} from \"./ConfirmModal.types\";\n\nexport function ConfirmModal(\n props: ModalComponentProps<ConfirmModalParams, ConfirmModalResult>,\n): ReactNode {\n const { close, input } = props;\n\n const cancelText = input.cancelText ?? DEFAULT_CANCEL_TEXT;\n const confirmText = input.confirmText ?? DEFAULT_CONFIRM_TEXT;\n const variant = input.variant ?? \"default\";\n const dismissible = input.dismissible !== false;\n const hasDescription = input.description !== undefined;\n const titleId = useId();\n const descriptionId = useId();\n const dialogRef = useRef<HTMLElement>(null);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n const confirmButtonRef = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n const previouslyFocused = document.activeElement;\n\n // Destructive confirms focus the safe action so an accidental Enter does not confirm.\n let initialFocusRef = confirmButtonRef;\n\n if (variant === \"danger\") {\n initialFocusRef = cancelButtonRef;\n }\n\n initialFocusRef.current?.focus();\n\n return () => {\n if (previouslyFocused instanceof HTMLElement) {\n previouslyFocused.focus();\n }\n };\n }, [variant]);\n\n const handleCancel = (): void => {\n close({ confirmed: false, reason: \"cancel\" });\n };\n\n const handleConfirm = (): void => {\n close({ confirmed: true });\n };\n\n const handleDismiss = (): void => {\n close({ confirmed: false, reason: \"dismiss\" });\n };\n\n const handleEscape = (event: KeyboardEvent<HTMLElement>): void => {\n if (!dismissible) {\n return;\n }\n\n event.preventDefault();\n handleDismiss();\n };\n\n const handleTab = (event: KeyboardEvent<HTMLElement>): void => {\n if (dialogRef.current === null) {\n return;\n }\n\n const focusable = getFocusableElements(dialogRef.current);\n\n if (focusable.length === 0) {\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement;\n\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n return;\n }\n\n if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>): void => {\n if (event.key === \"Escape\") {\n handleEscape(event);\n return;\n }\n\n if (event.key === \"Tab\") {\n handleTab(event);\n }\n };\n\n let describedBy: string | undefined;\n\n if (hasDescription) {\n describedBy = descriptionId;\n }\n\n return (\n <section\n aria-describedby={describedBy}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n data-variant={variant}\n onKeyDown={handleKeyDown}\n ref={dialogRef}\n role=\"dialog\"\n >\n <h2 id={titleId}>{input.title}</h2>\n\n {hasDescription && <p id={descriptionId}>{input.description}</p>}\n\n <button ref={cancelButtonRef} type=\"button\" onClick={handleCancel}>\n {cancelText}\n </button>\n\n <button ref={confirmButtonRef} type=\"button\" onClick={handleConfirm}>\n {confirmText}\n </button>\n\n {dismissible && (\n <button aria-label=\"Dismiss\" type=\"button\" onClick={handleDismiss}>\n Dismiss\n </button>\n )}\n </section>\n );\n}\n","import { createModal } from \"../registry\";\nimport { ConfirmModal } from \"./ConfirmModal\";\nimport type {\n ConfirmModalParams,\n ConfirmModalResult,\n} from \"./ConfirmModal.types\";\n\nexport const confirmModal = createModal<ConfirmModalParams, ConfirmModalResult>(\n {\n id: \"confirm\",\n component: ConfirmModal,\n },\n);\n","import type { ModalDismissReason } from \"../types\";\n\nexport class ModalDismissError extends Error {\n public readonly reason: ModalDismissReason;\n\n public constructor(reason: ModalDismissReason) {\n super(`Modal dismissed: ${reason}`);\n\n this.name = \"ModalDismissError\";\n this.reason = reason;\n }\n}\n","export class ModalRejectError extends Error {\n public readonly value: unknown;\n\n public constructor(value: unknown) {\n super(\"Modal rejected.\");\n\n this.name = \"ModalRejectError\";\n this.value = value;\n }\n}\n","import { createContext } from \"react\";\nimport type { StoreApi } from \"zustand\";\nimport type { ModalStore } from \"./modalStore.types\";\n\nexport const ModalStoreContext = createContext<\n StoreApi<ModalStore> | undefined\n>(undefined);\n","import { useContext } from \"react\";\nimport { useStore } from \"zustand\";\nimport { ModalStoreContext } from \"./ModalStoreContext\";\nimport type { StoreApi } from \"zustand\";\nimport type { ModalStore } from \"./modalStore.types\";\n\nexport function useModalStoreApi(): StoreApi<ModalStore> {\n const store = useContext(ModalStoreContext);\n\n if (store === undefined) {\n throw new Error(\"Modal store must be used within ModalProvider\");\n }\n\n return store;\n}\n\nexport function useModalStore<TSelected>(\n selector: (state: ModalStore) => TSelected,\n): TSelected {\n return useStore(useModalStoreApi(), selector);\n}\n","import type { StoreApi } from \"zustand\";\nimport type { ModalInstanceId } from \"../types\";\nimport type { ModalStore, ModalStoreActions } from \"./modalStore.types\";\n\ntype SetModalStore = StoreApi<ModalStore>[\"setState\"];\ntype GetModalStore = StoreApi<ModalStore>[\"getState\"];\n\nexport function createModalStoreActions(\n set: SetModalStore,\n get: GetModalStore,\n): ModalStoreActions {\n const removeTimerIds = new Map<\n ModalInstanceId,\n ReturnType<typeof globalThis.setTimeout>\n >();\n\n const clearRemoveTimer = (instanceId: ModalInstanceId): void => {\n const timerId = removeTimerIds.get(instanceId);\n\n if (timerId === undefined) {\n return;\n }\n\n globalThis.clearTimeout(timerId);\n removeTimerIds.delete(instanceId);\n };\n\n return {\n addModal: (modal) => {\n set((state) => ({\n modals: [...state.modals, { ...modal, status: \"open\" }],\n }));\n },\n allocateInstanceId: () => {\n const { nextInstanceIndex } = get();\n\n set({ nextInstanceIndex: nextInstanceIndex + 1 });\n\n return `modal-${String(nextInstanceIndex)}`;\n },\n dismissAll: (reason) => {\n const modals = get().modals.filter((item) => item.status === \"open\");\n\n for (const modal of modals) {\n modal.dismiss(reason);\n }\n\n set((state) => ({\n modals: state.modals.map((modal) => ({\n ...modal,\n status: \"closing\",\n })),\n }));\n },\n markModalClosing: (instanceId) => {\n set((state) => ({\n modals: state.modals.map((modal) => {\n if (modal.instanceId === instanceId) {\n return { ...modal, status: \"closing\" };\n }\n\n return modal;\n }),\n }));\n },\n scheduleRemove: (instanceId, delayMs) => {\n clearRemoveTimer(instanceId);\n\n if (delayMs <= 0) {\n get().removeModal(instanceId);\n return;\n }\n\n const timerId = globalThis.setTimeout(() => {\n removeTimerIds.delete(instanceId);\n get().removeModal(instanceId);\n }, delayMs);\n\n removeTimerIds.set(instanceId, timerId);\n },\n removeModal: (instanceId) => {\n clearRemoveTimer(instanceId);\n\n set((state) => ({\n modals: state.modals.filter((modal) => modal.instanceId !== instanceId),\n }));\n },\n clearModals: () => {\n get().clearRemoveTimers();\n\n set({ modals: [] });\n },\n clearRemoveTimers: () => {\n for (const timerId of removeTimerIds.values()) {\n globalThis.clearTimeout(timerId);\n }\n\n removeTimerIds.clear();\n },\n };\n}\n","import type { ModalStoreState } from \"./modalStore.types\";\n\nexport const MODAL_STORE_DEFAULTS: ModalStoreState = {\n modals: [],\n nextInstanceIndex: 0,\n};\n","import { createStore } from \"zustand/vanilla\";\nimport { createModalStoreActions } from \"./modalStore.actions\";\nimport { MODAL_STORE_DEFAULTS } from \"./modalStore.constants\";\nimport type { StoreApi } from \"zustand\";\nimport type { ModalStore } from \"./modalStore.types\";\n\nexport function createModalStore(): StoreApi<ModalStore> {\n return createStore<ModalStore>((set, get) => ({\n ...MODAL_STORE_DEFAULTS,\n ...createModalStoreActions(set, get),\n }));\n}\n","import { useState } from \"react\";\nimport { createModalStore } from \"./modalStore\";\nimport { ModalStoreContext } from \"./ModalStoreContext\";\nimport type { ReactNode } from \"react\";\nimport type { ModalStoreProviderProps } from \"./ModalStoreProvider.types\";\n\nexport function ModalStoreProvider({\n children,\n}: ModalStoreProviderProps): ReactNode {\n const [store] = useState(createModalStore);\n\n return (\n <ModalStoreContext.Provider value={store}>\n {children}\n </ModalStoreContext.Provider>\n );\n}\n","import { useModalStore } from \"./useModalStore\";\nimport type { ModalInstance } from \"./modalStore.types\";\n\nexport const useModals = (): Array<ModalInstance> =>\n useModalStore((state) => state.modals);\n","import { createContext } from \"react\";\nimport { confirmModal } from \"../confirm\";\nimport type { ModalRuntimeConfig } from \"./ModalRuntimeConfigContext.types\";\n\nexport const ModalRuntimeConfigContext = createContext<ModalRuntimeConfig>({\n closeDelayMs: 0,\n confirmModal,\n});\n","import { useContext } from \"react\";\nimport { ModalRuntimeConfigContext } from \"../runtime\";\nimport type { ModalRuntimeConfig } from \"../runtime\";\n\nexport function useModalRuntimeConfig(): ModalRuntimeConfig {\n return useContext(ModalRuntimeConfigContext);\n}\n","import type { ModalDismissReason } from \"../../types\";\n\nexport const DEFAULT_DISMISS_REASON: ModalDismissReason = \"dismiss\";\n","import { useCallback, useMemo } from \"react\";\nimport { ModalDismissError, ModalRejectError } from \"../../errors\";\nimport { useModalStoreApi } from \"../../store\";\nimport { useModalRuntimeConfig } from \"../useModalRuntimeConfig\";\nimport { DEFAULT_DISMISS_REASON } from \"./useModalManager.constants\";\nimport type { ModalInstance } from \"../../store\";\nimport type {\n ModalDefinition,\n ModalDismissReason,\n ModalInstanceId,\n} from \"../../types\";\nimport type { ModalHandle, ModalManager } from \"./useModalManager.types\";\n\nexport function useModalManager(): ModalManager {\n const store = useModalStoreApi();\n const { closeDelayMs, confirmModal } = useModalRuntimeConfig();\n\n const scheduleRemove = useCallback(\n (instanceId: ModalInstanceId) => {\n store.getState().scheduleRemove(instanceId, closeDelayMs);\n },\n [closeDelayMs, store],\n );\n\n const settleInstance = useCallback(\n (\n instanceId: ModalInstanceId,\n settle: (instance: ModalInstance) => void,\n ) => {\n const instance = store\n .getState()\n .modals.find((modal) => modal.instanceId === instanceId);\n\n if (instance === undefined || instance.status === \"closing\") {\n return;\n }\n\n store.getState().markModalClosing(instanceId);\n\n settle(instance);\n scheduleRemove(instanceId);\n },\n [scheduleRemove, store],\n );\n\n const dismiss = useCallback(\n (\n instanceId: ModalInstanceId,\n reason: ModalDismissReason = DEFAULT_DISMISS_REASON,\n ) => {\n settleInstance(instanceId, (instance) => {\n instance.dismiss(reason);\n });\n },\n [settleInstance],\n );\n\n const closeAll = useCallback(\n (reason?: ModalDismissReason) => {\n const dismissReason = reason ?? \"close-all\";\n\n const openInstanceIds = store\n .getState()\n .modals.filter((modal) => modal.status === \"open\")\n .map((modal) => modal.instanceId);\n\n store.getState().dismissAll(dismissReason);\n\n for (const instanceId of openInstanceIds) {\n scheduleRemove(instanceId);\n }\n },\n [scheduleRemove, store],\n );\n\n const open = useCallback(\n <TInput, TResult>(\n modal: ModalDefinition<TInput, TResult>,\n input: TInput,\n ): ModalHandle<TResult> => {\n const storeState = store.getState();\n const instanceId = storeState.allocateInstanceId();\n\n const result = new Promise<TResult>((resolve, reject) => {\n const Component = modal.component;\n\n const handleClose = (modalResult: TResult): void => {\n settleInstance(instanceId, () => {\n resolve(modalResult);\n });\n };\n\n const handleDismiss = (\n reason: ModalDismissReason = DEFAULT_DISMISS_REASON,\n ): void => {\n settleInstance(instanceId, () => {\n reject(new ModalDismissError(reason));\n });\n };\n\n const handleReject = (error: unknown): void => {\n settleInstance(instanceId, () => {\n reject(\n error instanceof Error ? error : new ModalRejectError(error),\n );\n });\n };\n\n storeState.addModal({\n instanceId,\n status: \"open\",\n definitionId: modal.id,\n render: () => (\n <Component\n close={handleClose}\n dismiss={handleDismiss}\n instanceId={instanceId}\n input={input}\n reject={handleReject}\n />\n ),\n dismiss: (reason) => {\n reject(new ModalDismissError(reason));\n },\n });\n });\n\n const dismissHandle = (reason?: ModalDismissReason): void => {\n dismiss(instanceId, reason);\n };\n\n return Object.assign(result, { dismiss: dismissHandle, instanceId });\n },\n [dismiss, settleInstance, store],\n );\n\n const confirm = useCallback<ModalManager[\"confirm\"]>(\n (params) => open(confirmModal, params),\n [confirmModal, open],\n );\n\n return useMemo(\n () => ({ closeAll, confirm, dismiss, open }),\n [closeAll, confirm, dismiss, open],\n );\n}\n","import { useModals } from \"../store\";\nimport type { ReactNode } from \"react\";\nimport type {\n ModalRendererProps,\n ModalViewportProps,\n} from \"./ModalViewport.types\";\n\nfunction DefaultModalRenderer({ children }: ModalRendererProps): ReactNode {\n return <>{children}</>;\n}\n\nexport function ModalViewport({\n renderer: Renderer = DefaultModalRenderer,\n}: ModalViewportProps): ReactNode {\n const modals = useModals();\n\n return (\n <>\n {modals.map((modal) => (\n <Renderer\n key={modal.instanceId}\n modal={{\n definitionId: modal.definitionId,\n instanceId: modal.instanceId,\n status: modal.status,\n }}\n >\n {modal.render()}\n </Renderer>\n ))}\n </>\n );\n}\n","import { useEffect } from \"react\";\nimport { useModalManager } from \"../hooks\";\nimport type { ReactNode } from \"react\";\nimport type { ModalController } from \"../registry\";\n\ninterface ModalRegistryBinderProps {\n controller: ModalController;\n}\n\nexport function ModalRegistryBinder(\n props: ModalRegistryBinderProps,\n): ReactNode {\n const { controller } = props;\n\n const manager = useModalManager();\n\n useEffect(() => {\n const unbind = controller.bind(manager);\n\n return () => {\n unbind();\n };\n }, [controller, manager]);\n\n return null;\n}\n","import type { ModalDismissReason } from \"../types\";\n\nexport const PROVIDER_UNMOUNT_DISMISS_REASON: ModalDismissReason =\n \"provider-unmount\";\n","import { useEffect } from \"react\";\nimport { useModalStoreApi } from \"../store\";\nimport { PROVIDER_UNMOUNT_DISMISS_REASON } from \"./ModalStoreCleanup.constants\";\n\nexport function ModalStoreCleanup(): null {\n const store = useModalStoreApi();\n\n useEffect(\n () => () => {\n store.getState().dismissAll(PROVIDER_UNMOUNT_DISMISS_REASON);\n store.getState().clearRemoveTimers();\n store.getState().clearModals();\n },\n [store],\n );\n\n return null;\n}\n","import { useMemo } from \"react\";\nimport { confirmModal as defaultConfirmModal } from \"../confirm\";\nimport { getModalRegistryController } from \"../registry/modalRegistryBinding\";\nimport { ModalRuntimeConfigContext } from \"../runtime\";\nimport { ModalStoreProvider } from \"../store\";\nimport { ModalViewport } from \"../viewport\";\nimport { ModalRegistryBinder } from \"./ModalRegistryBinder\";\nimport { ModalStoreCleanup } from \"./ModalStoreCleanup\";\nimport type { ReactNode } from \"react\";\nimport type { ModalRuntimeConfig } from \"../runtime\";\nimport type { ModalProviderProps } from \"./ModalProvider.types\";\n\nexport function ModalProvider(props: ModalProviderProps): ReactNode {\n const {\n children,\n closeDelayMs = 0,\n confirmModal = defaultConfirmModal,\n registry,\n renderer,\n } = props;\n const registryController =\n registry === undefined ? undefined : getModalRegistryController(registry);\n\n if (registry !== undefined && registryController === undefined) {\n throw new Error(\n \"ModalProvider registry must be created by createModalRegistry\",\n );\n }\n\n const runtimeConfig = useMemo<ModalRuntimeConfig>(\n () => ({ closeDelayMs, confirmModal }),\n [closeDelayMs, confirmModal],\n );\n\n return (\n <ModalStoreProvider>\n <ModalRuntimeConfigContext.Provider value={runtimeConfig}>\n {children}\n {registryController && (\n <ModalRegistryBinder controller={registryController} />\n )}\n <ModalViewport renderer={renderer} />\n <ModalStoreCleanup />\n </ModalRuntimeConfigContext.Provider>\n </ModalStoreProvider>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/registry/createModal.ts","../src/registry/createModalRegistry.constants.ts","../src/registry/createModalRegistry.ts","../src/confirm/ConfirmModal.constants.ts","../src/confirm/ConfirmModal.utils.ts","../src/confirm/ConfirmModal.tsx","../src/confirm/builtInConfirmModal.ts","../src/errors/ModalDismissError.ts","../src/errors/ModalRejectError.ts","../src/lifecycle/modalLifecycle.ts","../src/lifecycle/ModalLifecycleContext.ts","../src/lifecycle/useModalLifecycle.ts","../src/lifecycle/useModalLifecycleState.ts","../src/runtime/ModalRuntimeConfigContext.ts","../src/hooks/useModalRuntimeConfig.ts","../src/hooks/useModalManager/useModalManager.tsx","../src/viewport/ModalViewport.tsx","../src/provider/ModalRegistryBinder.tsx","../src/provider/useModalLifecycleOwner.ts","../src/provider/ModalProvider.tsx"],"names":["isNonEmptyArray","isDefined","result","createContext","useContext","confirmModal","jsx","useEffect","useRef","assertTrue","useMemo","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ModalOptions,\n RegisteredModalDefinition,\n} from \"./createModal.types\";\n\nfunction createGeneratedModalId(): string {\n return `modal-definition-${crypto.randomUUID()}`;\n}\n\nexport function createModal<TInput, TResult>(\n options: ModalOptions<TInput, TResult>,\n): RegisteredModalDefinition<TInput, TResult> {\n const definition = {\n ...options,\n id: options.id ?? createGeneratedModalId(),\n };\n\n return {\n ...definition,\n open: (manager, ...args) => manager.open(definition, ...args),\n };\n}\n","export const MODAL_REGISTRY_UNKNOWN_KEY_ERROR =\n \"Modal registry does not contain modal\";\nexport const MODAL_CONTROLLER_UNBOUND_ERROR =\n \"Modal registry is not bound to a mounted ModalProvider\";\n","import {\n assertTrue,\n hasProperty,\n isFunction,\n isNonEmptyArray,\n isObject,\n} from \"@okyrychenko-dev/type-utils\";\nimport {\n MODAL_CONTROLLER_UNBOUND_ERROR,\n MODAL_REGISTRY_UNKNOWN_KEY_ERROR,\n} from \"./createModalRegistry.constants\";\nimport type { ModalHandle, ModalManager } from \"../hooks\";\nimport type {\n ModalDismissReason,\n ModalInstanceId,\n ModalOpenArgs,\n} from \"../types\";\nimport type {\n ModalRegistry,\n ModalRegistryDefinitions,\n ModalRegistryInput,\n} from \"./createModalRegistry.types\";\n\nconst MODAL_REGISTRY_ATTACH = Symbol(\"modal-registry-attach\");\n\nexport interface ModalRegistryAttachable {\n [MODAL_REGISTRY_ATTACH](manager: ModalManager): VoidFunction;\n}\n\nexport function isModalRegistryAttachable(\n value: unknown,\n): value is ModalRegistryAttachable {\n return isObject(value) && isFunction(value[MODAL_REGISTRY_ATTACH]);\n}\n\nexport function attachModalRegistry(\n registry: ModalRegistryAttachable,\n manager: ModalManager,\n): VoidFunction {\n return registry[MODAL_REGISTRY_ATTACH](manager);\n}\n\nexport function createModalRegistry<\n const TDefinitions extends ModalRegistryDefinitions,\n>(definitions: TDefinitions): ModalRegistry<TDefinitions> {\n let attachments: Array<{ manager: ModalManager }> = [];\n\n const activeManager = (): ModalManager => {\n assertTrue(isNonEmptyArray(attachments), MODAL_CONTROLLER_UNBOUND_ERROR);\n\n return attachments[attachments.length - 1].manager;\n };\n\n const attach = (manager: ModalManager): VoidFunction => {\n const attachment = { manager };\n attachments.push(attachment);\n\n return () => {\n attachments = attachments.filter((candidate) => candidate !== attachment);\n };\n };\n\n function open<TKey extends keyof TDefinitions & string>(\n key: TKey,\n ...args: ModalOpenArgs<ModalRegistryInput<TDefinitions[TKey]>>\n ): ReturnType<TDefinitions[TKey][\"open\"]>;\n function open(key: string, input?: unknown): ModalHandle<unknown> {\n assertTrue(\n hasProperty(definitions, key),\n () => `${MODAL_REGISTRY_UNKNOWN_KEY_ERROR}: ${key}`,\n );\n\n return definitions[key].open(activeManager(), input);\n }\n\n const registry: ModalRegistry<TDefinitions> & {\n [MODAL_REGISTRY_ATTACH]: (manager: ModalManager) => VoidFunction;\n } = {\n closeAll: (reason?: ModalDismissReason) => {\n activeManager().closeAll(reason);\n },\n confirm: (params: Parameters<ModalManager[\"confirm\"]>[0]) => {\n return activeManager().confirm(params);\n },\n dismiss: (instanceId: ModalInstanceId, reason?: ModalDismissReason) => {\n activeManager().dismiss(instanceId, reason);\n },\n isReady: () => isNonEmptyArray(attachments),\n open,\n [MODAL_REGISTRY_ATTACH]: attach,\n };\n\n return registry;\n}\n","export const DEFAULT_CANCEL_TEXT = \"Cancel\";\nexport const DEFAULT_CONFIRM_TEXT = \"Confirm\";\n\nexport const CONFIRM_MODAL_FOCUSABLE_SELECTOR = [\n \"a[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(\", \");\n","import { CONFIRM_MODAL_FOCUSABLE_SELECTOR } from \"./ConfirmModal.constants\";\n\nexport function getFocusableElements(\n container: HTMLElement,\n): Array<HTMLElement> {\n return Array.from(\n container.querySelectorAll<HTMLElement>(CONFIRM_MODAL_FOCUSABLE_SELECTOR),\n );\n}\n","import {\n isDefined,\n isInstanceOf,\n isNonEmptyArray,\n} from \"@okyrychenko-dev/type-utils\";\nimport { useEffect, useId, useRef } from \"react\";\nimport {\n DEFAULT_CANCEL_TEXT,\n DEFAULT_CONFIRM_TEXT,\n} from \"./ConfirmModal.constants\";\nimport { getFocusableElements } from \"./ConfirmModal.utils\";\nimport type { Optional } from \"@okyrychenko-dev/type-utils\";\nimport type { KeyboardEvent, ReactNode } from \"react\";\nimport type { ModalComponentProps } from \"../types\";\nimport type {\n ConfirmModalParams,\n ConfirmModalResult,\n} from \"./ConfirmModal.types\";\n\nexport function ConfirmModal(\n props: ModalComponentProps<ConfirmModalParams, ConfirmModalResult>,\n): ReactNode {\n const { close, input } = props;\n\n const cancelText = input.cancelText ?? DEFAULT_CANCEL_TEXT;\n const confirmText = input.confirmText ?? DEFAULT_CONFIRM_TEXT;\n const variant = input.variant ?? \"default\";\n const dismissible = input.dismissible !== false;\n const hasDescription = isDefined(input.description);\n const titleId = useId();\n const descriptionId = useId();\n const dialogRef = useRef<HTMLElement>(null);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n const confirmButtonRef = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n const previouslyFocused = document.activeElement;\n\n // Destructive confirms focus the safe action so an accidental Enter does not confirm.\n let initialFocusRef = confirmButtonRef;\n\n if (variant === \"danger\") {\n initialFocusRef = cancelButtonRef;\n }\n\n initialFocusRef.current?.focus();\n\n return () => {\n if (isInstanceOf(previouslyFocused, HTMLElement)) {\n previouslyFocused.focus();\n }\n };\n }, [variant]);\n\n const handleCancel = (): void => {\n close({ confirmed: false, reason: \"cancel\" });\n };\n\n const handleConfirm = (): void => {\n close({ confirmed: true });\n };\n\n const handleDismiss = (): void => {\n close({ confirmed: false, reason: \"dismiss\" });\n };\n\n const handleEscape = (event: KeyboardEvent<HTMLElement>): void => {\n if (!dismissible) {\n return;\n }\n\n event.preventDefault();\n handleDismiss();\n };\n\n const handleTab = (event: KeyboardEvent<HTMLElement>): void => {\n if (!isDefined(dialogRef.current)) {\n return;\n }\n\n const focusable = getFocusableElements(dialogRef.current);\n\n if (!isNonEmptyArray(focusable)) {\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement;\n\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n return;\n }\n\n if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>): void => {\n if (event.key === \"Escape\") {\n handleEscape(event);\n return;\n }\n\n if (event.key === \"Tab\") {\n handleTab(event);\n }\n };\n\n let describedBy: Optional<string>;\n\n if (hasDescription) {\n describedBy = descriptionId;\n }\n\n return (\n <section\n aria-describedby={describedBy}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n data-variant={variant}\n onKeyDown={handleKeyDown}\n ref={dialogRef}\n role=\"dialog\"\n >\n <h2 id={titleId}>{input.title}</h2>\n\n {hasDescription && <p id={descriptionId}>{input.description}</p>}\n\n <button ref={cancelButtonRef} type=\"button\" onClick={handleCancel}>\n {cancelText}\n </button>\n\n <button ref={confirmButtonRef} type=\"button\" onClick={handleConfirm}>\n {confirmText}\n </button>\n\n {dismissible && (\n <button aria-label=\"Dismiss\" type=\"button\" onClick={handleDismiss}>\n Dismiss\n </button>\n )}\n </section>\n );\n}\n","import { createModal } from \"../registry\";\nimport { ConfirmModal } from \"./ConfirmModal\";\nimport type {\n ConfirmModalParams,\n ConfirmModalResult,\n} from \"./ConfirmModal.types\";\n\nexport const confirmModal = createModal<ConfirmModalParams, ConfirmModalResult>(\n {\n id: \"confirm\",\n component: ConfirmModal,\n },\n);\n","import type { ModalDismissReason } from \"../types\";\n\nexport class ModalDismissError extends Error {\n public readonly reason: ModalDismissReason;\n\n public constructor(reason: ModalDismissReason) {\n super(`Modal dismissed: ${reason}`);\n\n this.name = \"ModalDismissError\";\n this.reason = reason;\n }\n}\n","export class ModalRejectError extends Error {\n public readonly value: unknown;\n\n public constructor(value: unknown) {\n super(\"Modal rejected.\");\n\n this.name = \"ModalRejectError\";\n this.value = value;\n }\n}\n","import { isDefined, isError } from \"@okyrychenko-dev/type-utils\";\nimport { createElement } from \"react\";\nimport { ModalDismissError, ModalRejectError } from \"../errors\";\nimport type {\n ModalDefinition,\n ModalDismissReason,\n ModalInstanceId,\n ModalOpenArgs,\n} from \"../types\";\nimport type {\n CreateModalLifecycleOptions,\n ModalLifecycle,\n ModalLifecycleHandle,\n ModalLifecycleInstance,\n ModalLifecycleState,\n} from \"./modalLifecycle.types\";\n\nexport function createModalLifecycle(\n options: CreateModalLifecycleOptions,\n): ModalLifecycle {\n let nextInstanceIndex = 0;\n let instances: Array<ModalLifecycleInstance> = [];\n let disposed = false;\n let closeDelayMs = options.closeDelayMs;\n const serverSnapshot: ModalLifecycleState = { instances: [] };\n let snapshot = serverSnapshot;\n\n const observers = new Set<VoidFunction>();\n\n const removalTimers = new Map<\n ModalInstanceId,\n ReturnType<typeof globalThis.setTimeout>\n >();\n const dismissers = new Map<\n ModalInstanceId,\n (reason?: ModalDismissReason) => void\n >();\n\n const notifyObservers = (): void => {\n for (const observer of observers) {\n observer();\n }\n };\n\n const publishState = (): void => {\n if (disposed) {\n return;\n }\n\n snapshot = { instances: [...instances] };\n notifyObservers();\n };\n\n const removeInstance = (instanceId: ModalInstanceId): void => {\n const timer = removalTimers.get(instanceId);\n\n if (isDefined(timer)) {\n globalThis.clearTimeout(timer);\n removalTimers.delete(instanceId);\n }\n\n dismissers.delete(instanceId);\n\n instances = instances.filter(\n (candidate) => candidate.instanceId !== instanceId,\n );\n publishState();\n };\n\n const settleInstance = (\n instanceId: ModalInstanceId,\n settle: VoidFunction,\n ): void => {\n const instance = instances.find(\n (candidate) => candidate.instanceId === instanceId,\n );\n\n if (!isDefined(instance) || instance.status === \"closing\") {\n return;\n }\n\n instances = instances.map((candidate): ModalLifecycleInstance => {\n if (candidate.instanceId === instanceId) {\n return { ...candidate, status: \"closing\" };\n }\n\n return candidate;\n });\n publishState();\n settle();\n\n if (closeDelayMs <= 0) {\n removeInstance(instanceId);\n return;\n }\n\n const timer = globalThis.setTimeout(() => {\n removeInstance(instanceId);\n }, closeDelayMs);\n removalTimers.set(instanceId, timer);\n };\n\n const dismissOpenInstances = (reason: ModalDismissReason): void => {\n const openInstanceIds = instances\n .filter((instance) => instance.status === \"open\")\n .map((instance) => instance.instanceId);\n\n for (const instanceId of openInstanceIds) {\n dismissers.get(instanceId)?.(reason);\n }\n };\n\n return {\n closeAll: (reason = \"close-all\") => {\n dismissOpenInstances(reason);\n },\n dispose: () => {\n if (disposed) {\n return;\n }\n\n disposed = true;\n dismissOpenInstances(\"provider-unmount\");\n\n for (const timer of removalTimers.values()) {\n globalThis.clearTimeout(timer);\n }\n\n removalTimers.clear();\n dismissers.clear();\n instances = [];\n snapshot = { instances: [] };\n notifyObservers();\n observers.clear();\n },\n dismiss: (instanceId, reason) => {\n dismissers.get(instanceId)?.(reason);\n },\n getSnapshot: () => snapshot,\n getServerSnapshot: () => serverSnapshot,\n open: <TInput, TResult>(\n modal: ModalDefinition<TInput, TResult>,\n ...args: ModalOpenArgs<TInput>\n ): ModalLifecycleHandle<TResult> => {\n const input = args[0];\n const instanceId = `modal-${String(nextInstanceIndex)}`;\n nextInstanceIndex += 1;\n\n if (disposed) {\n const result = Promise.reject<TResult>(\n new ModalDismissError(\"provider-unmount\"),\n );\n\n return Object.assign(result, {\n dismiss: () => undefined,\n instanceId,\n });\n }\n\n const result = new Promise<TResult>((resolve, reject) => {\n const dismiss = (reason: ModalDismissReason = \"dismiss\"): void => {\n settleInstance(instanceId, () => {\n reject(new ModalDismissError(reason));\n });\n };\n dismissers.set(instanceId, dismiss);\n\n const instance: ModalLifecycleInstance = {\n definitionId: modal.id,\n instanceId,\n render: () =>\n createElement(modal.component, {\n close: (modalResult) => {\n settleInstance(instanceId, () => {\n resolve(modalResult);\n });\n },\n dismiss,\n input,\n instanceId,\n reject: (error) => {\n settleInstance(instanceId, () => {\n reject(isError(error) ? error : new ModalRejectError(error));\n });\n },\n }),\n status: \"open\",\n };\n\n instances = [...instances, instance];\n publishState();\n });\n\n return Object.assign(result, {\n dismiss: (reason?: ModalDismissReason) => {\n dismissers.get(instanceId)?.(reason);\n },\n instanceId,\n });\n },\n setCloseDelayMs: (nextCloseDelayMs: number): void => {\n closeDelayMs = nextCloseDelayMs;\n },\n subscribe: (observer): VoidFunction => {\n if (disposed) {\n return () => undefined;\n }\n\n observers.add(observer);\n\n return () => {\n observers.delete(observer);\n };\n },\n };\n}\n","import { createContext } from \"react\";\nimport type { Optional } from \"@okyrychenko-dev/type-utils\";\nimport type { ModalLifecycle } from \"./modalLifecycle.types\";\n\nexport const ModalLifecycleContext =\n createContext<Optional<ModalLifecycle>>(undefined);\n","import { assertDefined } from \"@okyrychenko-dev/type-utils\";\nimport { useContext } from \"react\";\nimport { ModalLifecycleContext } from \"./ModalLifecycleContext\";\nimport type { ModalLifecycle } from \"./modalLifecycle.types\";\n\nexport function useModalLifecycle(): ModalLifecycle {\n const lifecycle = useContext(ModalLifecycleContext);\n\n assertDefined(lifecycle, \"Modal lifecycle must be used within ModalProvider\");\n\n return lifecycle;\n}\n","import { useSyncExternalStore } from \"react\";\nimport { useModalLifecycle } from \"./useModalLifecycle\";\nimport type { UseModalLifecycleStateReturn } from \"./useModalLifecycleState.types\";\n\nexport function useModalLifecycleState(): UseModalLifecycleStateReturn {\n const lifecycle = useModalLifecycle();\n\n return useSyncExternalStore(\n lifecycle.subscribe,\n lifecycle.getSnapshot,\n lifecycle.getServerSnapshot,\n );\n}\n","import { createContext } from \"react\";\nimport { confirmModal } from \"../confirm\";\nimport type { ModalRuntimeConfig } from \"./ModalRuntimeConfigContext.types\";\n\nexport const ModalRuntimeConfigContext = createContext<ModalRuntimeConfig>({\n closeDelayMs: 0,\n confirmModal,\n});\n","import { useContext } from \"react\";\nimport { ModalRuntimeConfigContext } from \"../runtime\";\nimport type { ModalRuntimeConfig } from \"../runtime\";\n\nexport function useModalRuntimeConfig(): ModalRuntimeConfig {\n return useContext(ModalRuntimeConfigContext);\n}\n","import { useCallback, useMemo } from \"react\";\nimport { useModalLifecycle } from \"../../lifecycle\";\nimport { useModalRuntimeConfig } from \"../useModalRuntimeConfig\";\nimport type { ModalManager } from \"./useModalManager.types\";\n\nexport function useModalManager(): ModalManager {\n const lifecycle = useModalLifecycle();\n const { confirmModal } = useModalRuntimeConfig();\n\n const confirm = useCallback<ModalManager[\"confirm\"]>(\n (params) => lifecycle.open(confirmModal, params),\n [confirmModal, lifecycle],\n );\n\n return useMemo(\n () => ({\n closeAll: lifecycle.closeAll,\n confirm,\n dismiss: lifecycle.dismiss,\n open: lifecycle.open,\n }),\n [confirm, lifecycle],\n );\n}\n","import { useModalLifecycleState } from \"../lifecycle\";\nimport type { ReactNode } from \"react\";\nimport type {\n ModalRendererProps,\n ModalViewportProps,\n} from \"./ModalViewport.types\";\n\nfunction DefaultModalRenderer({ children }: ModalRendererProps): ReactNode {\n return <>{children}</>;\n}\n\nexport function ModalViewport({\n renderer: Renderer = DefaultModalRenderer,\n}: ModalViewportProps): ReactNode {\n const { instances: modals } = useModalLifecycleState();\n\n return (\n <>\n {modals.map((modal) => (\n <Renderer\n key={modal.instanceId}\n modal={{\n definitionId: modal.definitionId,\n instanceId: modal.instanceId,\n status: modal.status,\n }}\n >\n {modal.render()}\n </Renderer>\n ))}\n </>\n );\n}\n","import { type ReactNode, useEffect } from \"react\";\nimport { useModalManager } from \"../hooks\";\nimport { attachModalRegistry } from \"../registry/createModalRegistry\";\nimport type { ModalRegistryAttachable } from \"../registry/createModalRegistry\";\n\ninterface ModalRegistryBinderProps {\n registry: ModalRegistryAttachable;\n}\n\nexport function ModalRegistryBinder(\n props: ModalRegistryBinderProps,\n): ReactNode {\n const { registry } = props;\n\n const manager = useModalManager();\n\n useEffect(() => {\n const unbind = attachModalRegistry(registry, manager);\n\n return () => {\n unbind();\n };\n }, [registry, manager]);\n\n return null;\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { createModalLifecycle } from \"../lifecycle/modalLifecycle\";\nimport type { ModalLifecycle } from \"../lifecycle/modalLifecycle.types\";\n\nexport function useModalLifecycleOwner(closeDelayMs: number): ModalLifecycle {\n const [lifecycle] = useState(() => createModalLifecycle({ closeDelayMs }));\n const mountGeneration = useRef(0);\n\n useEffect(() => {\n lifecycle.setCloseDelayMs(closeDelayMs);\n }, [closeDelayMs, lifecycle]);\n\n useEffect(() => {\n mountGeneration.current += 1;\n\n return () => {\n mountGeneration.current += 1;\n const cleanupGeneration = mountGeneration.current;\n\n globalThis.queueMicrotask(() => {\n if (mountGeneration.current === cleanupGeneration) {\n lifecycle.dispose();\n }\n });\n };\n }, [lifecycle]);\n\n return lifecycle;\n}\n","import { assertTrue, isDefined } from \"@okyrychenko-dev/type-utils\";\nimport { useMemo } from \"react\";\nimport { confirmModal as defaultConfirmModal } from \"../confirm/builtInConfirmModal\";\nimport { ModalLifecycleContext } from \"../lifecycle/ModalLifecycleContext\";\nimport { isModalRegistryAttachable } from \"../registry/createModalRegistry\";\nimport { ModalRuntimeConfigContext } from \"../runtime/ModalRuntimeConfigContext\";\nimport { ModalViewport } from \"../viewport/ModalViewport\";\nimport { ModalRegistryBinder } from \"./ModalRegistryBinder\";\nimport { useModalLifecycleOwner } from \"./useModalLifecycleOwner\";\nimport type { ReactNode } from \"react\";\nimport type { ModalRuntimeConfig } from \"../runtime/ModalRuntimeConfigContext.types\";\nimport type { ModalProviderProps } from \"./ModalProvider.types\";\n\nexport function ModalProvider(props: ModalProviderProps): ReactNode {\n const {\n children,\n closeDelayMs = 0,\n confirmModal = defaultConfirmModal,\n registry,\n renderer,\n } = props;\n\n if (isDefined(registry)) {\n assertTrue(\n isModalRegistryAttachable(registry),\n \"ModalProvider registry must be created by createModalRegistry\",\n );\n }\n\n const runtimeConfig = useMemo<ModalRuntimeConfig>(\n () => ({ closeDelayMs, confirmModal }),\n [closeDelayMs, confirmModal],\n );\n\n const lifecycle = useModalLifecycleOwner(closeDelayMs);\n\n return (\n <ModalLifecycleContext.Provider value={lifecycle}>\n <ModalRuntimeConfigContext.Provider value={runtimeConfig}>\n {children}\n {isDefined(registry) && <ModalRegistryBinder registry={registry} />}\n <ModalViewport renderer={renderer} />\n </ModalRuntimeConfigContext.Provider>\n </ModalLifecycleContext.Provider>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@okyrychenko-dev/react-modal-manager",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed modal/dialog lifecycle manager for React",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -8,40 +8,29 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
},
|
|
16
21
|
"sideEffects": false,
|
|
17
22
|
"files": [
|
|
18
23
|
"dist",
|
|
19
24
|
"README.md",
|
|
25
|
+
"CHANGELOG.md",
|
|
20
26
|
"LICENSE"
|
|
21
27
|
],
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsup",
|
|
24
|
-
"dev": "tsup --watch",
|
|
25
|
-
"clean": "rm -rf dist",
|
|
26
|
-
"prepublishOnly": "npm run clean && npm run build",
|
|
27
|
-
"typecheck": "tsc --noEmit",
|
|
28
|
-
"lint": "eslint src --ext .ts,.tsx",
|
|
29
|
-
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
30
|
-
"check": "npm run lint && npm run typecheck && npm run test:run && npm run build",
|
|
31
|
-
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
32
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
33
|
-
"test": "vitest",
|
|
34
|
-
"test:run": "vitest run",
|
|
35
|
-
"storybook": "storybook dev -p 6006",
|
|
36
|
-
"build-storybook": "storybook build"
|
|
37
|
-
},
|
|
38
28
|
"keywords": [
|
|
39
29
|
"react",
|
|
40
30
|
"modal",
|
|
41
31
|
"dialog",
|
|
42
32
|
"promise",
|
|
43
|
-
"typescript"
|
|
44
|
-
"zustand"
|
|
33
|
+
"typescript"
|
|
45
34
|
],
|
|
46
35
|
"author": "Oleksii Kyrychenko alexey.kirichenko@gmail.com",
|
|
47
36
|
"license": "MIT",
|
|
@@ -57,10 +46,10 @@
|
|
|
57
46
|
"access": "public"
|
|
58
47
|
},
|
|
59
48
|
"peerDependencies": {
|
|
60
|
-
"react": "^18.0.0 || ^19.0.0"
|
|
61
|
-
"zustand": "^5.0.0"
|
|
49
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
62
50
|
},
|
|
63
51
|
"devDependencies": {
|
|
52
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
64
53
|
"@eslint/js": "^9.39.1",
|
|
65
54
|
"@storybook/addon-docs": "10.2.16",
|
|
66
55
|
"@storybook/react-vite": "10.2.16",
|
|
@@ -69,9 +58,11 @@
|
|
|
69
58
|
"@testing-library/react": "^16.3.0",
|
|
70
59
|
"@types/node": "^24.10.4",
|
|
71
60
|
"@types/react": "^19.2.5",
|
|
61
|
+
"@types/react-dom": "^19.2.7",
|
|
72
62
|
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
73
63
|
"@typescript-eslint/parser": "^8.46.4",
|
|
74
|
-
"@vitest/coverage-v8": "^4.
|
|
64
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
65
|
+
"esbuild": "0.27.7",
|
|
75
66
|
"eslint": "^9.39.1",
|
|
76
67
|
"eslint-config-prettier": "^10.1.8",
|
|
77
68
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -79,6 +70,7 @@
|
|
|
79
70
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
80
71
|
"happy-dom": "^20.0.10",
|
|
81
72
|
"prettier": "^3.6.2",
|
|
73
|
+
"publint": "^0.3.24",
|
|
82
74
|
"react": "^19.2.0",
|
|
83
75
|
"react-dom": "^19.2.0",
|
|
84
76
|
"remark-gfm": "^4.0.1",
|
|
@@ -86,7 +78,30 @@
|
|
|
86
78
|
"tsup": "^8.5.1",
|
|
87
79
|
"typescript": "^5.3.3",
|
|
88
80
|
"typescript-eslint": "^8.46.4",
|
|
89
|
-
"vitest": "^4.
|
|
90
|
-
|
|
81
|
+
"vitest": "^4.1.11"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"@okyrychenko-dev/type-utils": "^0.1.2"
|
|
85
|
+
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "tsup",
|
|
88
|
+
"benchmark:lifecycle": "pnpm run build && NODE_ENV=production node scripts/benchmark-lifecycle.mjs",
|
|
89
|
+
"competitive:check": "node scripts/check-competitive-package.mjs",
|
|
90
|
+
"package:check": "node scripts/check-packed-package.mjs && attw --pack . && publint",
|
|
91
|
+
"release:check": "pnpm run check && pnpm run build-storybook && pnpm run package:check",
|
|
92
|
+
"dev": "tsup --watch",
|
|
93
|
+
"clean": "rm -rf dist",
|
|
94
|
+
"typecheck": "tsc --noEmit",
|
|
95
|
+
"typecheck:examples": "tsc --project tsconfig.examples.json",
|
|
96
|
+
"lint": "eslint src scripts --ext .ts,.tsx,.mjs",
|
|
97
|
+
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
98
|
+
"check": "pnpm run lint && pnpm run format:check && pnpm run typecheck && pnpm run typecheck:examples && pnpm run test:run && pnpm run build",
|
|
99
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\" \"scripts/**/*.{mjs,ts}\" \"*.{json,ts,mjs}\" \".github/workflows/*.yml\"",
|
|
100
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\" \"scripts/**/*.{mjs,ts}\" \"*.{json,ts,mjs}\" \".github/workflows/*.yml\"",
|
|
101
|
+
"test": "vitest",
|
|
102
|
+
"test:run": "vitest run",
|
|
103
|
+
"test:coverage": "vitest run --coverage",
|
|
104
|
+
"storybook": "storybook dev -p 6006",
|
|
105
|
+
"build-storybook": "storybook build"
|
|
91
106
|
}
|
|
92
|
-
}
|
|
107
|
+
}
|