{"version":3,"file":"dialog.mjs","names":[],"sources":["../src/dialog/dialog.context.ts","../src/dialog/dialog.model.ts","../src/dialog/dialog.store.ts","../src/dialog/use-dialogs.ts","../src/dialog/components/dialogs.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { DialogModel } from \"./dialog.model\";\nimport type { DialogStore } from \"./dialog.store\";\n\nexport const dialogStoreContext = createContext<DialogStore | undefined>(undefined);\nexport const useDialogStore = () => {\n  const context = useContext(dialogStoreContext);\n  if (!context) {\n    throw new Error(\"Dialog store context not available. Are you using the <Dialogs /> component?\");\n  }\n  return context;\n};\n\nexport const DialogStoreProvider = dialogStoreContext.Provider;\n\nexport const dialogContext = createContext<DialogModel | undefined>(undefined);\nexport const useDialogContext = () => {\n  const context = useContext(dialogContext);\n  if (!context) {\n    throw new Error(\"Dialog context not available. Are you using <DialogProvider /> ?\");\n  }\n  return context;\n};\n\nexport const useDialogContextIfAvailable = () => useContext(dialogContext);\n\nexport const DialogProvider = dialogContext.Provider;\n","import { makeAutoObservable } from \"mobx\";\nimport type { DialogStore } from \"./dialog.store\";\nimport type { AnyComponent, DialogModelConfig, DialogState } from \"./dialog.types\";\n\nexport class DialogModel {\n  readonly id: string;\n  readonly component: AnyComponent;\n  readonly props?: React.ComponentProps<AnyComponent>;\n\n  openedAt = 0;\n  previouslyFocusedElement: HTMLElement | null = null;\n\n  state!: DialogState;\n\n  constructor(\n    readonly store: DialogStore,\n    readonly config: DialogModelConfig,\n  ) {\n    this.id = config.id ?? btoa(Math.random().toString()).substring(3, 12);\n    this.component = config.component;\n    this.props = config.props;\n\n    this.setState(config.initialState ?? \"closed\");\n\n    makeAutoObservable(this, {\n      id: false,\n      component: false,\n      props: false,\n      openedAt: false,\n      previouslyFocusedElement: false,\n    });\n  }\n\n  close(closeImmediately?: boolean): void {\n    this.setState(closeImmediately ? \"closed\" : \"closing\");\n  }\n\n  open(openImmediately?: boolean): void {\n    this.setState(openImmediately ? \"opened\" : \"opening\");\n  }\n\n  setState(state: DialogState): void {\n    if (this.state === state) return;\n\n    this.state = state;\n    if (state === \"opened\" || state === \"opening\") {\n      this.openedAt = Date.now();\n      if (state === \"opening\") {\n        this.previouslyFocusedElement =\n          document.activeElement instanceof HTMLElement ? document.activeElement : null;\n      }\n    } else if (state === \"closed\") {\n      this.previouslyFocusedElement?.focus();\n      if (this.config.removeOnClosed) {\n        this.store.dialogs.delete(this.id);\n      }\n      this.previouslyFocusedElement = null;\n    }\n  }\n}\n","import { makeAutoObservable } from \"mobx\";\nimport { DialogModel } from \"./dialog.model\";\nimport type { AnyComponent, DialogComponentAndProps, DialogModelConfig } from \"./dialog.types\";\n\nexport class DialogStore {\n  dialogs = new Map<string, DialogModel>();\n\n  get openDialogs(): DialogModel[] {\n    return [...this.dialogs.values()]\n      .filter((d) => d.state !== \"closed\")\n      .sort((d1, d2) => d1.openedAt - d2.openedAt);\n  }\n\n  get activeDialog(): DialogModel | undefined {\n    return this.openDialogs.at(-1);\n  }\n\n  constructor() {\n    makeAutoObservable(this);\n  }\n\n  add(config: DialogModelConfig): DialogModel {\n    const dialogModel = new DialogModel(this, config);\n    this.dialogs.set(dialogModel.id, dialogModel);\n    return dialogModel;\n  }\n\n  open<C extends AnyComponent>(...args: DialogComponentAndProps<C>): DialogModel {\n    const [component, props] = args;\n    return this.add({\n      component,\n      props,\n      removeOnClosed: true,\n      initialState: \"opening\",\n    });\n  }\n\n  close(closeImmediately?: boolean): void {\n    this.activeDialog?.close(closeImmediately);\n  }\n}\n","import { useRef } from \"react\";\nimport { DialogStore } from \"./dialog.store\";\n\nexport const useDialogs = (store?: DialogStore): DialogStore => {\n  const storeRef = useRef<DialogStore | undefined>(store);\n  if (!storeRef.current) {\n    storeRef.current = new DialogStore();\n  }\n  return storeRef.current;\n};\n","import { observer } from \"mobx-react-lite\";\nimport { DialogProvider, DialogStoreProvider } from \"../dialog.context\";\nimport type { DialogModel } from \"../dialog.model\";\nimport type { DialogStore } from \"../dialog.store\";\nimport { useDialogs } from \"../use-dialogs\";\n\nexport interface MobxDialogsProps {\n  store?: DialogStore;\n}\n\nexport const MobxDialogs = observer(({ store }: MobxDialogsProps) => {\n  const dialogStore = useDialogs(store);\n\n  return (\n    <DialogStoreProvider value={dialogStore}>\n      {dialogStore.openDialogs.map((dialog) => {\n        return <MobxDialog key={dialog.id} dialog={dialog} />;\n      })}\n    </DialogStoreProvider>\n  );\n});\n\nexport interface MobxDialogProps {\n  dialog: DialogModel;\n}\n\nexport const MobxDialog = observer(({ dialog }: MobxDialogProps) => {\n  const { component: DialogComponent, props: dialogProps } = dialog;\n  return (\n    <DialogProvider value={dialog}>\n      <DialogComponent {...dialogProps} />\n    </DialogProvider>\n  );\n});\n"],"mappings":"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"}