-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Commerce Atomic): add product text component (#3902)
This PR adds atomic-product-text and atomic-commerce-text. https://coveord.atlassian.net/browse/KIT-3150 --------- Co-authored-by: Olivier Lamothe <[email protected]> Co-authored-by: GitHub Actions Bot <> Co-authored-by: Frederic Beaudoin <[email protected]>
- Loading branch information
1 parent
784f805
commit 01a9035
Showing
10 changed files
with
242 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
packages/atomic/src/components/commerce/atomic-commerce-text/atomic-commerce-text.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import {Component, Prop, State} from '@stencil/core'; | ||
import { | ||
InitializableComponent, | ||
InitializeBindings, | ||
} from '../../../utils/initialization-utils'; | ||
import {CommerceBindings} from '../atomic-commerce-interface/atomic-commerce-interface'; | ||
|
||
/** | ||
* @internal | ||
* The `atomic-commerce-text` component leverages the I18n translation module through the atomic-commerce-interface. | ||
*/ | ||
@Component({ | ||
tag: 'atomic-commerce-text', | ||
shadow: true, | ||
}) | ||
export class AtomicCommerceText | ||
implements InitializableComponent<CommerceBindings> | ||
{ | ||
@InitializeBindings() public bindings!: CommerceBindings; | ||
|
||
private strings = { | ||
value: () => | ||
this.bindings.i18n.t(this.value, { | ||
count: this.count, | ||
}), | ||
}; | ||
@State() public error!: Error; | ||
|
||
/** | ||
* The string key value. | ||
*/ | ||
@Prop({reflect: true}) public value!: string; | ||
/** | ||
* The count value used for plurals. | ||
*/ | ||
@Prop({reflect: true}) public count?: number; | ||
|
||
public connectedCallback() { | ||
if (!this.value) { | ||
this.error = new Error('The "value" attribute must be defined.'); | ||
} | ||
} | ||
|
||
public render() { | ||
return this.strings.value(); | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
...mponents/commerce/product-template-components/atomic-product-text/atomic-product-text.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import {Product, ProductTemplatesHelpers} from '@coveo/headless/commerce'; | ||
import {Component, h, Prop, Element} from '@stencil/core'; | ||
import {isArray} from 'lodash'; | ||
import {getFieldValueCaption} from '../../../../utils/field-utils'; | ||
import { | ||
InitializableComponent, | ||
InitializeBindings, | ||
} from '../../../../utils/initialization-utils'; | ||
import {CommerceBindings} from '../../atomic-commerce-interface/atomic-commerce-interface'; | ||
import {ProductContext} from '../product-template-decorators'; | ||
import {getStringValueFromProductOrNull} from '../product-utils'; | ||
|
||
/** | ||
* @internal | ||
* The `atomic-product-text` component renders the value of a string product field. | ||
*/ | ||
@Component({ | ||
tag: 'atomic-product-text', | ||
shadow: false, | ||
}) | ||
export class AtomicProductText | ||
implements InitializableComponent<CommerceBindings> | ||
{ | ||
@InitializeBindings() public bindings!: CommerceBindings; | ||
public error!: Error; | ||
|
||
@ProductContext() private product!: Product; | ||
|
||
@Element() private host!: HTMLElement; | ||
|
||
/** | ||
* The product field which the component should use. | ||
* This will look in the Product object first, and then in the product.additionalFields object for the fields. | ||
*/ | ||
@Prop({reflect: true}) public field!: string; | ||
/** | ||
* The locale key for the text to display when the configured field has no value. | ||
*/ | ||
@Prop({reflect: true}) public default?: string; | ||
|
||
private possiblyWarnOnBadFieldType() { | ||
const productValueRaw = ProductTemplatesHelpers.getProductProperty( | ||
this.product, | ||
this.field | ||
); | ||
if (isArray(productValueRaw)) { | ||
this.bindings.engine.logger.error( | ||
`atomic-product-text cannot be used with multi value field "${this.field}" with values "${productValueRaw}".`, | ||
this | ||
); | ||
} | ||
} | ||
|
||
public render() { | ||
const productValueAsString = getStringValueFromProductOrNull( | ||
this.product, | ||
this.field | ||
); | ||
|
||
if (!productValueAsString && !this.default) { | ||
this.possiblyWarnOnBadFieldType(); | ||
this.host.remove(); | ||
return; | ||
} | ||
|
||
if (!productValueAsString && this.default) { | ||
this.possiblyWarnOnBadFieldType(); | ||
return ( | ||
<atomic-commerce-text | ||
value={getFieldValueCaption( | ||
this.field, | ||
productValueAsString ?? this.default, | ||
this.bindings.i18n | ||
)} | ||
></atomic-commerce-text> | ||
); | ||
} | ||
|
||
if (productValueAsString !== null) { | ||
this.possiblyWarnOnBadFieldType(); | ||
return ( | ||
<atomic-commerce-text | ||
value={getFieldValueCaption( | ||
this.field, | ||
productValueAsString, | ||
this.bindings.i18n | ||
)} | ||
></atomic-commerce-text> | ||
); | ||
} | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
packages/atomic/src/components/commerce/product-template-components/product-utils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import {Product, ProductTemplatesHelpers} from '@coveo/headless/commerce'; | ||
|
||
export function getStringValueFromProductOrNull( | ||
product: Product, | ||
field: string | ||
) { | ||
const value = ProductTemplatesHelpers.getProductProperty(product, field); | ||
|
||
if (typeof value !== 'string' || value.trim() === '') { | ||
return null; | ||
} | ||
|
||
return value; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.