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