{"version":3,"file":"tabs-BwJxhIXi.cjs","names":[],"sources":["../../src/setup.ts","../../src/tabs.ts"],"sourcesContent":["/**\n * @deijose/nix-ionic / setup.ts — v2 modular setup\n *\n * Architecture (Nix Ionic 2):\n *\n *   initializeNixIonic(options)   — configures Ionic Core once; returns a\n *                                    handle with status/diagnostics. Safe to\n *                                    call again (no-op after first init, but\n *                                    validates incompatible config changes).\n *\n *   registerIonicComponents(...definers)  — incremental & idempotent. Always\n *                                    registers new definers, skips already-\n *                                    registered custom elements. Works for\n *                                    lazy route loading.\n *\n *   registerIonicons(map)         — incremental with collision diagnostics.\n *                                    Merges new icons into the global set;\n *                                    warns on name collisions.\n *\n *   setupNixIonic(options)        — backward-compatible facade that calls all\n *                                    three. Existing apps work unchanged.\n *\n * Key changes vs v1.x:\n *   - No more `isInitialized` blocking: `registerIonicComponents` and\n *     `registerIonicons` are always incremental.\n *   - No `unpkg@latest` default asset path: uses official `setAssetPath` from\n *     ionicons. CDN is opt-in only.\n *   - SSR-safe: no `window` access at module load; guards in each function.\n *   - Returns a handle with diagnostics from `initializeNixIonic`.\n */\n\nimport { initialize } from \"@ionic/core/components\";\n\n// Minimal core components — the bare minimum any nix-ionic app needs.\nimport { defineCustomElement as defineIonApp } from \"@ionic/core/components/ion-app.js\";\nimport { defineCustomElement as defineIonRouterOutlet } from \"@ionic/core/components/ion-router-outlet.js\";\nimport { defineCustomElement as defineIonBackButton } from \"@ionic/core/components/ion-back-button.js\";\nimport { defineCustomElement as defineIonButtons } from \"@ionic/core/components/ion-buttons.js\";\n\n// Icons\nimport { defineCustomElement as defineIonIcon } from \"ionicons/components/ion-icon.js\";\nimport { addIcons, setAssetPath } from \"ionicons\";\nimport { arrowBack, arrowBackSharp, chevronBack, chevronBackSharp } from \"ionicons/icons\";\n\nexport type ComponentDefiner = () => void;\nexport type IconDefinitionMap = Record<string, string>;\n\nexport interface SetupNixIonicOptions {\n    /** @deprecated Use `icons` mode in `initializeNixIonic` instead. */\n    iconAssetPath?: string;\n    components?: ComponentDefiner[];\n    icons?: IconDefinitionMap;\n}\n\nexport interface InitializeOptions {\n    /**\n     * Icon asset strategy:\n     * - \"inline\" (default): icons are inlined via addIcons; no remote fetch.\n     * - \"assets\": use setAssetPath to a local URL; icons fetched on demand.\n     * - object with `mode: \"assets\"` and `path` for explicit local path.\n     */\n    icons?: \"inline\" | \"assets\" | { mode: \"assets\"; path: string };\n    /** Ionic mode override: \"ios\" | \"md\" | undefined (auto-detect). */\n    mode?: \"ios\" | \"md\";\n}\n\nexport interface SetupHandle {\n    /** True if this call performed the initialization; false if already init. */\n    readonly initialized: boolean;\n    /** Diagnostics collected during initialization. */\n    readonly diagnostics: string[];\n}\n\n// --- Internal registry state ---\n\nconst _coreDefiners: ComponentDefiner[] = [\n    defineIonApp,\n    defineIonRouterOutlet,\n    defineIonBackButton,\n    defineIonButtons,\n    defineIonIcon,\n];\n\nconst _defaultIcons: IconDefinitionMap = {\n    \"arrow-back\": arrowBack,\n    \"arrow-back-sharp\": arrowBackSharp,\n    \"chevron-back\": chevronBack,\n    \"chevron-back-sharp\": chevronBackSharp,\n};\n\nlet _initialized = false;\nconst _registeredIconNames = new Set<string>();\n\nfunction _hasWindow(): boolean {\n    return typeof window !== \"undefined\";\n}\n\nfunction _hasCustomElements(): boolean {\n    return typeof customElements !== \"undefined\";\n}\n\n/**\n * Initialize Ionic Core for Nix.js. Configures the runtime once.\n *\n * Subsequent calls are no-ops for the core init, but `registerIonicComponents`\n * and `registerIonicons` remain incremental regardless.\n *\n * Returns a handle with diagnostics.\n */\nexport function initializeNixIonic(options: InitializeOptions = {}): SetupHandle {\n    const diagnostics: string[] = [];\n\n    if (!_hasWindow()) {\n        // SSR/prerender: do not touch DOM. Module is import-safe.\n        return { initialized: false, diagnostics: [\"SSR: window unavailable, skipping init\"] };\n    }\n\n    if (_initialized) {\n        // Validate incompatible config changes after init.\n        if (options.mode) {\n            diagnostics.push(\"mode cannot be changed after initialization; ignoring\");\n        }\n        return { initialized: false, diagnostics };\n    }\n\n    // Icon asset strategy\n    const iconsCfg = options.icons ?? \"inline\";\n    if (iconsCfg === \"inline\") {\n        // Default: no remote asset path. Icons are inlined via addIcons.\n        // setAssetPath to empty string prevents any CDN fetch.\n        setAssetPath(\"\");\n    } else if (typeof iconsCfg === \"object\" && iconsCfg.mode === \"assets\") {\n        setAssetPath(iconsCfg.path);\n    } else if (iconsCfg === \"assets\") {\n        // \"assets\" mode without explicit path — use a sensible default\n        // relative to the document base.\n        const base = document.baseURI || \"/\";\n        setAssetPath(new URL(\"assets/icons/\", base).href);\n    }\n\n    // Initialize Ionic Core\n    initialize();\n\n    // Register minimal core components\n    for (const definer of _coreDefiners) {\n        definer();\n    }\n\n    // Register default back icons (used by IonBackButton)\n    addIcons(_defaultIcons);\n    for (const name of Object.keys(_defaultIcons)) {\n        _registeredIconNames.add(name);\n    }\n\n    _initialized = true;\n\n    return { initialized: true, diagnostics };\n}\n\n/**\n * Register additional Ionic custom element definers. Incremental and\n * idempotent — always processes new definers, safe to call from lazy routes.\n *\n * @example\n * ```ts\n * // In a lazy route module:\n * import { defineCustomElement as defineIonDatetime } from \"@ionic/core/components/ion-datetime.js\";\n * registerIonicComponents(defineIonDatetime);\n * ```\n */\nexport function registerIonicComponents(...definers: ComponentDefiner[]): void {\n    if (!_hasCustomElements()) {\n        if (_hasWindow()) {\n            console.warn(\"[nix-ionic] customElements unavailable; cannot register components\");\n        }\n        return;\n    }\n\n    for (const definer of definers) {\n        try {\n            definer();\n        } catch (e) {\n            // Ionic definers internally guard against double-registration,\n            // but we catch just in case.\n            if (e instanceof Error && !e.message.includes(\"already been registered\")) {\n                console.warn(`[nix-ionic] Component registration error: ${e.message}`);\n            }\n        }\n    }\n}\n\n/**\n * Register additional Ionicons by name → SVG string mapping. Incremental\n * with collision diagnostics.\n *\n * @example\n * ```ts\n * import { registerIonicons } from \"@deijose/nix-ionic\";\n * import { home, homeOutline } from \"ionicons/icons\";\n *\n * registerIonicons({ home, \"home-outline\": homeOutline });\n * ```\n */\nexport function registerIonicons(map: IconDefinitionMap): void {\n    if (!_hasWindow()) {\n        return;\n    }\n\n    const toAdd: IconDefinitionMap = {};\n    for (const [name, svg] of Object.entries(map)) {\n        if (_registeredIconNames.has(name)) {\n            // Overwriting is allowed (addIcons merges), but warn in dev.\n            console.warn(`[nix-ionic] Icon \"${name}\" already registered; overwriting.`);\n        }\n        toAdd[name] = svg;\n        _registeredIconNames.add(name);\n    }\n\n    if (Object.keys(toAdd).length > 0) {\n        addIcons(toAdd);\n    }\n}\n\n/**\n * Backward-compatible facade. Calls `initializeNixIonic`, then registers\n * any extra components and icons passed via options.\n *\n * Existing v1.x apps work unchanged. New apps should prefer the granular\n * functions (`initializeNixIonic` + `registerIonicComponents` + `registerIonicons`)\n * for lazy loading and HMR support.\n *\n * @deprecated Prefer `initializeNixIonic` + `registerIonicComponents` + `registerIonicons` for new code.\n */\nexport function setupNixIonic(options: SetupNixIonicOptions = {}): void {\n    if (!_hasWindow()) return;\n\n    // Map old options to new init\n    const initOpts: InitializeOptions = {};\n    if (options.iconAssetPath) {\n        initOpts.icons = { mode: \"assets\", path: options.iconAssetPath };\n    }\n\n    const handle = initializeNixIonic(initOpts);\n\n    // Register extra components (always incremental, even after init)\n    if (options.components) {\n        registerIonicComponents(...options.components);\n    }\n\n    // Register extra icons (always incremental, even after init)\n    if (options.icons) {\n        registerIonicons(options.icons);\n    }\n\n    void handle;\n}\n\nexport { addIcons, setAssetPath };\n","/**\n * @deijose/nix-ionic / tabs.ts  —  v2\n *\n * Bottom tab bar that drives navigation through the core router. The visual\n * \"active\" state is computed from `nixRouter().current` directly.\n *\n * Tab switches are intentionally direction:\"none\" — Ionic's convention is no\n * animation between tabs. Per-tab stacks (configured on IonRouterOutlet via\n * `tabs: [...]`) preserve each tab's deep view across switches.\n */\n\nimport { html, NixComponent, effect, ref, nextTick } from \"@deijose/nix-js\";\nimport type { NixTemplate } from \"@deijose/nix-js\";\nimport { nixRouter, type NavigationDirection } from \"@deijose/nix-js\";\nimport { addIcons, type IconDefinitionMap } from \"./setup.js\";\n\n/** Layout of icon and label inside each tab button. */\nexport type TabButtonLayout =\n    | \"icon-top\"\n    | \"icon-start\"\n    | \"icon-end\"\n    | \"icon-bottom\"\n    | \"icon-hide\"\n    | \"label-hide\";\n\nexport interface BottomTabItem {\n    path: string;\n    label: string;\n    icon?: string;\n    activeIcon?: string;\n    exact?: boolean;\n    tabId?: string;\n    /** Badge text or number (e.g. notification count). */\n    badge?: string | number;\n    /** Badge color (Ionic color name). Default: \"danger\". */\n    badgeColor?: string;\n}\n\nexport interface BottomTabBarOptions {\n    slot?: \"top\" | \"bottom\";\n    className?: string;\n    hiddenPaths?: string[];\n    /**\n     * Direction passed to the router on tab change.\n     * Default `\"none\"` — no animation, native Ionic feel.\n     */\n    navigationDirection?: NavigationDirection;\n    hideWhen?: (path: string) => boolean;\n    /**\n     * Icon SVG data to register for the tab bar icons.\n     *\n     * The Vite plugin can only detect static `name=\"icon-name\"` in html``\n     * templates. Tab bar icons are dynamic, so pass the data here.\n     */\n    icons?: IconDefinitionMap;\n    /**\n     * Layout of icon and label inside each tab button.\n     * Default: `\"icon-top\"`.\n     */\n    layout?: TabButtonLayout;\n    /**\n     * CSS custom properties to set on the `ion-tab-bar` element.\n     * Useful for theming: `--background`, `--color`, `--color-selected`, etc.\n     *\n     * @example\n     * ```ts\n     * createBottomTabBar(tabs, {\n     *   cssVars: {\n     *     \"--background\": \"#1a1a2e\",\n     *     \"--color-selected\": \"#00ff88\",\n     *   },\n     * });\n     * ```\n     */\n    cssVars?: Record<string, string>;\n}\n\nfunction _normalizePath(p: string): string {\n    if (!p || p === \"/\") return \"/\";\n    return p.endsWith(\"/\") ? p.slice(0, -1) : p;\n}\n\nfunction _isActive(tab: BottomTabItem, currentPath: string): boolean {\n    const cur = _normalizePath(currentPath);\n    const tgt = _normalizePath(tab.path);\n    if (tab.exact) return cur === tgt;\n    if (tgt === \"/\") return cur === \"/\";\n    return cur === tgt || cur.startsWith(`${tgt}/`);\n}\n\nfunction _isHidden(path: string, patterns?: string[]): boolean {\n    if (!patterns?.length) return false;\n    const cur = _normalizePath(path);\n    return patterns.some((pat) => {\n        const norm = _normalizePath(pat);\n        if (norm.endsWith(\"/*\")) {\n            const base = norm.slice(0, -2);\n            return cur === base || cur.startsWith(`${base}/`);\n        }\n        return cur === norm;\n    });\n}\n\n/** Convert a cssVars record to a CSS string for the style attribute. */\nfunction _cssVarsToString(vars: Record<string, string> | undefined): string {\n    if (!vars) return \"\";\n    return Object.entries(vars)\n        .map(([k, v]) => `${k}: ${v}`)\n        .join(\"; \");\n}\n\nexport function createBottomTabBar(\n    tabs: BottomTabItem[],\n    options: BottomTabBarOptions = {},\n): NixTemplate {\n    const router = nixRouter();\n    const slot = options.slot ?? \"bottom\";\n    const className = options.className ?? \"nix-ion-tab-bar\";\n    const direction: NavigationDirection = options.navigationDirection ?? \"none\";\n    const layout: TabButtonLayout = options.layout ?? \"icon-top\";\n    const cssVars = options.cssVars;\n\n    // Register icons if provided.\n    if (options.icons) {\n        addIcons(options.icons);\n    }\n\n    // Stencil boolean props (like `selected`) cannot be set via HTML\n    // attributes with Nix.js. We use an effect to set the JS property\n    // directly on each ion-tab-button after it's in the DOM, and\n    // re-sync whenever the route changes.\n    const tabBarRef = ref<HTMLElement>();\n    let synced = false;\n    effect(() => {\n        const currentPath = router.current.value;\n        const tabBarEl = tabBarRef.el;\n        if (!tabBarEl) {\n            if (!synced) {\n                nextTick(() => {\n                    synced = true;\n                    const el = tabBarRef.el;\n                    if (!el) return;\n                    const btns = el.querySelectorAll(\"ion-tab-button\");\n                    btns.forEach((btn, i) => {\n                        const tab = tabs[i];\n                        if (!tab) return;\n                        (btn as any).selected = _isActive(tab, router.current.value);\n                    });\n                });\n            }\n            return;\n        }\n        const buttons = tabBarEl.querySelectorAll(\"ion-tab-button\");\n        buttons.forEach((btn, i) => {\n            const tab = tabs[i];\n            if (!tab) return;\n            const isActive = _isActive(tab, currentPath);\n            (btn as any).selected = isActive;\n        });\n    });\n\n    return html`\n    <ion-tab-bar\n      slot=${slot}\n      class=${className}\n      ref=${tabBarRef}\n      style=${() => {\n            const path = router.current.value;\n            const hidden = options.hideWhen\n                ? options.hideWhen(path)\n                : _isHidden(path, options.hiddenPaths);\n            const vars = _cssVarsToString(cssVars);\n            const display = hidden ? \"display:none\" : \"\";\n            return [vars, display].filter(Boolean).join(\"; \");\n        }}\n    >\n      ${tabs.map((tab) => {\n            const computedTabId = tab.path === \"/\"\n                ? \"root\"\n                : _normalizePath(tab.path).replace(/^\\//, \"\").replace(/\\//g, \"-\");\n            const tabId = tab.tabId ?? computedTabId;\n\n            return html`\n          <ion-tab-button\n            tab=${tabId}\n            layout=${layout}\n            @click.prevent.stop=${() => {\n                    // .prevent.stop prevents Ionic's internal tab selection\n                    // (which looks for <ion-tab> children we don't have).\n                    // We drive navigation through the Nix.js router instead.\n                    if (_isActive(tab, router.current.value)) {\n                        router.replace(tab.path, { direction: \"none\" });\n                    } else {\n                        router.navigate(tab.path, { direction });\n                    }\n                }}\n          >\n            ${tab.icon\n                    ? html`\n                  <ion-icon\n                    name=${() => {\n                            const active = _isActive(tab, router.current.value);\n                            return active && tab.activeIcon ? tab.activeIcon : tab.icon;\n                        }}\n                  ></ion-icon>\n                `\n                    : \"\"}\n            <ion-label>${tab.label}</ion-label>\n            ${tab.badge != null\n                    ? html`<ion-badge color=${tab.badgeColor ?? \"danger\"}>${tab.badge}</ion-badge>`\n                    : \"\"}\n          </ion-tab-button>\n        `;\n        })}\n    </ion-tab-bar>\n  `;\n}\n\n/**\n * Wraps an IonRouterOutlet and a tab bar in <ion-tabs>.\n *\n * <ion-tabs> provides the correct CSS layout context: the outlet fills\n * the available space and the tab bar sits at the bottom (or top).\n *\n * We use <ion-tabs> for layout only — navigation is driven by the\n * Nix.js router via the @click handler on each <ion-tab-button>, not\n * by Ionic's internal tab selection. The tab buttons have `tab` IDs\n * so Ionic doesn't warn, but there are no <ion-tab> children.\n *\n * A small CSS snippet is injected to ensure <ion-tabs> fills its\n * parent and the absolutely-positioned <ion-router-outlet> doesn't\n * collapse the layout.\n */\nexport function createTabsLayout(\n    outlet: NixTemplate | NixComponent,\n    tabBar: NixTemplate,\n): NixTemplate {\n    _injectTabsLayoutStyles();\n    const outletTemplate = outlet instanceof NixComponent ? outlet.render() : outlet;\n    return html`\n        <ion-tabs>\n            ${outletTemplate}\n            ${tabBar}\n        </ion-tabs>\n    `;\n}\n\n/** Inject the tabs layout CSS once (idempotent). */\nlet _tabsStylesInjected = false;\nfunction _injectTabsLayoutStyles(): void {\n    if (_tabsStylesInjected) return;\n    if (typeof document === \"undefined\") return;\n    _tabsStylesInjected = true;\n    const style = document.createElement(\"style\");\n    style.id = \"nix-ionic-tabs-layout\";\n    // ion-tabs defaults to display:block with no explicit height, which\n    // collapses to the tab bar's height because ion-router-outlet is\n    // position:absolute. Force ion-tabs to fill its parent and use flexbox\n    // so the outlet takes the remaining space above the tab bar.\n    style.textContent = `\nion-tabs {\n    display: flex !important;\n    flex-direction: column !important;\n    height: 100% !important;\n    width: 100% !important;\n    position: relative !important;\n}\nion-tabs > ion-router-outlet {\n    flex: 1 1 0 !important;\n    min-height: 0 !important;\n    position: relative !important;\n    top: auto !important;\n    bottom: auto !important;\n    left: auto !important;\n    right: auto !important;\n}\nion-tabs > ion-tab-bar {\n    flex-shrink: 0 !important;\n}\n`;\n    document.head.appendChild(style);\n}\n"],"mappings":"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"}