{"version":3,"file":"overlays.cjs","names":[],"sources":["../../src/overlays.ts"],"sourcesContent":["/**\n * @deijose/nix-ionic / overlays.ts\n *\n * Reactive overlay controllers for Nix.js following the `create*` pattern\n * (`createStore`, `createRouter`, `createForm` → `createToast`, `createAlert`, etc.).\n *\n * Each controller provides:\n *   - `presented: Signal<boolean>` — reactive presentation state\n *   - `result: Signal<OverlayEventDetail | null>` — dismiss event detail\n *   - `present(opts)` — creates + presents the overlay\n *   - `dismiss(data?, role?)` — dismisses the active overlay\n *   - `dispose()` — transactional cleanup, dismisses if still presented\n *\n * Stale-result protection: only the most recent `present()` call's dismiss\n * event updates the result signal. Latest-wins: presenting a new overlay\n * dismisses the previous one.\n *\n * @example Function component (preferred)\n * ```ts\n * import { signal, html } from \"@deijose/nix-js\";\n * import { createToast, createAlert } from \"@deijose/nix-ionic\";\n *\n * function SettingsPage() {\n *   // Create overlay controllers — signals close over function scope\n *   const toast = createToast();\n *   const alert = createAlert();\n *\n *   const save = async () => {\n *     // Use withLoading for async tasks\n *     const ok = await withLoading({ message: \"Saving...\" }, async () => {\n *       await fetch(\"/api/settings\", { method: \"POST\" });\n *     });\n *     toast.present({ message: \"Saved!\", duration: 1500 });\n *   };\n *\n *   const deleteAccount = () => {\n *     // confirm() returns a Promise<boolean>\n *     confirm({\n *       header: \"Delete account\",\n *       message: \"This cannot be undone.\",\n *       confirmText: \"Delete\",\n *     }).then((yes) => {\n *       if (yes) alert.present({ header: \"Done\", message: \"Account deleted\" });\n *     });\n *   };\n *\n *   return html`\n *     <ion-content>\n *       <ion-button @click=${save}>Save</ion-button>\n *       <ion-button color=\"danger\" @click=${deleteAccount}>Delete</ion-button>\n *     </ion-content>\n *   `;\n * }\n * ```\n *\n * @example Class component with lifecycle cleanup\n * ```ts\n * import { NixComponent, html, signal } from \"@deijose/nix-js\";\n * import { createLoading, IonPage } from \"@deijose/nix-ionic\";\n *\n * class ProfilePage extends IonPage {\n *   private loading = createLoading();\n *   private data = signal<unknown>(null);\n *\n *   override async onMount() {\n *     // withLoading auto-dismisses on settle or error\n *     const result = await withLoading(\n *       { message: \"Loading profile...\" },\n *       () => fetch(\"/api/profile\").then(r => r.json()),\n *     );\n *     this.data.value = result;\n *   }\n *\n *   override onUnmount() {\n *     // Dispose all overlay controllers to prevent leaks\n *     this.loading.dispose();\n *   }\n *\n *   override render() {\n *     return html`\n *       <ion-content>\n *         <p>${() => JSON.stringify(this.data.value)}</p>\n *       </ion-content>\n *     `;\n *   }\n * }\n * ```\n *\n * @example Reactive UI driven by overlay signals\n * ```ts\n * import { signal, html } from \"@deijose/nix-js\";\n * import { createModal } from \"@deijose/nix-ionic\";\n *\n * function ProductList() {\n *   const modal = createModal();\n *   const selected = signal<string | null>(null);\n *\n *   const openDetail = (id: string) => {\n *     selected.value = id;\n *     modal.present({ component: \"product-detail\" });\n *   };\n *\n *   return html`\n *     <ion-content>\n *       <ion-list>\n *         <ion-button @click=${() => openDetail(\"1\")}>Product 1</ion-button>\n *       </ion-list>\n *\n *       <!-- Reactively show dismiss result -->\n *       ${() => modal.result.value\n *         ? html`<p>Modal closed with role: ${modal.result.value.role}</p>`\n *         : null}\n *\n *       <!-- Reactively disable button while modal is open -->\n *       <ion-button\n *         disabled=${() => modal.presented.value}\n *         @click=${() => openDetail(\"2\")}\n *       >Product 2</ion-button>\n *     </ion-content>\n *   `;\n * }\n * ```\n */\n\nimport { signal, type Signal, mount, type NixTemplate, type NixComponent } from \"@deijose/nix-js\";\nimport {\n    toastController,\n    alertController,\n    loadingController,\n    actionSheetController,\n    popoverController,\n    modalController,\n    pickerController,\n} from \"@ionic/core\";\n\n// --- Nix.js framework delegate for overlays ---\n// Ionic overlays (popover, modal) need a \"framework delegate\" to render\n// content when `component` is not a string tag name or HTMLElement.\n// We provide a delegate that uses Nix.js `mount()` to render templates.\n\ninterface FrameworkDelegate {\n    attachViewToDom: (\n        parentElement: HTMLElement,\n        userComponent: unknown,\n        userComponentProps?: Record<string, unknown>,\n        cssClasses?: string[],\n    ) => Promise<HTMLElement>;\n    removeViewFromDom: (\n        parentElement: HTMLElement,\n        childElement: HTMLElement,\n    ) => Promise<void>;\n}\n\nlet _delegateHandle: { unmount: () => void } | null = null;\n\nconst nixDelegate: FrameworkDelegate = {\n    async attachViewToDom(parentElement, userComponent, _props, cssClasses) {\n        // If userComponent is a function (NixTemplate factory), call it and mount\n        if (typeof userComponent === \"function\") {\n            const template = (userComponent as () => NixTemplate)();\n            const handle = mount(template, parentElement);\n            _delegateHandle = handle;\n            return parentElement;\n        }\n        // If userComponent is a string, create the element\n        if (typeof userComponent === \"string\") {\n            const el = document.createElement(userComponent);\n            if (cssClasses) cssClasses.forEach((c) => el.classList.add(c));\n            parentElement.appendChild(el);\n            return el;\n        }\n        // If userComponent is an HTMLElement, append it\n        if (userComponent instanceof HTMLElement) {\n            if (cssClasses) cssClasses.forEach((c) => userComponent.classList.add(c));\n            parentElement.appendChild(userComponent);\n            return userComponent;\n        }\n        // Fallback: just return the parent\n        return parentElement;\n    },\n    async removeViewFromDom(_parent, _child) {\n        if (_delegateHandle) {\n            _delegateHandle.unmount();\n            _delegateHandle = null;\n        }\n    },\n};\n\n// --- Types ---\n\nexport interface OverlayHandle<TDetail = unknown> {\n    /** True while the overlay is presented (visible). */\n    readonly presented: Signal<boolean>;\n    /** The dismiss event detail (role, data) — null until dismissed. */\n    readonly result: Signal<TDetail | null>;\n    /** Present the overlay with the given options. */\n    present(options: Record<string, unknown>): Promise<void>;\n    /** Dismiss the active overlay with optional data and role. */\n    dismiss(data?: unknown, role?: string): Promise<boolean>;\n    /** Cleanup: dismisses any active overlay. Safe to call multiple times. */\n    dispose(): void;\n}\n\ninterface ActiveOverlay {\n    el: { dismiss: (data?: unknown, role?: string) => Promise<boolean> };\n    dismissPromise: Promise<unknown>;\n    token: number; // stale-result protection\n}\n\n// --- Internal factory ---\n\nfunction createOverlayHandle<TDetail>(\n    controller: {\n        create: (opts: Record<string, unknown>) => Promise<any>;\n    },\n): OverlayHandle<TDetail> {\n    const presented = signal(false);\n    const result = signal<TDetail | null>(null);\n    let active: ActiveOverlay | null = null;\n    let disposed = false;\n\n    async function present(options: Record<string, unknown>): Promise<void> {\n        if (disposed) return;\n\n        // If an overlay is already active, dismiss it first (latest-wins).\n        if (active) {\n            try {\n                await active.el.dismiss();\n            } catch { /* ignore */ }\n        }\n\n        const token = (active?.token ?? 0) + 1;\n\n        // If `component` is a function (NixTemplate factory), inject our\n        // framework delegate so Ionic can render Nix.js templates inside\n        // popover/modal overlays.\n        const opts = { ...options };\n        if (typeof opts.component === \"function\" && !opts.delegate) {\n            opts.delegate = nixDelegate;\n        }\n\n        const el = await controller.create(opts);\n        await el.present();\n        active = { el, dismissPromise: el.onDidDismiss?.() ?? Promise.resolve(null), token };\n        presented.value = true;\n\n        // Fire-and-forget the dismiss wait — updates state when the overlay\n        // is dismissed by the user or by dismiss(). This avoids blocking the\n        // caller; they can use the `presented` and `result` signals to react.\n        active.dismissPromise\n            .then((detail) => {\n                if (active?.token === token && !disposed) {\n                    result.value = detail as TDetail;\n                    presented.value = false;\n                    active = null;\n                }\n            })\n            .catch(() => {\n                if (active?.token === token && !disposed) {\n                    presented.value = false;\n                    active = null;\n                }\n            });\n    }\n\n    async function dismiss(data?: unknown, role?: string): Promise<boolean> {\n        if (!active || disposed) return false;\n        try {\n            return await active.el.dismiss(data, role);\n        } catch {\n            return false;\n        }\n    }\n\n    function dispose(): void {\n        if (disposed) return;\n        disposed = true;\n        if (active) {\n            try {\n                active.el.dismiss();\n            } catch { /* ignore */ }\n            active = null;\n        }\n        presented.value = false;\n    }\n\n    return { presented, result, present, dismiss, dispose };\n}\n\n// --- Public factories (create* pattern) ---\n\n/**\n * Create a reactive toast overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createToast(): OverlayHandle {\n    return createOverlayHandle(toastController as any);\n}\n\n/**\n * Create a reactive alert overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createAlert(): OverlayHandle {\n    return createOverlayHandle(alertController as any);\n}\n\n/**\n * Create a reactive loading overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createLoading(): OverlayHandle {\n    return createOverlayHandle(loadingController as any);\n}\n\n/**\n * Create a reactive action-sheet overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createActionSheet(): OverlayHandle {\n    return createOverlayHandle(actionSheetController as any);\n}\n\n/**\n * Create a reactive popover overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createPopover(): OverlayHandle {\n    return createOverlayHandle(popoverController as any);\n}\n\n/**\n * Create a reactive modal overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createModal(): OverlayHandle {\n    return createOverlayHandle(modalController as any);\n}\n\n// --- Convenience: one-shot helpers (no controller needed) ---\n\n/**\n * Present a toast and return immediately (fire-and-forget).\n * The toast auto-dismisses after its duration.\n *\n * @example\n * ```ts\n * import { showToast } from \"@deijose/nix-ionic\";\n *\n * showToast({ message: \"Saved!\", duration: 1500 });\n * ```\n */\nexport async function showToast(\n    options: Record<string, unknown>,\n): Promise<void> {\n    const toast = await toastController.create(options);\n    await toast.present();\n}\n\n/**\n * Present a loading overlay, run an async task, then dismiss.\n * Returns the task result. If the task throws, the loading is still dismissed.\n *\n * @example\n * ```ts\n * import { withLoading } from \"@deijose/nix-ionic\";\n *\n * const data = await withLoading(\n *   { message: \"Fetching...\" },\n *   () => fetch(\"/api/data\").then(r => r.json()),\n * );\n * ```\n */\nexport async function withLoading<T>(\n    options: Record<string, unknown>,\n    task: () => Promise<T>,\n): Promise<T> {\n    const loading = await loadingController.create(options);\n    await loading.present();\n    try {\n        return await task();\n    } finally {\n        await loading.dismiss();\n    }\n}\n\n/**\n * Present a confirm alert and return true if \"OK\" was clicked, false otherwise.\n *\n * @example\n * ```ts\n * import { confirm } from \"@deijose/nix-ionic\";\n *\n * const yes = await confirm({\n *   header: \"Delete\",\n *   message: \"Are you sure?\",\n *   confirmText: \"Delete\",\n * });\n * if (yes) deleteItem();\n * ```\n */\nexport async function confirm(\n    options: { header?: string; message?: string; confirmText?: string; cancelText?: string },\n): Promise<boolean> {\n    return new Promise((resolve) => {\n        alertController\n            .create({\n                header: options.header,\n                message: options.message,\n                buttons: [\n                    { text: options.cancelText ?? \"Cancel\", role: \"cancel\", handler: () => resolve(false) },\n                    { text: options.confirmText ?? \"OK\", role: \"confirm\", handler: () => resolve(true) },\n                ],\n            } as any)\n            .then((el) => el.present());\n    });\n}\n\n// Re-export Ionic controllers for advanced use\nexport {\n    toastController,\n    alertController,\n    loadingController,\n    actionSheetController,\n    popoverController,\n    modalController,\n    pickerController,\n};\n\n// =============================================================================\n// --- Nix.js delegate for modal/popover content mounting ---\n// =============================================================================\n\n/**\n * A Nix.js FrameworkDelegate that can mount NixTemplate or NixComponent\n * instances inside Ionic overlays (modal, popover).\n *\n * Ionic's `FrameworkDelegate` interface has two methods:\n *   - `attachViewToDom(container, component, props, cssClasses)` → HTMLElement\n *   - `removeViewFromDom(container, component)` → void\n *\n * For Nix.js, \"component\" is a function that returns a NixTemplate or\n * NixComponent. The delegate creates a wrapper div, mounts the Nix.js\n * content into it, appends it to the overlay, and tracks the unmount\n * handle for cleanup on dismiss.\n */\nexport interface NixOverlayDelegate {\n    attachViewToDom(\n        container: HTMLElement,\n        component: () => NixTemplate | NixComponent,\n        propsOrData?: Record<string, unknown>,\n        cssClasses?: string[],\n    ): Promise<HTMLElement>;\n    removeViewFromDom(container: HTMLElement, component: unknown): Promise<void>;\n}\n\n/**\n * Create a Nix.js delegate for use with Ionic modal/popover controllers.\n * The delegate mounts Nix.js templates inside overlays and cleans up on\n * removal.\n *\n * @example\n * ```ts\n * import { createNixDelegate, createModal } from \"@deijose/nix-ionic\";\n * import { html, signal } from \"@deijose/nix-js\";\n *\n * const delegate = createNixDelegate();\n * const modal = createModal();\n *\n * // The delegate is passed via `delegate` option\n * modal.present({\n *   component: () => html`<ion-content><h1>Hello from modal!</h1></ion-content>`,\n *   delegate,\n * });\n * ```\n */\nexport function createNixDelegate(): NixOverlayDelegate {\n    // Track unmount handles by wrapper element for cleanup\n    const handles = new Map<HTMLElement, () => void>();\n\n    return {\n        async attachViewToDom(\n            container: HTMLElement,\n            component: () => NixTemplate | NixComponent,\n            _propsOrData?: Record<string, unknown>,\n            cssClasses?: string[],\n        ): Promise<HTMLElement> {\n            // Create a wrapper div to hold the Nix.js content\n            const wrapper = document.createElement(\"div\");\n            if (cssClasses) {\n                for (const cls of cssClasses) wrapper.classList.add(cls);\n            }\n            // Mount the Nix.js content into the wrapper\n            const handle = mount(component(), wrapper);\n            handles.set(wrapper, handle.unmount);\n            // Append to the overlay container\n            container.appendChild(wrapper);\n            return wrapper;\n        },\n\n        async removeViewFromDom(_container: HTMLElement, component: unknown): Promise<void> {\n            // component is the wrapper element returned by attachViewToDom\n            const wrapper = component as HTMLElement;\n            const unmount = handles.get(wrapper);\n            if (unmount) {\n                unmount();\n                handles.delete(wrapper);\n            }\n            if (wrapper.parentElement) {\n                wrapper.remove();\n            }\n        },\n    };\n}\n\n// =============================================================================\n// --- Enhanced modal/popover with delegate support ---\n// =============================================================================\n\n/**\n * Options for presenting a modal with Nix.js content.\n * The `component` function returns a NixTemplate or NixComponent that will\n * be mounted inside the modal via the Nix.js delegate.\n */\nexport interface ModalOptions {\n    /** Function returning the Nix.js content to mount inside the modal. */\n    component: () => NixTemplate | NixComponent;\n    /** Component props/data passed to the delegate. */\n    componentProps?: Record<string, unknown>;\n    /** CSS classes to add to the mounted content wrapper. */\n    cssClasses?: string[];\n    /** Modal-specific options. */\n    backdropDismiss?: boolean;\n    showBackdrop?: boolean;\n    animated?: boolean;\n    canDismiss?: boolean | (() => Promise<boolean>);\n    /** Custom delegate (if not provided, a default Nix.js delegate is used). */\n    delegate?: NixOverlayDelegate;\n    [key: string]: unknown;\n}\n\n/**\n * Options for presenting a popover with Nix.js content.\n */\nexport interface PopoverOptions {\n    /** Function returning the Nix.js content to mount inside the popover. */\n    component: () => NixTemplate | NixComponent;\n    /** Component props/data passed to the delegate. */\n    componentProps?: Record<string, unknown>;\n    /** CSS classes to add to the mounted content wrapper. */\n    cssClasses?: string[];\n    /** The element that the popover should be anchored to. */\n    event?: Event | { target: HTMLElement };\n    /** Popover-specific options. */\n    backdropDismiss?: boolean;\n    showBackdrop?: boolean;\n    animated?: boolean;\n    /** Custom delegate (if not provided, a default Nix.js delegate is used). */\n    delegate?: NixOverlayDelegate;\n    [key: string]: unknown;\n}\n\n/**\n * Enhanced modal controller with Nix.js delegate support.\n * Unlike the basic `createModal()`, this automatically creates and uses\n * a Nix.js delegate so `component` can be a NixTemplate/NixComponent.\n *\n * @example\n * ```ts\n * import { createModalController, createNixDelegate } from \"@deijose/nix-ionic\";\n * import { html, signal } from \"@deijose/nix-js\";\n *\n * const modal = createModalController();\n *\n * modal.present({\n *   component: () => html`\n *     <ion-header>\n *       <ion-toolbar><ion-title>Settings</ion-title></ion-toolbar>\n *     </ion-header>\n *     <ion-content><p>Modal content here</p></ion-content>\n *   `,\n * });\n *\n * // React to dismiss\n * effect(() => {\n *   if (modal.result.value) {\n *     console.log(\"Modal dismissed:\", modal.result.value);\n *   }\n * });\n * ```\n */\nexport function createModalController(delegate?: NixOverlayDelegate): OverlayHandle {\n    const nixDelegate = delegate ?? createNixDelegate();\n    const handle = createOverlayHandle(modalController as any);\n\n    // Wrap present to inject the delegate and convert component\n    const originalPresent = handle.present;\n    async function present(options: ModalOptions): Promise<void> {\n        await originalPresent({\n            ...options,\n            delegate: nixDelegate,\n        });\n    }\n\n    return { ...handle, present };\n}\n\n/**\n * Enhanced popover controller with Nix.js delegate support.\n * Automatically creates and uses a Nix.js delegate so `component` can be\n * a NixTemplate/NixComponent.\n *\n * @example\n * ```ts\n * import { createPopoverController } from \"@deijose/nix-ionic\";\n * import { html } from \"@deijose/nix-js\";\n *\n * const popover = createPopoverController();\n *\n * // In an event handler:\n * popover.present({\n *   component: () => html`<ion-content><p>Popover content</p></ion-content>`,\n *   event, // the click event for anchoring\n * });\n * ```\n */\nexport function createPopoverController(delegate?: NixOverlayDelegate): OverlayHandle {\n    const nixDelegate = delegate ?? createNixDelegate();\n    const handle = createOverlayHandle(popoverController as any);\n\n    const originalPresent = handle.present;\n    async function present(options: PopoverOptions): Promise<void> {\n        await originalPresent({\n            ...options,\n            delegate: nixDelegate,\n        });\n    }\n\n    return { ...handle, present };\n}\n\n// =============================================================================\n// --- Picker wrapper ---\n// =============================================================================\n\n/**\n * Options for a picker column.\n */\nexport interface PickerColumnOption {\n    text: string;\n    value: string | number;\n    disabled?: boolean;\n}\n\n/**\n * Options for presenting a picker overlay.\n */\nexport interface PickerOptions {\n    columns: Array<{\n        name: string;\n        options: PickerColumnOption[];\n        selectedIndex?: number;\n    }>;\n    buttons?: Array<{\n        text: string;\n        role?: string;\n        handler?: (selected: Record<string, PickerColumnOption>) => void;\n    }>;\n    cssClass?: string;\n    animated?: boolean;\n    backdropDismiss?: boolean;\n    [key: string]: unknown;\n}\n\n/**\n * Create a reactive picker overlay controller.\n * Pickers are column-based selection overlays (like iOS date pickers).\n *\n * @example\n * ```ts\n * import { createPicker } from \"@deijose/nix-ionic\";\n *\n * const picker = createPicker();\n * await picker.present({\n *   columns: [{\n *     name: \"size\",\n *     options: [\n *       { text: \"Small\", value: \"sm\" },\n *       { text: \"Medium\", value: \"md\" },\n *       { text: \"Large\", value: \"lg\" },\n *     ],\n *   }],\n *   buttons: [\n *     { text: \"Cancel\", role: \"cancel\" },\n *     { text: \"Done\", role: \"confirm\" },\n *   ],\n * });\n * ```\n */\nexport function createPicker(): OverlayHandle {\n    // Ionic 8's ion-picker is a wheel-style component without columns/buttons/isOpen.\n    // The legacy picker (with columns, buttons, isOpen) is accessed via pickerController,\n    // which creates <ion-picker-legacy> internally. These legacy components must be\n    // registered as custom elements, otherwise customElements.whenDefined() hangs\n    // forever and the picker never appears.\n    //\n    // We register them lazily here (not in setup.ts) to preserve tree-shaking —\n    // apps that don't use the picker won't bundle the legacy picker code.\n    if (typeof customElements !== \"undefined\") {\n        if (!customElements.get(\"ion-picker-legacy\")) {\n            import(\"@ionic/core/components/ion-picker-legacy.js\")\n                .then((m) => m.defineCustomElement())\n                .catch(() => { });\n        }\n        if (!customElements.get(\"ion-picker-legacy-column\")) {\n            import(\"@ionic/core/components/ion-picker-legacy-column.js\")\n                .then((m) => m.defineCustomElement())\n                .catch(() => { });\n        }\n        if (!customElements.get(\"ion-backdrop\")) {\n            import(\"@ionic/core/components/ion-backdrop.js\")\n                .then((m) => m.defineCustomElement())\n                .catch(() => { });\n        }\n    }\n    return createOverlayHandle(pickerController as any);\n}\n"],"mappings":"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"}