{"version":3,"names":["MissingResultParentError","Error","constructor","elementName","super","ResultContext","opts","folded","component","resultVariable","connectedCallback","componentWillRender","render","element","getElement","this","event","buildCustomEvent","resultContextEventName","result","isFolded","children","canceled","dispatchEvent","error","nodeName","toLowerCase","call","remove","console","InteractiveResultContext","interactiveResultVariable","interactiveResultContextEventName","resultContext","Promise","resolve","reject","closest","childTemplatesContextEventName","ChildTemplatesContext","resultTemplateProviderProp","resultTemplateProvider","resultDisplayConfigContextEventName","ResultDisplayConfigContext","config"],"sources":["src/components/search/result-template-components/result-template-decorators.tsx"],"sourcesContent":["import {FoldedResult, InteractiveResult, Result} from '@coveo/headless';\nimport {ComponentInterface, getElement} from '@stencil/core';\nimport {buildCustomEvent} from '../../../utils/event-utils';\nimport {closest} from '../../../utils/utils';\nimport {AnyResult} from '../../common/interface/result';\nimport {\n  ResultDisplayDensity,\n  ResultDisplayImageSize,\n} from '../../common/layout/display-options';\nimport {ResultTemplateProvider} from '../../common/result-list/result-template-provider';\n\nexport class MissingResultParentError extends Error {\n  constructor(elementName: string) {\n    super(\n      `The \"${elementName}\" element must be the child of an \"atomic-result\" element.`\n    );\n  }\n}\n\n/**\n * A [StencilJS property decorator](https://stenciljs.com/) to be used for result template components.\n * This allows the Stencil component to fetch the current result from its rendered parent, the `atomic-result` component.\n *\n * Example:\n * @ResultContext() private result!: Result;\n *\n * For more information and examples, view the \"Utilities\" section of the readme.\n */\nexport function ResultContext(opts: {folded: boolean} = {folded: false}) {\n  return (component: ComponentInterface, resultVariable: string) => {\n    const {connectedCallback, componentWillRender, render} = component;\n    component.connectedCallback = function () {\n      const element = getElement(this);\n      const event = buildCustomEvent(\n        resultContextEventName,\n        (result: FoldedResult | Result) => {\n          if (opts.folded) {\n            if (isFolded(result)) {\n              this[resultVariable] = result;\n            } else {\n              this[resultVariable] = {children: [], result};\n            }\n          } else {\n            this[resultVariable] = isFolded(result) ? result.result : result;\n          }\n        }\n      );\n\n      const canceled = element.dispatchEvent(event);\n      if (canceled) {\n        this.error = new MissingResultParentError(\n          element.nodeName.toLowerCase()\n        );\n        return;\n      }\n      return connectedCallback && connectedCallback.call(this);\n    };\n\n    component.componentWillRender = function () {\n      if (this.error) {\n        return;\n      }\n\n      return componentWillRender && componentWillRender.call(this);\n    };\n\n    component.render = function () {\n      if (this.error) {\n        const element = getElement(this);\n        element.remove();\n        console.error(\n          'Result component is in error and has been removed from the DOM',\n          this.error,\n          this,\n          element\n        );\n        return;\n      }\n      return render && render.call(this);\n    };\n  };\n}\n\nexport function InteractiveResultContext() {\n  return (component: ComponentInterface, interactiveResultVariable: string) => {\n    const {connectedCallback} = component;\n    component.connectedCallback = function () {\n      const element = getElement(this);\n      const event = buildCustomEvent(\n        interactiveResultContextEventName,\n        (result: AnyResult) => {\n          this[interactiveResultVariable] = result;\n        }\n      );\n      element.dispatchEvent(event);\n      return connectedCallback && connectedCallback.call(this);\n    };\n  };\n}\n\ntype ResultContextEventHandler<T = Result> = (result: T) => void;\nexport type ResultContextEvent<T = Result> = CustomEvent<\n  ResultContextEventHandler<T>\n>;\nconst resultContextEventName = 'atomic/resolveResult';\nexport type InteractiveResultContextEvent = CustomEvent<\n  (interactiveResult: InteractiveResult) => void\n>;\nconst interactiveResultContextEventName = 'atomic/resolveInteractiveResult';\n\n/**\n * Retrieves `Result` on a rendered `atomic-result`.\n *\n * This method is useful for building custom result template elements, see [Create a Result List](https://docs.coveo.com/en/atomic/latest/cc-search/create-custom-components/native-components/#custom-result-template-component-example) for more information.\n *\n * You should use the method in the [connectedCallback lifecycle method](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks).\n *\n * @param element The element that the event is dispatched to, which must be the child of a rendered \"atomic-result\".\n * @returns A promise that resolves on initialization of the parent \"atomic-result\" element, or rejects when there is no parent \"atomic-result\" element.\n */\nexport function resultContext<T extends Result | FoldedResult = Result>(\n  element: Element\n) {\n  return new Promise<T>((resolve, reject) => {\n    const event = buildCustomEvent<ResultContextEventHandler<T>>(\n      resultContextEventName,\n      (result: T) => {\n        return resolve(result);\n      }\n    );\n    element.dispatchEvent(event);\n\n    if (!closest(element, 'atomic-result')) {\n      reject(new MissingResultParentError(element.nodeName.toLowerCase()));\n    }\n  });\n}\nfunction isFolded(result: Result | FoldedResult): result is FoldedResult {\n  return 'children' in result;\n}\n\ntype ChildTemplatesContextEventHandler = (\n  resultTemplateProvider?: ResultTemplateProvider\n) => void;\nexport type ChildTemplatesContextEvent =\n  CustomEvent<ChildTemplatesContextEventHandler>;\nconst childTemplatesContextEventName = 'atomic/resolveChildTemplates';\n\ninterface AtomicResultChildren {\n  resultTemplateProvider?: ResultTemplateProvider;\n}\n/**\n * A [StencilJS property decorator](https://stenciljs.com/) to be used for children result templates.\n * This allows the Stencil component to fetch children templates defined a level above.\n */\nexport function ChildTemplatesContext() {\n  return (\n    component: ComponentInterface,\n    resultTemplateProviderProp: string\n  ) => {\n    const {componentWillRender} = component;\n    component.componentWillRender = function () {\n      const element = getElement(this);\n      const event = buildCustomEvent(\n        childTemplatesContextEventName,\n        (resultTemplateProvider?: ResultTemplateProvider) => {\n          const component = this as AtomicResultChildren;\n          if (component.resultTemplateProvider) {\n            return;\n          }\n\n          this[resultTemplateProviderProp] = resultTemplateProvider;\n        }\n      );\n\n      const canceled = element.dispatchEvent(event);\n      if (canceled) {\n        this[resultTemplateProviderProp] = null;\n        return;\n      }\n      return componentWillRender && componentWillRender.call(this);\n    };\n  };\n}\n\nexport type DisplayConfig = {\n  density: ResultDisplayDensity;\n  imageSize: ResultDisplayImageSize;\n};\n\ntype ResultDisplayConfigContextEventHandler = (config: DisplayConfig) => void;\nexport type ResultDisplayConfigContextEvent =\n  CustomEvent<ResultDisplayConfigContextEventHandler>;\nconst resultDisplayConfigContextEventName = 'atomic/resolveResultDisplayConfig';\n\n/**\n * A [StencilJS property decorator](https://stenciljs.com/) to fetch display properties for a result.\n */\nexport function ResultDisplayConfigContext() {\n  return (component: ComponentInterface, resultVariable: string) => {\n    const {componentWillRender} = component;\n    component.componentWillRender = function () {\n      const element = getElement(this);\n      const event = buildCustomEvent(\n        resultDisplayConfigContextEventName,\n        (config: DisplayConfig) => {\n          this[resultVariable] = config;\n        }\n      );\n\n      const canceled = element.dispatchEvent(event);\n      if (canceled) {\n        return;\n      }\n      return componentWillRender && componentWillRender.call(this);\n    };\n  };\n}\n"],"mappings":"kHAWaA,UAAiCC,MAC5C,WAAAC,CAAYC,GACVC,MACE,QAAQD,8D,WAcEE,EAAcC,EAA0B,CAACC,OAAQ,QAC/D,MAAO,CAACC,EAA+BC,KACrC,MAAMC,kBAACA,EAAiBC,oBAAEA,EAAmBC,OAAEA,GAAUJ,EACzDA,EAAUE,kBAAoB,WAC5B,MAAMG,EAAUC,EAAWC,MAC3B,MAAMC,EAAQC,EACZC,GACCC,IACC,GAAIb,EAAKC,OAAQ,CACf,GAAIa,EAASD,GAAS,CACpBJ,KAAKN,GAAkBU,C,KAClB,CACLJ,KAAKN,GAAkB,CAACY,SAAU,GAAIF,S,MAEnC,CACLJ,KAAKN,GAAkBW,EAASD,GAAUA,EAAOA,OAASA,C,KAKhE,MAAMG,EAAWT,EAAQU,cAAcP,GACvC,GAAIM,EAAU,CACZP,KAAKS,MAAQ,IAAIxB,EACfa,EAAQY,SAASC,eAEnB,M,CAEF,OAAOhB,GAAqBA,EAAkBiB,KAAKZ,K,EAGrDP,EAAUG,oBAAsB,WAC9B,GAAII,KAAKS,MAAO,CACd,M,CAGF,OAAOb,GAAuBA,EAAoBgB,KAAKZ,K,EAGzDP,EAAUI,OAAS,WACjB,GAAIG,KAAKS,MAAO,CACd,MAAMX,EAAUC,EAAWC,MAC3BF,EAAQe,SACRC,QAAQL,MACN,iEACAT,KAAKS,MACLT,KACAF,GAEF,M,CAEF,OAAOD,GAAUA,EAAOe,KAAKZ,K,CAC9B,CAEL,C,SAEgBe,IACd,MAAO,CAACtB,EAA+BuB,KACrC,MAAMrB,kBAACA,GAAqBF,EAC5BA,EAAUE,kBAAoB,WAC5B,MAAMG,EAAUC,EAAWC,MAC3B,MAAMC,EAAQC,EACZe,GACCb,IACCJ,KAAKgB,GAA6BZ,CAAM,IAG5CN,EAAQU,cAAcP,GACtB,OAAON,GAAqBA,EAAkBiB,KAAKZ,K,CACpD,CAEL,CAMA,MAAMG,EAAyB,uBAI/B,MAAMc,EAAoC,kC,SAY1BC,EACdpB,GAEA,OAAO,IAAIqB,SAAW,CAACC,EAASC,KAC9B,MAAMpB,EAAQC,EACZC,GACCC,GACQgB,EAAQhB,KAGnBN,EAAQU,cAAcP,GAEtB,IAAKqB,EAAQxB,EAAS,iBAAkB,CACtCuB,EAAO,IAAIpC,EAAyBa,EAAQY,SAASC,e,IAG3D,CACA,SAASN,EAASD,GAChB,MAAO,aAAcA,CACvB,CAOA,MAAMmB,EAAiC,+B,SASvBC,IACd,MAAO,CACL/B,EACAgC,KAEA,MAAM7B,oBAACA,GAAuBH,EAC9BA,EAAUG,oBAAsB,WAC9B,MAAME,EAAUC,EAAWC,MAC3B,MAAMC,EAAQC,EACZqB,GACCG,IACC,MAAMjC,EAAYO,KAClB,GAAIP,EAAUiC,uBAAwB,CACpC,M,CAGF1B,KAAKyB,GAA8BC,CAAsB,IAI7D,MAAMnB,EAAWT,EAAQU,cAAcP,GACvC,GAAIM,EAAU,CACZP,KAAKyB,GAA8B,KACnC,M,CAEF,OAAO7B,GAAuBA,EAAoBgB,KAAKZ,K,CACxD,CAEL,CAUA,MAAM2B,EAAsC,oC,SAK5BC,IACd,MAAO,CAACnC,EAA+BC,KACrC,MAAME,oBAACA,GAAuBH,EAC9BA,EAAUG,oBAAsB,WAC9B,MAAME,EAAUC,EAAWC,MAC3B,MAAMC,EAAQC,EACZyB,GACCE,IACC7B,KAAKN,GAAkBmC,CAAM,IAIjC,MAAMtB,EAAWT,EAAQU,cAAcP,GACvC,GAAIM,EAAU,CACZ,M,CAEF,OAAOX,GAAuBA,EAAoBgB,KAAKZ,K,CACxD,CAEL,Q"}