From 3579383987c6a127b4f0c569ec47789546e45316 Mon Sep 17 00:00:00 2001 From: Louis Bompart Date: Wed, 28 Aug 2024 22:36:26 -0400 Subject: [PATCH] fix(atomic): revert new grid card click behavior/link https://coveord.atlassian.net/browse/KIT-3508 --- .prettierignore | 3 +- .../atomic-angular.module.ts | 2 - .../src/lib/stencil-generated/components.ts | 27 +-- .../commerce/CommerceProductListWrapper.tsx | 38 +--- .../CommerceRecommendationListWrapper.tsx | 38 +--- .../recommendation/RecsListWrapper.tsx | 31 +--- .../components/search/ResultListWrapper.tsx | 31 +--- .../result-components/result-link.cypress.ts | 2 +- .../result-text-selectors.ts | 2 +- packages/atomic/src/components.d.ts | 50 +---- ...omic-commerce-product-list.new.stories.tsx | 3 + .../atomic-commerce-product-list.tsx | 34 ++-- .../e2e/atomic-commerce-product-list.e2e.ts | 7 +- .../atomic-commerce-recommendation-list.tsx | 32 ++-- .../atomic-product/atomic-product.tsx | 38 +--- .../product-list/product-template-provider.ts | 73 +++----- .../atomic-product-template.tsx | 1 - .../product-template-common.tsx | 26 +-- ...c-commerce-search-box-instant-products.tsx | 4 +- .../common/item-list/display-grid.tsx | 30 ++- .../common/item-list/item-list-common.tsx | 6 +- .../item-list/item-template-provider.ts | 35 +--- .../result-template-common.tsx | 30 +-- .../template-provider/template-provider.ts | 33 ++-- .../template-system/template-system.pcss | 4 - .../atomic-recs-list/atomic-ipx-recs-list.tsx | 33 ++-- .../atomic-recs-list/atomic-recs-list.tsx | 33 ++-- .../search/atomic-result/atomic-result.tsx | 38 +--- .../atomic-result-list/atomic-result-list.tsx | 35 ++-- .../result-template-decorators.spec.tsx | 6 + .../atomic-result-template.tsx | 3 +- .../atomic-search-box-instant-results.tsx | 4 +- packages/atomic/src/pages/index.html | 1 - packages/atomic/src/utils/dom-utils.tsx | 6 - .../product-templates-manager.ts | 17 +- .../result-templates-manager.ts | 27 +-- .../features/templates/templates-manager.ts | 41 +---- .../atomic-react/src/pages/ResultListPage.tsx | 173 ++++++++++-------- 38 files changed, 319 insertions(+), 678 deletions(-) diff --git a/.prettierignore b/.prettierignore index 26b8de76282..1bbac2f56e2 100644 --- a/.prettierignore +++ b/.prettierignore @@ -22,5 +22,4 @@ packages/atomic/src/external-builds/**/* packages/atomic/src/generated/** packages/quantic/docs/out/quantic-docs.json packages/samples/headless-react/build/**/* -packages/samples/angular/src/lang/*.json -packages/samples/vuejs/public/lang/*.json \ No newline at end of file +packages/samples/angular/src/lang/*.json \ No newline at end of file diff --git a/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/atomic-angular.module.ts b/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/atomic-angular.module.ts index cd71a0561c3..64a2bbc46c5 100644 --- a/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/atomic-angular.module.ts +++ b/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/atomic-angular.module.ts @@ -17,7 +17,6 @@ AtomicCommerceFacets, AtomicCommerceInterface, AtomicCommerceLoadMoreProducts, AtomicCommercePager, -AtomicCommerceProductList, AtomicCommerceProductsPerPage, AtomicCommerceQuerySummary, AtomicCommerceRefineModal, @@ -129,7 +128,6 @@ AtomicCommerceFacets, AtomicCommerceInterface, AtomicCommerceLoadMoreProducts, AtomicCommercePager, -AtomicCommerceProductList, AtomicCommerceProductsPerPage, AtomicCommerceQuerySummary, AtomicCommerceRefineModal, 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 f828f2684bd..1fdba07a8bb 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 @@ -274,29 +274,6 @@ export declare interface AtomicCommercePager extends Components.AtomicCommercePa } -@ProxyCmp({ - inputs: ['density', 'display', 'gridCellLinkTarget', 'imageSize', 'numberOfPlaceholders'], - methods: ['setRenderFunction'] -}) -@Component({ - selector: 'atomic-commerce-product-list', - changeDetection: ChangeDetectionStrategy.OnPush, - template: '', - // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['density', 'display', 'gridCellLinkTarget', 'imageSize', 'numberOfPlaceholders'], -}) -export class AtomicCommerceProductList { - protected el: HTMLElement; - constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { - c.detach(); - this.el = r.nativeElement; - } -} - - -export declare interface AtomicCommerceProductList extends Components.AtomicCommerceProductList {} - - @ProxyCmp({ inputs: ['choicesDisplayed', 'initialChoice'] }) @@ -1302,14 +1279,14 @@ export declare interface AtomicRelevanceInspector extends Components.AtomicRelev @ProxyCmp({ - inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'linkContent', 'result', 'stopPropagation'] + inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'result', 'stopPropagation'] }) @Component({ selector: 'atomic-result', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'linkContent', 'result', 'stopPropagation'], + inputs: ['classes', 'content', 'density', 'display', 'imageSize', 'result', 'stopPropagation'], }) export class AtomicResult { protected el: HTMLElement; diff --git a/packages/atomic-react/src/components/commerce/CommerceProductListWrapper.tsx b/packages/atomic-react/src/components/commerce/CommerceProductListWrapper.tsx index 4769ae01562..d10f7441ca3 100644 --- a/packages/atomic-react/src/components/commerce/CommerceProductListWrapper.tsx +++ b/packages/atomic-react/src/components/commerce/CommerceProductListWrapper.tsx @@ -3,15 +3,7 @@ import type {Product} from '@coveo/headless/commerce'; import React, {useEffect, useRef} from 'react'; import {createRoot} from 'react-dom/client'; import {renderToString} from 'react-dom/server'; -import { - AtomicCommerceProductList, - AtomicProductLink, -} from '../stencil-generated/commerce'; - -interface Template { - contentTemplate: JSX.Element; - linkTemplate: JSX.Element; -} +import {AtomicCommerceProductList} from '../stencil-generated/commerce'; /** * The properties of the AtomicCommerceProductList component @@ -21,7 +13,7 @@ interface WrapperProps extends AtomicJSX.AtomicCommerceProductList { * A template function that takes a result item and outputs its target rendering as a JSX element. * It can be used to conditionally render different type of result templates based on the properties of each result. */ - template: (result: Product) => JSX.Element | Template; + template: (result: Product) => JSX.Element; } /** @@ -35,30 +27,12 @@ export const ListWrapper: React.FC = (props) => { const commerceProductListRef = useRef(null); useEffect(() => { - commerceProductListRef.current?.setRenderFunction( - (product, root, linkContainer) => { - const templateResult = template(product as Product); - if (hasLinkTemplate(templateResult)) { - createRoot(linkContainer!).render(templateResult.linkTemplate); - createRoot(root).render(templateResult.contentTemplate); - return renderToString(templateResult.contentTemplate); - } else { - createRoot(root).render(templateResult); - createRoot(linkContainer!).render( - - ); - return renderToString(templateResult); - } - } - ); + commerceProductListRef.current?.setRenderFunction((result, root) => { + createRoot(root).render(template(result as Product)); + return renderToString(template(result as Product)); + }); }, [commerceProductListRef]); return ( ); }; - -const hasLinkTemplate = ( - template: JSX.Element | Template -): template is Template => { - return (template as Template).linkTemplate !== undefined; -}; diff --git a/packages/atomic-react/src/components/commerce/CommerceRecommendationListWrapper.tsx b/packages/atomic-react/src/components/commerce/CommerceRecommendationListWrapper.tsx index dd9b5de1d80..8bc4b731be8 100644 --- a/packages/atomic-react/src/components/commerce/CommerceRecommendationListWrapper.tsx +++ b/packages/atomic-react/src/components/commerce/CommerceRecommendationListWrapper.tsx @@ -3,15 +3,7 @@ import type {Product} from '@coveo/headless/commerce'; import React, {useEffect, useRef} from 'react'; import {createRoot} from 'react-dom/client'; import {renderToString} from 'react-dom/server'; -import { - AtomicCommerceRecommendationList, - AtomicProductLink, -} from '../stencil-generated/commerce'; - -interface Template { - contentTemplate: JSX.Element; - linkTemplate: JSX.Element; -} +import {AtomicCommerceRecommendationList} from '../stencil-generated/commerce'; /** * The properties of the AtomicCommerceRecommendationList component @@ -21,7 +13,7 @@ interface WrapperProps extends AtomicJSX.AtomicCommerceRecommendationList { * A template function that takes a result item and outputs its target rendering as a JSX element. * It can be used to conditionally render different type of result templates based on the properties of each result. */ - template: (result: Product) => JSX.Element | Template; + template: (result: Product) => JSX.Element; } /** @@ -35,22 +27,10 @@ export const ListWrapper: React.FC = (props) => { const commerceRecsListRef = useRef(null); useEffect(() => { - commerceRecsListRef.current?.setRenderFunction( - (product, root, linkContainer) => { - const templateResult = template(product as Product); - if (hasLinkTemplate(templateResult)) { - createRoot(linkContainer!).render(templateResult.linkTemplate); - createRoot(root).render(templateResult.contentTemplate); - return renderToString(templateResult.contentTemplate); - } else { - createRoot(root).render(templateResult); - createRoot(linkContainer!).render( - - ); - return renderToString(templateResult); - } - } - ); + commerceRecsListRef.current?.setRenderFunction((result, root) => { + createRoot(root).render(template(result as Product)); + return renderToString(template(result as Product)); + }); }, [commerceRecsListRef]); return ( = (props) => { /> ); }; - -const hasLinkTemplate = ( - template: JSX.Element | Template -): template is Template => { - return (template as Template).linkTemplate !== undefined; -}; diff --git a/packages/atomic-react/src/components/recommendation/RecsListWrapper.tsx b/packages/atomic-react/src/components/recommendation/RecsListWrapper.tsx index 21f610cae81..43a594887cd 100644 --- a/packages/atomic-react/src/components/recommendation/RecsListWrapper.tsx +++ b/packages/atomic-react/src/components/recommendation/RecsListWrapper.tsx @@ -3,12 +3,7 @@ import type {Result} from '@coveo/headless/recommendation'; import React, {useEffect, useRef} from 'react'; import {createRoot} from 'react-dom/client'; import {renderToString} from 'react-dom/server'; -import {AtomicRecsList, AtomicResultLink} from '../stencil-generated/search'; - -interface Template { - contentTemplate: JSX.Element; - linkTemplate: JSX.Element; -} +import {AtomicRecsList} from '../stencil-generated/search'; /** * The properties of the AtomicRecsList component @@ -18,7 +13,7 @@ interface WrapperProps extends AtomicJSX.AtomicRecsList { * A template function that takes a result item and outputs its target rendering as a JSX element. * It can be used to conditionally render different type of result templates based on the properties of each result. */ - template: (result: Result) => JSX.Element | Template; + template: (result: Result) => JSX.Element; } /** @@ -31,26 +26,10 @@ export const RecsListWrapper: React.FC = (props) => { const {template, ...otherProps} = props; const recsListRef = useRef(null); useEffect(() => { - recsListRef.current?.setRenderFunction((result, root, linkContainer) => { - const templateResult = template(result as Result); - if (hasLinkTemplate(templateResult)) { - createRoot(linkContainer!).render(templateResult.linkTemplate); - createRoot(root).render(templateResult.contentTemplate); - return renderToString(templateResult.contentTemplate); - } else { - createRoot(root).render(templateResult); - createRoot(linkContainer!).render( - - ); - return renderToString(templateResult); - } + recsListRef.current?.setRenderFunction((result, root) => { + createRoot(root).render(template(result as Result)); + return renderToString(template(result as Result)); }); }, [recsListRef]); return ; }; - -const hasLinkTemplate = ( - template: JSX.Element | Template -): template is Template => { - return (template as Template).linkTemplate !== undefined; -}; diff --git a/packages/atomic-react/src/components/search/ResultListWrapper.tsx b/packages/atomic-react/src/components/search/ResultListWrapper.tsx index 183c1489a04..e685d9ba2fe 100644 --- a/packages/atomic-react/src/components/search/ResultListWrapper.tsx +++ b/packages/atomic-react/src/components/search/ResultListWrapper.tsx @@ -3,12 +3,7 @@ import type {Result} from '@coveo/headless'; import React, {useEffect, useRef} from 'react'; import {createRoot} from 'react-dom/client'; import {renderToString} from 'react-dom/server'; -import {AtomicResultLink, AtomicResultList} from '../stencil-generated/search'; - -interface Template { - contentTemplate: JSX.Element; - linkTemplate: JSX.Element; -} +import {AtomicResultList} from '../stencil-generated/search'; /** * The properties of the AtomicResultList component @@ -18,7 +13,7 @@ interface WrapperProps extends AtomicJSX.AtomicResultList { * A template function that takes a result item and outputs its target rendering as a JSX element. * It can be used to conditionally render different type of result templates based on the properties of each result. */ - template: (result: Result) => JSX.Element | Template; + template: (result: Result) => JSX.Element; } /** @@ -31,26 +26,10 @@ export const ResultListWrapper: React.FC = (props) => { const {template, ...otherProps} = props; const resultListRef = useRef(null); useEffect(() => { - resultListRef.current?.setRenderFunction((result, root, linkContainer) => { - const templateResult = template(result as Result); - if (hasLinkTemplate(templateResult)) { - createRoot(linkContainer!).render(templateResult.linkTemplate); - createRoot(root).render(templateResult.contentTemplate); - return renderToString(templateResult.contentTemplate); - } else { - createRoot(root).render(templateResult); - createRoot(linkContainer!).render( - - ); - return renderToString(templateResult); - } + resultListRef.current?.setRenderFunction((result, root) => { + createRoot(root).render(template(result as Result)); + return renderToString(template(result as Result)); }); }, [resultListRef]); return ; }; - -const hasLinkTemplate = ( - template: JSX.Element | Template -): template is Template => { - return (template as Template).linkTemplate !== undefined; -}; diff --git a/packages/atomic/cypress/e2e/result-list/result-components/result-link.cypress.ts b/packages/atomic/cypress/e2e/result-list/result-components/result-link.cypress.ts index 23cdfea9cdb..1f4ece4229b 100644 --- a/packages/atomic/cypress/e2e/result-list/result-components/result-link.cypress.ts +++ b/packages/atomic/cypress/e2e/result-list/result-components/result-link.cypress.ts @@ -81,7 +81,7 @@ describe('Result Link Component', () => { }); it('should render an "atomic-result-text" component containing the title', () => { - ResultLinkSelectors.firstInResult().first().should('have.text', title); + ResultLinkSelectors.firstInResult().should('have.text', title); }); }); diff --git a/packages/atomic/cypress/e2e/result-list/result-components/result-text-selectors.ts b/packages/atomic/cypress/e2e/result-list/result-components/result-text-selectors.ts index bd24d7265e1..4806a1cdd37 100644 --- a/packages/atomic/cypress/e2e/result-list/result-components/result-text-selectors.ts +++ b/packages/atomic/cypress/e2e/result-list/result-components/result-text-selectors.ts @@ -5,6 +5,6 @@ export const resultTextComponent = 'atomic-result-text'; export const ResultTextSelectors = { shadow: () => cy.get(resultTextComponent), firstInResult: () => - ResultListSelectors.firstResult().find(resultTextComponent).first(), + ResultListSelectors.firstResult().find(resultTextComponent), highlight: () => ResultTextSelectors.firstInResult().find('b'), }; diff --git a/packages/atomic/src/components.d.ts b/packages/atomic/src/components.d.ts index f0a27c8119d..c2bc9d757d5 100644 --- a/packages/atomic/src/components.d.ts +++ b/packages/atomic/src/components.d.ts @@ -479,9 +479,6 @@ export namespace Components { */ "previousButtonIcon": string; } - /** - * @alpha The `atomic-commerce-product-list` component is responsible for displaying products. - */ interface AtomicCommerceProductList { /** * The spacing of various elements in the product list, including the gap between products, the gap between parts of a product, and the font sizes of different parts in a product. @@ -494,7 +491,6 @@ export namespace Components { /** * The target location to open the product link (see [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)). This property is only leveraged when `display` is `grid`. * @defaultValue `_self` - * @deprecated - Instead of using this property, provide an `atomic-product-link` in the `link` slot of the `atomic-product-template` component. */ "gridCellLinkTarget": ItemTarget; /** @@ -597,7 +593,6 @@ export namespace Components { /** * The [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target) location to open the product link. This property is ignored unless the `display` property is set to `grid`. * @defaultValue `_self` - * @deprecated - Instead of using this property, provide an `atomic-product-link` in the `link` slot of the `atomic-product-template` component. */ "gridCellLinkTarget": ItemTarget; /** @@ -1643,7 +1638,6 @@ export namespace Components { /** * The target location to open the result link (see [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)). This property is only leveraged when `display` is `grid`. * @defaultValue `_self` - * @deprecated - Instead of using this property, provide an `atomic-result-link` in the `link` slot of the `atomic-result-template` component. */ "gridCellLinkTarget": ItemTarget1; /** @@ -1935,11 +1929,6 @@ export namespace Components { * The InteractiveProduct item. */ "interactiveProduct": InteractiveProduct; - /** - * The product link to use when the product is clicked in a grid layout. - * @default - An `atomic-result-link` without any customization. - */ - "linkContent": ParentNode; "loadingFlag"?: string; /** * The product item. @@ -2384,7 +2373,6 @@ export namespace Components { /** * The target location to open the result link (see [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)). This property is only leveraged when `display` is `grid`. * @defaultValue `_self` - * @deprecated - Instead of using this property, provide an `atomic-result-link` in the `link` slot of the `atomic-result-template` component. */ "gridCellLinkTarget": ItemTarget; /** @@ -2556,11 +2544,6 @@ export namespace Components { * The InteractiveResult item. */ "interactiveResult": InteractiveResult; - /** - * 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 @@ -2740,7 +2723,6 @@ export namespace Components { /** * The target location to open the result link (see [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)). This property is only leveraged when `display` is `grid`. * @defaultValue `_self` - * @deprecated - Instead of using this property, provide an `atomic-result-link` in the `link` slot of the `atomic-result-template` component. */ "gridCellLinkTarget": ItemTarget; /** @@ -2941,6 +2923,8 @@ export namespace Components { } /** * A [result template](https://docs.coveo.com/en/atomic/latest/usage/displaying-results#defining-a-result-template) determines the format of the query results, depending on the conditions that are defined for each template. + * A `template` element must be the child of an `atomic-result-template`, and either an `atomic-result-list` or `atomic-folded-result-list` must be the parent of each `atomic-result-template`. + * **Note:** Any `