{"version":3,"names":["Hidden","h","Host","class","initializeEventName","initializableElements","initializeBindings","element","Promise","resolve","reject","event","buildCustomEvent","bindings","dispatchEvent","closest","join","MissingInterfaceParentError","nodeName","toLowerCase","Error","constructor","elementName","super","applyFocusVisiblePolyfill","shadowRoot","window","addEventListener","_a","call","once","renderedAttribute","loadedAttribute","InitializeBindings","forceUpdate","component","bindingsProperty","componentWillLoad","render","componentDidRender","componentDidLoad","disconnectedCallback","unsubscribeLanguage","console","error","getElement","this","setAttribute","updateLanguage","forceUpdateComponent","i18n","on","off","initialize","e","getAttribute","BindStateToController","controllerProperty","options","stateProperty","onUpdateCallbackMethod","unsubscribeController","subscribe","state","isConnected"],"sources":["src/components/common/hidden.tsx","src/utils/initialization-utils.tsx"],"sourcesContent":["import {FunctionalComponent, Host, h} from '@stencil/core';\n\nexport const Hidden: FunctionalComponent = () => (\n <Host class=\"atomic-hidden\"></Host>\n);\n","import {\n ComponentInterface,\n getElement,\n h,\n forceUpdate as forceUpdateComponent,\n} from '@stencil/core';\nimport {TOptions} from 'i18next';\nimport {Hidden} from '../components/common/hidden';\nimport {AnyBindings} from '../components/common/interface/bindings';\nimport {Bindings} from '../components/search/atomic-search-interface/atomic-search-interface';\nimport {buildCustomEvent} from './event-utils';\nimport {closest} from './utils';\n\ndeclare global {\n interface Window {\n applyFocusVisiblePolyfill?: (shadowRoot: ShadowRoot) => void;\n }\n}\n\nexport type InitializeEventHandler = (bindings: AnyBindings) => void;\nexport type InitializeEvent = CustomEvent<InitializeEventHandler>;\nexport const initializeEventName = 'atomic/initializeComponent';\nconst initializableElements = [\n 'atomic-recs-interface',\n 'atomic-search-interface',\n 'atomic-relevance-inspector',\n 'atomic-insight-interface',\n 'atomic-external',\n];\n\n/**\n * Retrieves `Bindings` on a configured parent search interface.\n * @param event Element on which to dispatch the event, which must be the child of a configured \"atomic-search-interface\" or \"atomic-external\" element.\n * @returns A promise that resolves on initialization of the parent \"atomic-search-interface\" or \"atomic-external\" element, and rejects when it's not the case.\n */\nexport function initializeBindings<SpecificBindings extends AnyBindings>(\n element: Element\n) {\n return new Promise<SpecificBindings>((resolve, reject) => {\n const event = buildCustomEvent<InitializeEventHandler>(\n initializeEventName,\n (bindings) => resolve(bindings as SpecificBindings)\n );\n element.dispatchEvent(event);\n\n if (!closest(element, initializableElements.join(', '))) {\n reject(new MissingInterfaceParentError(element.nodeName.toLowerCase()));\n }\n });\n}\n\nexport class MissingInterfaceParentError extends Error {\n constructor(elementName: string) {\n super(\n `The \"${elementName}\" element must be the child of the following elements: ${initializableElements.join(\n ', '\n )}`\n );\n }\n}\n\n/**\n * Necessary interface an Atomic Component must have to initialize itself correctly.\n */\nexport interface InitializableComponent<\n SpecificBindings extends AnyBindings = Bindings,\n> extends ComponentInterface {\n /**\n * Bindings passed from the `AtomicSearchInterface` to its children components.\n */\n bindings: SpecificBindings;\n /**\n * Method called right after the `bindings` property is defined. This is the method where Headless Framework controllers should be initialized.\n */\n initialize?: () => void;\n error: Error;\n}\n\n/**\n * Makes Shadow Dom elements compatible with the focus-visible polyfill https://github.com/WICG/focus-visible\n * Necessary for Safari under version 15.4.\n */\nexport function applyFocusVisiblePolyfill(element: HTMLElement) {\n if (!element.shadowRoot) {\n return;\n }\n\n if (window.applyFocusVisiblePolyfill) {\n window.applyFocusVisiblePolyfill(element.shadowRoot);\n return;\n }\n\n window.addEventListener(\n 'focus-visible-polyfill-ready',\n () => window.applyFocusVisiblePolyfill?.(element.shadowRoot!),\n {once: true}\n );\n}\n\ntype InitializeBindingsProps = {\n forceUpdate?: boolean;\n};\n\nconst renderedAttribute = 'data-atomic-rendered';\nconst loadedAttribute = 'data-atomic-loaded';\n\n/**\n * A [StencilJS property decorator](https://stenciljs.com/) to be used on a property named `bindings`.\n * This will automatically fetch the `Bindings` from the parent `atomic-search-interface` or `atomic-external` components.\n *\n * Once a component is bound, the `initialize` method is called.\n * In the event of an initialization error, the `error` property will be set and an `atomic-component-error` will be rendered.\n *\n * In order for a component using this decorator to render properly, it should have an internal state bound to one of the properties from `bindings`.\n * This is possible by using the `BindStateToController` decorator.\n *\n * @example\n * @InitializeBindings() public bindings!: Bindings;\n *\n * For more information and examples, view the \"Utilities\" section of the readme.\n */\nexport function InitializeBindings<SpecificBindings extends AnyBindings>({\n forceUpdate,\n}: InitializeBindingsProps = {}) {\n return (\n component: InitializableComponent<SpecificBindings>,\n bindingsProperty: string\n ) => {\n const {\n componentWillLoad,\n render,\n componentDidRender,\n componentDidLoad,\n disconnectedCallback,\n } = component;\n let unsubscribeLanguage = () => {};\n\n if (bindingsProperty !== 'bindings') {\n return console.error(\n `The InitializeBindings decorator should be used on a property called \"bindings\", and not \"${bindingsProperty}\"`,\n component\n );\n }\n\n component.componentWillLoad = function () {\n const element = getElement(this);\n element.setAttribute(renderedAttribute, 'false');\n element.setAttribute(loadedAttribute, 'false');\n const event = buildCustomEvent(\n initializeEventName,\n (bindings: SpecificBindings) => {\n this.bindings = bindings;\n\n const updateLanguage = () => forceUpdateComponent(this);\n this.bindings.i18n.on('languageChanged', updateLanguage);\n unsubscribeLanguage = () =>\n this.bindings.i18n.off('languageChanged', updateLanguage);\n\n try {\n // When no controller is initialized, updating a property with a State() decorator, there will be no re-render.\n // In this case, we have to manually trigger it.\n if (this.initialize) {\n this.initialize();\n if (forceUpdate) {\n forceUpdateComponent(this);\n }\n } else {\n forceUpdateComponent(this);\n }\n } catch (e) {\n this.error = e as Error;\n }\n }\n );\n\n element.dispatchEvent(event);\n\n if (!closest(element, initializableElements.join(', '))) {\n this.error = new MissingInterfaceParentError(\n element.nodeName.toLowerCase()\n );\n return;\n }\n\n return componentWillLoad && componentWillLoad.call(this);\n };\n\n component.render = function () {\n if (this.error) {\n return (\n <atomic-component-error\n element={getElement(this)}\n error={this.error}\n ></atomic-component-error>\n );\n }\n\n if (!this.bindings) {\n return <Hidden></Hidden>;\n }\n\n getElement(this).setAttribute(renderedAttribute, 'true');\n return render && render.call(this);\n };\n\n component.disconnectedCallback = function () {\n const element = getElement(this);\n element.setAttribute(renderedAttribute, 'false');\n element.setAttribute(loadedAttribute, 'false');\n unsubscribeLanguage();\n disconnectedCallback && disconnectedCallback.call(this);\n };\n\n component.componentDidRender = function () {\n const element = getElement(this);\n if (element.getAttribute(renderedAttribute) === 'false') {\n return;\n }\n\n componentDidRender && componentDidRender.call(this);\n if (element.getAttribute(loadedAttribute) === 'false') {\n element.setAttribute(loadedAttribute, 'true');\n applyFocusVisiblePolyfill(getElement(this));\n componentDidLoad && componentDidLoad.call(this);\n }\n };\n\n component.componentDidLoad = function () {};\n };\n}\n\n/**\n * A [StencilJS property decorator](https://stenciljs.com/) is used together with the [State decorator](https://stenciljs.com/docs/state#state-decorator).\n * This allows the Stencil component state property to automatically get updates from a [Coveo Headless controller](https://docs.coveo.com/en/headless/latest/usage/#use-headless-controllers).\n *\n * @example\n * @BindStateToController('pager') @State() private pagerState!: PagerState;\n *\n * For more information and examples, view the \"Utilities\" section of the readme.\n *\n * @param controllerProperty The controller property to subscribe to. The controller has to be created inside of the `initialize` method.\n * @param options The configurable `BindStateToController` options.\n */\nexport function BindStateToController(\n controllerProperty: string,\n options?: {\n /**\n * Component's method to be called when state is updated.\n */\n onUpdateCallbackMethod?: string;\n }\n) {\n return (\n component: InitializableComponent<AnyBindings>,\n stateProperty: string\n ) => {\n const {disconnectedCallback, initialize} = component;\n\n component.initialize = function () {\n initialize && initialize.call(this);\n\n if (!initialize) {\n return console.error(\n `ControllerState: The \"initialize\" method has to be defined and instantiate a controller for the property ${controllerProperty}`,\n component\n );\n }\n\n if (!this[controllerProperty]) {\n return;\n }\n\n if (\n options?.onUpdateCallbackMethod &&\n !this[options.onUpdateCallbackMethod]\n ) {\n return console.error(\n `ControllerState: The onUpdateCallbackMethod property \"${options.onUpdateCallbackMethod}\" is not defined`,\n component\n );\n }\n\n this.unsubscribeController = this[controllerProperty].subscribe(() => {\n this[stateProperty] = this[controllerProperty].state;\n options?.onUpdateCallbackMethod &&\n this[options.onUpdateCallbackMethod]();\n });\n };\n\n component.disconnectedCallback = function () {\n !getElement(this).isConnected && this.unsubscribeController?.();\n disconnectedCallback && disconnectedCallback.call(this);\n };\n };\n}\n\ninterface DeferredExecution {\n args: unknown[];\n}\n\nexport function DeferUntilRender() {\n return (component: ComponentInterface, methodName: string) => {\n const {componentDidRender, connectedCallback} = component;\n const originalMethod = component[methodName] as Function;\n let deferredExecutions: DeferredExecution[] = [];\n\n component.connectedCallback = function () {\n this[methodName] = function (...args: unknown[]) {\n deferredExecutions.push({args});\n };\n connectedCallback && connectedCallback.call(this);\n };\n\n component.componentDidRender = function () {\n deferredExecutions.forEach(({args}) =>\n originalMethod.call(this, ...args)\n );\n deferredExecutions = [];\n componentDidRender && componentDidRender.call(this);\n };\n };\n}\n\nexport type I18nState = Record<string, (variables?: TOptions) => string>;\n"],"mappings":"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"}