Skip to content

Commit

Permalink
feat(atomic, commerce): create atomic-product-multi-value-text compon…
Browse files Browse the repository at this point in the history
…ent (#4224)

https://coveord.atlassian.net/browse/KIT-3440

Implement the `atomic-product-multi-value-text` component to render the
values of a multi-value string field.

* **New Component**: Add `atomic-product-multi-value-text` component in
`packages/atomic/src/components/commerce/product-template-components/atomic-product-multi-value-text/atomic-product-multi-value-text.tsx`.
- Combine functionalities from `atomic-product-text`,
`atomic-result-text`, and `atomic-result-multi-value-text`.
  - Use `ProductContext` to get the product data.
  - Use `getFieldValueCaption` to get the field value caption.
  - Render the multi-value text field values.
* **Storybook**: Add a new story for `atomic-product-multi-value-text`
in
`packages/atomic/src/components/commerce/product-template-components/atomic-product-multi-value-text/atomic-product-multi-value-text.new.stories.tsx`.
  - Test rendering of multi-value text field values.
  - Test rendering with different `max-values-to-display` values.
  - Test rendering with custom slot values.


---

For more details, open the [Copilot Workspace
session](https://copilot-workspace.githubnext.com/coveo/ui-kit?shareId=02336614-673d-4772-9196-21872fd10d36).

---
KIT-3440

---------

Co-authored-by: Frederic Beaudoin <[email protected]>
Co-authored-by: GitHub Actions Bot <>
Co-authored-by: ylakhdar <[email protected]>
  • Loading branch information
3 people authored Nov 4, 2024
1 parent 38970c3 commit 949d6ca
Show file tree
Hide file tree
Showing 17 changed files with 647 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ AtomicProductExcerpt,
AtomicProductFieldCondition,
AtomicProductImage,
AtomicProductLink,
AtomicProductMultiValueText,
AtomicProductNumericFieldValue,
AtomicProductPrice,
AtomicProductRating,
Expand Down Expand Up @@ -210,6 +211,7 @@ AtomicProductExcerpt,
AtomicProductFieldCondition,
AtomicProductImage,
AtomicProductLink,
AtomicProductMultiValueText,
AtomicProductNumericFieldValue,
AtomicProductPrice,
AtomicProductRating,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1388,6 +1388,28 @@ export class AtomicProductLink {
export declare interface AtomicProductLink extends Components.AtomicProductLink {}


@ProxyCmp({
inputs: ['delimiter', 'field', 'maxValuesToDisplay']
})
@Component({
selector: 'atomic-product-multi-value-text',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['delimiter', 'field', 'maxValuesToDisplay'],
})
export class AtomicProductMultiValueText {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}


export declare interface AtomicProductMultiValueText extends Components.AtomicProductMultiValueText {}


@ProxyCmp({
inputs: ['field']
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const AtomicProductExcerpt = /*@__PURE__*/createReactComponent<JSX.Atomic
export const AtomicProductFieldCondition = /*@__PURE__*/createReactComponent<JSX.AtomicProductFieldCondition, HTMLAtomicProductFieldConditionElement>('atomic-product-field-condition');
export const AtomicProductImage = /*@__PURE__*/createReactComponent<JSX.AtomicProductImage, HTMLAtomicProductImageElement>('atomic-product-image');
export const AtomicProductLink = /*@__PURE__*/createReactComponent<JSX.AtomicProductLink, HTMLAtomicProductLinkElement>('atomic-product-link');
export const AtomicProductMultiValueText = /*@__PURE__*/createReactComponent<JSX.AtomicProductMultiValueText, HTMLAtomicProductMultiValueTextElement>('atomic-product-multi-value-text');
export const AtomicProductNumericFieldValue = /*@__PURE__*/createReactComponent<JSX.AtomicProductNumericFieldValue, HTMLAtomicProductNumericFieldValueElement>('atomic-product-numeric-field-value');
export const AtomicProductPrice = /*@__PURE__*/createReactComponent<JSX.AtomicProductPrice, HTMLAtomicProductPriceElement>('atomic-product-price');
export const AtomicProductRating = /*@__PURE__*/createReactComponent<JSX.AtomicProductRating, HTMLAtomicProductRatingElement>('atomic-product-rating');
Expand Down
49 changes: 49 additions & 0 deletions packages/atomic/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2162,6 +2162,23 @@ export namespace Components {
*/
"hrefTemplate"?: string;
}
/**
* The `atomic-product-multi-value-text` component renders the values of a multi-value string field.
*/
interface AtomicProductMultiValueText {
/**
* The delimiter used to separate values when the field isn't indexed as a multi value field.
*/
"delimiter": string | null;
/**
* The field that the component should use. The component will try to find this field in the `Product.additionalFields` object unless it finds it in the `Product` object first. Make sure this field is present in the `fieldsToInclude` property of the `atomic-commerce-interface` component.
*/
"field": string;
/**
* The maximum number of field values to display. If there are _n_ more values than the specified maximum, the last displayed value will be "_n_ more...".
*/
"maxValuesToDisplay": number;
}
/**
* @alpha The `atomic-product-numeric-field-value` component renders the value of a number product field.
* The number can be formatted by adding a `atomic-format-number`, `atomic-format-currency` or `atomic-format-unit` component into this component.
Expand Down Expand Up @@ -4972,6 +4989,15 @@ declare global {
prototype: HTMLAtomicProductLinkElement;
new (): HTMLAtomicProductLinkElement;
};
/**
* The `atomic-product-multi-value-text` component renders the values of a multi-value string field.
*/
interface HTMLAtomicProductMultiValueTextElement extends Components.AtomicProductMultiValueText, HTMLStencilElement {
}
var HTMLAtomicProductMultiValueTextElement: {
prototype: HTMLAtomicProductMultiValueTextElement;
new (): HTMLAtomicProductMultiValueTextElement;
};
/**
* @alpha The `atomic-product-numeric-field-value` component renders the value of a number product field.
* The number can be formatted by adding a `atomic-format-number`, `atomic-format-currency` or `atomic-format-unit` component into this component.
Expand Down Expand Up @@ -6098,6 +6124,7 @@ declare global {
"atomic-product-field-condition": HTMLAtomicProductFieldConditionElement;
"atomic-product-image": HTMLAtomicProductImageElement;
"atomic-product-link": HTMLAtomicProductLinkElement;
"atomic-product-multi-value-text": HTMLAtomicProductMultiValueTextElement;
"atomic-product-numeric-field-value": HTMLAtomicProductNumericFieldValueElement;
"atomic-product-price": HTMLAtomicProductPriceElement;
"atomic-product-rating": HTMLAtomicProductRatingElement;
Expand Down Expand Up @@ -8189,6 +8216,23 @@ declare namespace LocalJSX {
*/
"hrefTemplate"?: string;
}
/**
* The `atomic-product-multi-value-text` component renders the values of a multi-value string field.
*/
interface AtomicProductMultiValueText {
/**
* The delimiter used to separate values when the field isn't indexed as a multi value field.
*/
"delimiter"?: string | null;
/**
* The field that the component should use. The component will try to find this field in the `Product.additionalFields` object unless it finds it in the `Product` object first. Make sure this field is present in the `fieldsToInclude` property of the `atomic-commerce-interface` component.
*/
"field": string;
/**
* The maximum number of field values to display. If there are _n_ more values than the specified maximum, the last displayed value will be "_n_ more...".
*/
"maxValuesToDisplay"?: number;
}
/**
* @alpha The `atomic-product-numeric-field-value` component renders the value of a number product field.
* The number can be formatted by adding a `atomic-format-number`, `atomic-format-currency` or `atomic-format-unit` component into this component.
Expand Down Expand Up @@ -9861,6 +9905,7 @@ declare namespace LocalJSX {
"atomic-product-field-condition": AtomicProductFieldCondition;
"atomic-product-image": AtomicProductImage;
"atomic-product-link": AtomicProductLink;
"atomic-product-multi-value-text": AtomicProductMultiValueText;
"atomic-product-numeric-field-value": AtomicProductNumericFieldValue;
"atomic-product-price": AtomicProductPrice;
"atomic-product-rating": AtomicProductRating;
Expand Down Expand Up @@ -10327,6 +10372,10 @@ declare module "@stencil/core" {
* @alpha The `atomic-product-link` component automatically transforms a search product title into a clickable link that points to the original item.
*/
"atomic-product-link": LocalJSX.AtomicProductLink & JSXBase.HTMLAttributes<HTMLAtomicProductLinkElement>;
/**
* The `atomic-product-multi-value-text` component renders the values of a multi-value string field.
*/
"atomic-product-multi-value-text": LocalJSX.AtomicProductMultiValueText & JSXBase.HTMLAttributes<HTMLAtomicProductMultiValueTextElement>;
/**
* @alpha The `atomic-product-numeric-field-value` component renders the value of a number product field.
* The number can be formatted by adding a `atomic-format-number`, `atomic-format-currency` or `atomic-format-unit` component into this component.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {wrapInCommerceInterface} from '@coveo/atomic-storybook-utils/commerce/commerce-interface-wrapper';
import {wrapInCommerceProductList} from '@coveo/atomic-storybook-utils/commerce/commerce-product-list-wrapper';
import {wrapInProductTemplate} from '@coveo/atomic-storybook-utils/commerce/commerce-product-template-wrapper';
import {parameters} from '@coveo/atomic-storybook-utils/common/common-meta-parameters';
import {renderComponent} from '@coveo/atomic-storybook-utils/common/render-component';
import {getSampleCommerceEngineConfiguration} from '@coveo/headless/commerce';
import type {Meta, StoryObj as Story} from '@storybook/web-components';
import {html} from 'lit/static-html.js';

const baseConfiguration = getSampleCommerceEngineConfiguration();

const {decorator: productDecorator} = wrapInProductTemplate();
const {decorator: commerceProductListDecorator} = wrapInCommerceProductList();
const {decorator: commerceInterfaceDecorator, play} = wrapInCommerceInterface({
engineConfig: {
...baseConfiguration,
context: {
...baseConfiguration.context,
view: {
url: 'https://sports.barca.group/browse/promotions/ui-kit-testing-product-multi-value-text',
},
},
},
type: 'product-listing',
});

const meta: Meta = {
component: 'atomic-product-multi-value-text',
title: 'Atomic-Commerce/Product Template Components/MultiValueText',
id: 'atomic-product-multi-value-text',
render: renderComponent,
parameters,
play,
args: {
'attributes-field': 'cat_available_sizes',
},
};

export default meta;

export const Default: Story = {
name: 'atomic-product-multi-value-text',
decorators: [
productDecorator,
commerceProductListDecorator,
commerceInterfaceDecorator,
],
};

export const WithDelimiter: Story = {
name: 'With delimiter',
decorators: [
productDecorator,
commerceProductListDecorator,
commerceInterfaceDecorator,
],
args: {
'attributes-field': 'ec_product_id',
'attributes-delimiter': '_',
},
};

export const WithMaxValuesToDisplaySetToMinimum: Story = {
name: 'With max values to display set to minimum',
decorators: [
productDecorator,
commerceProductListDecorator,
commerceInterfaceDecorator,
],
args: {
'attributes-max-values-to-display': 1,
},
};

export const WithMaxValuesToDisplaySetToTotalNumberOfValues: Story = {
name: 'With max values to display set to total number of values',
decorators: [
productDecorator,
commerceProductListDecorator,
commerceInterfaceDecorator,
],
args: {
'attributes-max-values-to-display': 6,
},
};

export const InAPageWithTheCorrespondingFacet: Story = {
name: 'In a page with the corresponding facet',
decorators: [
productDecorator,
commerceProductListDecorator,
(story) => {
return html`
<atomic-commerce-layout>
<atomic-layout-section section="facets"
><atomic-commerce-facets></atomic-commerce-facets>
</atomic-layout-section>
<atomic-layout-section section="main">
${story()}
</atomic-layout-section>
</atomic-commerce-layout>
`;
},
commerceInterfaceDecorator,
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
:host {
> ul {
display: flex;
list-style: none;
margin: 0;
padding: 0;

li {
display: inline-block;
}
}
}

.separator {
&::before {
display: inline;
content: ',\00a0';
}
}
Loading

0 comments on commit 949d6ca

Please sign in to comment.