import { computed, type ComputedRef } from 'vue' import type { Component } from 'vue' import type { IvyFormAPIHooks } from '@/composables/IvyFormAPI' export type MultiPageComponentKey = | 'progressIndicator' | 'pageNavigation' | 'progressSettings' | 'navigationSettings' const MULTI_PAGE_COMPONENT_HOOKS: Record = { progressIndicator: 'ivyforms/multi_page/filter/progress_indicator_component', pageNavigation: 'ivyforms/multi_page/filter/page_navigation_component', progressSettings: 'ivyforms/multi_page/filter/progress_settings_component', navigationSettings: 'ivyforms/multi_page/filter/navigation_settings_component', } const MULTI_PAGE_COMPONENT_REGISTRY_KEYS: Record = { progressIndicator: 'IvyFormProgressIndicator', pageNavigation: 'IvyFormPageNavigation', progressSettings: 'ProgressSettings', navigationSettings: 'NavigationSettings', } const isVueComponent = (value: unknown): value is Component => !!value && (typeof value === 'function' || typeof value === 'object') && ('render' in (value as Record) || 'setup' in (value as Record) || '__hmrId' in (value as Record) || '__name' in (value as Record)) const getHooks = (): IvyFormAPIHooks | undefined => { const liteHooks = window.IvyForms?.hooks const apiHooks = window.IvyForms?.api?.hooks if (liteHooks?.applyFilters) { return liteHooks } if (apiHooks?.applyFilters) { return apiHooks } return undefined } const resolveFromRegistry = (key: MultiPageComponentKey): Component | null => { const registry = window.IvyForms?.components const name = MULTI_PAGE_COMPONENT_REGISTRY_KEYS[key] if (!registry || !name) { return null } if (typeof registry === 'function') { try { const res = registry(name) if (isVueComponent(res)) return res if (res && typeof res === 'object') { const c = (res as Record)[name] if (isVueComponent(c)) return c } } catch { // noop } try { const map = registry() if (map && typeof map === 'object') { const c = (map as Record)[name] if (isVueComponent(c)) return c } } catch { // noop } } if (typeof registry === 'object') { const c = (registry as Record)[name] if (isVueComponent(c)) return c } return null } export const resolveMultiPageComponent = (key: MultiPageComponentKey): Component | null => { const hooks = getHooks() if (hooks?.applyFilters) { const resolved = hooks.applyFilters(MULTI_PAGE_COMPONENT_HOOKS[key], null) if (isVueComponent(resolved)) { return resolved } } return resolveFromRegistry(key) } const useResolvedComponent = (key: MultiPageComponentKey): ComputedRef => { return computed(() => { const hooks = getHooks() // Establish reactive dependency so components update when Pro registers filters later. void hooks?.updateCounter?.value return resolveMultiPageComponent(key) }) } export function useMultiPageComponents() { return { progressIndicator: useResolvedComponent('progressIndicator'), pageNavigation: useResolvedComponent('pageNavigation'), progressSettings: useResolvedComponent('progressSettings'), navigationSettings: useResolvedComponent('navigationSettings'), } }