{"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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"}