From 38970c3e27c62f67ba7274a5bec61cc8160d4bec Mon Sep 17 00:00:00 2001 From: Felix Perron-Brault Date: Mon, 4 Nov 2024 13:10:45 -0500 Subject: [PATCH] fix(atomic): fix clicks for recommendation lists in grid display mode (#4623) This PR ensures that clicks on grid display mode result cards open the result/product for `atomic-recs-list`, `atomic-ipx-recs-list` and `atomic-commerce-recommendation-list`, as with other types of result lists. https://coveord.atlassian.net/browse/KIT-3705 --- .../src/lib/stencil-generated/components.ts | 4 +-- packages/atomic/src/components.d.ts | 10 ++++++ .../atomic-commerce-recommendation-list.tsx | 5 +-- .../atomic-recs-list/atomic-ipx-recs-list.tsx | 2 ++ .../atomic-recs-list/atomic-recs-list.tsx | 2 ++ .../atomic-recs-result/atomic-recs-result.tsx | 36 ++++++++++++++++--- packages/atomic/src/pages/index.html | 1 - 7 files changed, 49 insertions(+), 11 deletions(-) diff --git a/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts b/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts index c83226b2dee..1fca16c1bac 100644 --- a/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts +++ b/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts @@ -1893,14 +1893,14 @@ export declare interface AtomicRecsList extends Components.AtomicRecsList {} @ProxyCmp({ - inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'result', 'stopPropagation'] + inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'linkContent', 'result', 'stopPropagation'] }) @Component({ selector: 'atomic-recs-result', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'result', 'stopPropagation'], + inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'linkContent', 'result', 'stopPropagation'], }) export class AtomicRecsResult { protected el: HTMLElement; diff --git a/packages/atomic/src/components.d.ts b/packages/atomic/src/components.d.ts index beb42d4e7ae..1ecb7eb68d3 100644 --- a/packages/atomic/src/components.d.ts +++ b/packages/atomic/src/components.d.ts @@ -2652,6 +2652,11 @@ export namespace Components { * The InteractiveResult item. */ "interactiveResult": RecsInteractiveResult; + /** + * The result link to use when the result is clicked in a grid layout. + * @default - An `atomic-result-link` without any customization. + */ + "linkContent": ParentNode; "loadingFlag"?: string; /** * Internal function used by atomic-recs-list in advanced setups, which lets you bypass the standard HTML template system. Particularly useful for Atomic React @@ -8646,6 +8651,11 @@ declare namespace LocalJSX { * The InteractiveResult item. */ "interactiveResult": RecsInteractiveResult; + /** + * The result link to use when the result is clicked in a grid layout. + * @default - An `atomic-result-link` without any customization. + */ + "linkContent"?: ParentNode; "loadingFlag"?: string; /** * Internal function used by atomic-recs-list in advanced setups, which lets you bypass the standard HTML template system. Particularly useful for Atomic React diff --git a/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx b/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx index 019393485b3..292951e93d1 100644 --- a/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx +++ b/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx @@ -322,10 +322,7 @@ export class AtomicCommerceRecommendationList this.imageSize ), content: this.productTemplateProvider.getTemplateContent(product), - linkContent: - this.display === 'grid' - ? this.productTemplateProvider.getLinkTemplateContent(product) - : this.productTemplateProvider.getEmptyLinkTemplateContent(), + linkContent: this.productTemplateProvider.getLinkTemplateContent(product), store: this.bindings.store, density: this.density, display: this.display, diff --git a/packages/atomic/src/components/ipx/atomic-ipx-recs-list/atomic-recs-list/atomic-ipx-recs-list.tsx b/packages/atomic/src/components/ipx/atomic-ipx-recs-list/atomic-recs-list/atomic-ipx-recs-list.tsx index 2ae8c6f1536..099b2e6b356 100644 --- a/packages/atomic/src/components/ipx/atomic-ipx-recs-list/atomic-recs-list/atomic-ipx-recs-list.tsx +++ b/packages/atomic/src/components/ipx/atomic-ipx-recs-list/atomic-recs-list/atomic-ipx-recs-list.tsx @@ -350,6 +350,8 @@ export class AtomicIPXRecsList implements InitializableComponent { this.imageSize ), content: this.itemTemplateProvider.getTemplateContent(recommendation), + linkContent: + this.itemTemplateProvider.getLinkTemplateContent(recommendation), store: this.bindings.store, density: this.density, display: this.display, diff --git a/packages/atomic/src/components/recommendations/atomic-recs-list/atomic-recs-list.tsx b/packages/atomic/src/components/recommendations/atomic-recs-list/atomic-recs-list.tsx index a131f53d691..c69e927dc1b 100644 --- a/packages/atomic/src/components/recommendations/atomic-recs-list/atomic-recs-list.tsx +++ b/packages/atomic/src/components/recommendations/atomic-recs-list/atomic-recs-list.tsx @@ -326,6 +326,8 @@ export class AtomicRecsList implements InitializableComponent { this.imageSize ), content: this.itemTemplateProvider.getTemplateContent(recommendation), + linkContent: + this.itemTemplateProvider.getLinkTemplateContent(recommendation), store: this.bindings.store, density: this.density, display: this.display, diff --git a/packages/atomic/src/components/recommendations/atomic-recs-result/atomic-recs-result.tsx b/packages/atomic/src/components/recommendations/atomic-recs-result/atomic-recs-result.tsx index 8cfbec370f8..1b0f4136a3f 100644 --- a/packages/atomic/src/components/recommendations/atomic-recs-result/atomic-recs-result.tsx +++ b/packages/atomic/src/components/recommendations/atomic-recs-result/atomic-recs-result.tsx @@ -1,5 +1,6 @@ import {Component, h, Prop, Element, Listen, Host} from '@stencil/core'; import {RecsInteractiveResult, RecsResult} from '..'; +import {parentNodeToString} from '../../../utils/dom-utils'; import {applyFocusVisiblePolyfill} from '../../../utils/initialization-utils'; import { InteractiveItemContextEvent, @@ -29,6 +30,7 @@ import {AtomicRecsStore} from '../atomic-recs-interface/store'; export class AtomicRecsResult { private layout!: ItemLayout; private resultRootRef?: HTMLElement; + private linkContainerRef?: HTMLElement; private executedRenderingFunctionOnce = false; @Element() host!: HTMLElement; @@ -37,6 +39,13 @@ export class AtomicRecsResult { */ @Prop() stopPropagation?: boolean; + /** + * The result link to use when the result is clicked in a grid layout. + * + * @default - An `atomic-result-link` without any customization. + */ + @Prop() linkContent: ParentNode = new DocumentFragment(); + /** * The result item. */ @@ -94,6 +103,18 @@ export class AtomicRecsResult { */ @Prop() renderingFunction: ItemRenderingFunction; + @Listen('click') + public handleClick(event: MouseEvent) { + if (this.stopPropagation) { + event.stopPropagation(); + } + this.host + .shadowRoot!.querySelector( + '.link-container > atomic-result-link a:not([slot])' + ) + ?.click(); + } + @Listen('atomic/resolveResult') public resolveResult(event: ItemContextEvent) { event.preventDefault(); @@ -133,11 +154,12 @@ export class AtomicRecsResult { } private getContentHTML() { - return Array.from(this.content!.children) - .map((child) => child.outerHTML) - .join(''); + return parentNodeToString(this.content!); } + private getLinkHTML() { + return parentNodeToString(this.linkContent); + } private get isCustomRenderFunctionMode() { return this.renderingFunction !== undefined; } @@ -158,6 +180,10 @@ export class AtomicRecsResult { class="result-root" ref={(ref) => (this.resultRootRef = ref)} > + ); } @@ -171,6 +197,7 @@ export class AtomicRecsResult { .join(' ')}`} innerHTML={this.getContentHTML()} > + ); } @@ -186,7 +213,8 @@ export class AtomicRecsResult { if (this.shouldExecuteRenderFunction()) { const customRenderOutputAsString = this.renderingFunction!( this.result, - this.resultRootRef! + this.resultRootRef!, + this.linkContainerRef! ); this.resultRootRef!.className += ` ${this.layout diff --git a/packages/atomic/src/pages/index.html b/packages/atomic/src/pages/index.html index 5d54fd9a883..41255b0b1ff 100644 --- a/packages/atomic/src/pages/index.html +++ b/packages/atomic/src/pages/index.html @@ -230,7 +230,6 @@ -