@coveo/atomic 3.31.2-pre.250e2f6259 → 3.31.2-pre.25fd3f0b2d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atomic/_atomic.esm.js +1 -1
- package/dist/atomic/atomic.esm.js.map +1 -1
- package/dist/atomic/components/_index.d.ts +0 -2
- package/dist/atomic/components/_index.js +1 -3
- package/dist/atomic/components/analytics-config.js +1 -1
- package/dist/atomic/components/atomic-product-rating.js +34 -2
- package/dist/atomic/components/atomic-product-rating.js.map +1 -1
- package/dist/atomic/components/components/commerce/atomic-product-field-condition/atomic-product-field-condition.js +70 -0
- package/dist/atomic/components/components/commerce/atomic-product-template/atomic-product-template.js +1 -0
- package/dist/atomic/components/components/commerce/index.js +1 -0
- package/dist/atomic/components/components/commerce/lazy-index.js +1 -0
- package/dist/atomic/components/global/environment.js +1 -1
- package/dist/atomic/components/index.js.map +1 -1
- package/dist/atomic/{p-9d58dc80.entry.js → p-48c24b74.entry.js} +2 -2
- package/dist/atomic/{p-940a79a5.js → p-96b96395.js} +2 -2
- package/dist/atomic/{p-e6f4dfb3.entry.js → p-af06280e.entry.js} +2 -2
- package/dist/atomic/{p-7b928196.entry.js → p-f876f7f7.entry.js} +2 -2
- package/dist/cjs/_loader.cjs.js +1 -1
- package/dist/cjs/{analytics-config-05d4b837.js → analytics-config-df2581de.js} +2 -2
- package/dist/cjs/{analytics-config-05d4b837.js.map → analytics-config-df2581de.js.map} +1 -1
- package/dist/cjs/atomic-insight-interface.cjs.entry.js +1 -1
- package/dist/cjs/atomic-recs-interface.cjs.entry.js +1 -1
- package/dist/cjs/atomic-search-interface.cjs.entry.js +1 -1
- package/dist/cjs/atomic.cjs.js +1 -1
- package/dist/cjs/index-757bc886.js +0 -4
- package/dist/cjs/version.cjs.js +2 -2
- package/dist/esm/_loader.js +1 -1
- package/dist/esm/{analytics-config-b8a89287.js → analytics-config-482fd000.js} +2 -2
- package/dist/esm/{analytics-config-b8a89287.js.map → analytics-config-482fd000.js.map} +1 -1
- package/dist/esm/atomic-insight-interface.entry.js +1 -1
- package/dist/esm/atomic-recs-interface.entry.js +1 -1
- package/dist/esm/atomic-search-interface.entry.js +1 -1
- package/dist/esm/atomic.js +1 -1
- package/dist/esm/index-3f35faca.js +0 -4
- package/dist/esm/version.js +2 -2
- package/dist/types/components/commerce/atomic-product-field-condition/atomic-product-field-condition.d.ts +24 -13
- package/dist/types/components/commerce/atomic-product-template/atomic-product-template.d.ts +1 -0
- package/dist/types/components/commerce/index.d.ts +1 -0
- package/dist/types/components.d.ts +0 -69
- package/docs/atomic-docs.json +1 -134
- package/package.json +3 -3
- package/dist/atomic/components/atomic-product-field-condition.d.ts +0 -11
- package/dist/atomic/components/atomic-product-field-condition.js +0 -131
- package/dist/atomic/components/atomic-product-field-condition.js.map +0 -1
- package/dist/atomic/components/stencil-product-template-decorators.js +0 -37
- package/dist/atomic/components/stencil-product-template-decorators.js.map +0 -1
- package/dist/atomic/p-a0b3c6e2.entry.js +0 -2
- package/dist/atomic/p-a0b3c6e2.entry.js.map +0 -1
- package/dist/cjs/atomic-product-field-condition.cjs.entry.js +0 -119
- package/dist/cjs/atomic-product-field-condition.cjs.entry.js.map +0 -1
- package/dist/esm/atomic-product-field-condition.entry.js +0 -115
- package/dist/esm/atomic-product-field-condition.entry.js.map +0 -1
- /package/dist/atomic/{p-9d58dc80.entry.js.map → p-48c24b74.entry.js.map} +0 -0
- /package/dist/atomic/{p-940a79a5.js.map → p-96b96395.js.map} +0 -0
- /package/dist/atomic/{p-e6f4dfb3.entry.js.map → p-af06280e.entry.js.map} +0 -0
- /package/dist/atomic/{p-7b928196.entry.js.map → p-f876f7f7.entry.js.map} +0 -0
package/docs/atomic-docs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2025-07-
|
|
2
|
+
"timestamp": "2025-07-31T23:08:21",
|
|
3
3
|
"compiler": {
|
|
4
4
|
"name": "@stencil/core",
|
|
5
5
|
"version": "4.20.0",
|
|
@@ -6562,139 +6562,6 @@
|
|
|
6562
6562
|
]
|
|
6563
6563
|
}
|
|
6564
6564
|
},
|
|
6565
|
-
{
|
|
6566
|
-
"filePath": "src/components/commerce/atomic-product-field-condition/atomic-product-field-condition.tsx",
|
|
6567
|
-
"encapsulation": "none",
|
|
6568
|
-
"tag": "atomic-product-field-condition",
|
|
6569
|
-
"docs": "The `atomic-product-field-condition` component takes a list of conditions that, if fulfilled, apply the template in which it's defined.\nThe condition properties can be based on any top-level product property of the `product` object, not restricted to fields (e.g., `ec_name`).",
|
|
6570
|
-
"docsTags": [
|
|
6571
|
-
{
|
|
6572
|
-
"name": "alpha"
|
|
6573
|
-
}
|
|
6574
|
-
],
|
|
6575
|
-
"usage": {},
|
|
6576
|
-
"props": [
|
|
6577
|
-
{
|
|
6578
|
-
"name": "ifDefined",
|
|
6579
|
-
"type": "string | undefined",
|
|
6580
|
-
"complexType": {
|
|
6581
|
-
"original": "string",
|
|
6582
|
-
"resolved": "string | undefined",
|
|
6583
|
-
"references": {}
|
|
6584
|
-
},
|
|
6585
|
-
"mutable": false,
|
|
6586
|
-
"attr": "if-defined",
|
|
6587
|
-
"reflectToAttr": true,
|
|
6588
|
-
"docs": "Verifies whether the specified fields are defined.",
|
|
6589
|
-
"docsTags": [],
|
|
6590
|
-
"values": [
|
|
6591
|
-
{
|
|
6592
|
-
"type": "string"
|
|
6593
|
-
},
|
|
6594
|
-
{
|
|
6595
|
-
"type": "undefined"
|
|
6596
|
-
}
|
|
6597
|
-
],
|
|
6598
|
-
"optional": true,
|
|
6599
|
-
"required": false
|
|
6600
|
-
},
|
|
6601
|
-
{
|
|
6602
|
-
"name": "ifNotDefined",
|
|
6603
|
-
"type": "string | undefined",
|
|
6604
|
-
"complexType": {
|
|
6605
|
-
"original": "string",
|
|
6606
|
-
"resolved": "string | undefined",
|
|
6607
|
-
"references": {}
|
|
6608
|
-
},
|
|
6609
|
-
"mutable": false,
|
|
6610
|
-
"attr": "if-not-defined",
|
|
6611
|
-
"reflectToAttr": true,
|
|
6612
|
-
"docs": "Verifies whether the specified fields are not defined.",
|
|
6613
|
-
"docsTags": [],
|
|
6614
|
-
"values": [
|
|
6615
|
-
{
|
|
6616
|
-
"type": "string"
|
|
6617
|
-
},
|
|
6618
|
-
{
|
|
6619
|
-
"type": "undefined"
|
|
6620
|
-
}
|
|
6621
|
-
],
|
|
6622
|
-
"optional": true,
|
|
6623
|
-
"required": false
|
|
6624
|
-
},
|
|
6625
|
-
{
|
|
6626
|
-
"name": "mustMatch",
|
|
6627
|
-
"type": "{ [x: string]: string[]; }",
|
|
6628
|
-
"complexType": {
|
|
6629
|
-
"original": "Record<string, string[]>",
|
|
6630
|
-
"resolved": "{ [x: string]: string[]; }",
|
|
6631
|
-
"references": {
|
|
6632
|
-
"Record": {
|
|
6633
|
-
"location": "global",
|
|
6634
|
-
"id": "global::Record"
|
|
6635
|
-
}
|
|
6636
|
-
}
|
|
6637
|
-
},
|
|
6638
|
-
"mutable": false,
|
|
6639
|
-
"reflectToAttr": false,
|
|
6640
|
-
"docs": "Verifies whether the specified fields match the specified values.",
|
|
6641
|
-
"docsTags": [
|
|
6642
|
-
{
|
|
6643
|
-
"name": "type",
|
|
6644
|
-
"text": "{Record<string, string[]>}"
|
|
6645
|
-
}
|
|
6646
|
-
],
|
|
6647
|
-
"default": "{}",
|
|
6648
|
-
"values": [
|
|
6649
|
-
{
|
|
6650
|
-
"type": "{ [x: string]: string[]; }"
|
|
6651
|
-
}
|
|
6652
|
-
],
|
|
6653
|
-
"optional": false,
|
|
6654
|
-
"required": false
|
|
6655
|
-
},
|
|
6656
|
-
{
|
|
6657
|
-
"name": "mustNotMatch",
|
|
6658
|
-
"type": "{ [x: string]: string[]; }",
|
|
6659
|
-
"complexType": {
|
|
6660
|
-
"original": "Record<string, string[]>",
|
|
6661
|
-
"resolved": "{ [x: string]: string[]; }",
|
|
6662
|
-
"references": {
|
|
6663
|
-
"Record": {
|
|
6664
|
-
"location": "global",
|
|
6665
|
-
"id": "global::Record"
|
|
6666
|
-
}
|
|
6667
|
-
}
|
|
6668
|
-
},
|
|
6669
|
-
"mutable": false,
|
|
6670
|
-
"reflectToAttr": false,
|
|
6671
|
-
"docs": "Verifies whether the specified fields do not match the specified values.",
|
|
6672
|
-
"docsTags": [
|
|
6673
|
-
{
|
|
6674
|
-
"name": "type",
|
|
6675
|
-
"text": "{Record<string, string[]>}"
|
|
6676
|
-
}
|
|
6677
|
-
],
|
|
6678
|
-
"default": "{}",
|
|
6679
|
-
"values": [
|
|
6680
|
-
{
|
|
6681
|
-
"type": "{ [x: string]: string[]; }"
|
|
6682
|
-
}
|
|
6683
|
-
],
|
|
6684
|
-
"optional": false,
|
|
6685
|
-
"required": false
|
|
6686
|
-
}
|
|
6687
|
-
],
|
|
6688
|
-
"methods": [],
|
|
6689
|
-
"events": [],
|
|
6690
|
-
"listeners": [],
|
|
6691
|
-
"styles": [],
|
|
6692
|
-
"slots": [],
|
|
6693
|
-
"parts": [],
|
|
6694
|
-
"dependents": [],
|
|
6695
|
-
"dependencies": [],
|
|
6696
|
-
"dependencyGraph": {}
|
|
6697
|
-
},
|
|
6698
6565
|
{
|
|
6699
6566
|
"filePath": "src/components/commerce/atomic-product-rating/atomic-product-rating.tsx",
|
|
6700
6567
|
"encapsulation": "shadow",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coveo/atomic",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.31.2-pre.
|
|
4
|
+
"version": "3.31.2-pre.25fd3f0b2d",
|
|
5
5
|
"description": "A web-component library for building modern UIs interfacing with the Coveo platform",
|
|
6
6
|
"homepage": "https://docs.coveo.com/en/atomic/latest/",
|
|
7
7
|
"repository": {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@lit/context": "1.1.6",
|
|
74
74
|
"@coveo/bueno": "1.0.24",
|
|
75
|
-
"@coveo/headless": "3.27.8-pre.
|
|
75
|
+
"@coveo/headless": "3.27.8-pre.25fd3f0b2d",
|
|
76
76
|
"@popperjs/core": "2.11.8",
|
|
77
77
|
"@salesforce-ux/design-system": "2.27.2",
|
|
78
78
|
"@stencil/core": "4.20.0",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
},
|
|
159
159
|
"peerDependencies": {
|
|
160
160
|
"@coveo/bueno": "1.0.24",
|
|
161
|
-
"@coveo/headless": "3.27.8-pre.
|
|
161
|
+
"@coveo/headless": "3.27.8-pre.25fd3f0b2d",
|
|
162
162
|
"typescript": ">=5.0.0"
|
|
163
163
|
},
|
|
164
164
|
"peerDependenciesMeta": {
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Components, JSX } from "../../types/components";
|
|
2
|
-
|
|
3
|
-
interface AtomicProductFieldCondition extends Components.AtomicProductFieldCondition, HTMLElement {}
|
|
4
|
-
export const AtomicProductFieldCondition: {
|
|
5
|
-
prototype: AtomicProductFieldCondition;
|
|
6
|
-
new (): AtomicProductFieldCondition;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Used to define this component and all nested components recursively.
|
|
10
|
-
*/
|
|
11
|
-
export const defineCustomElement: () => void;
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client';
|
|
2
|
-
import { M as MapProp } from './props-utils.js';
|
|
3
|
-
import './purify.js';
|
|
4
|
-
import { ProductTemplatesHelpers } from '@coveo/headless/commerce';
|
|
5
|
-
import { P as ProductContext } from './stencil-product-template-decorators.js';
|
|
6
|
-
|
|
7
|
-
// TODO: Replace by Set.prototype.intersection in July 2025
|
|
8
|
-
function intersection(setA, setB) {
|
|
9
|
-
const result = new Set();
|
|
10
|
-
for (const elem of setA) {
|
|
11
|
-
if (setB.has(elem)) {
|
|
12
|
-
result.add(elem);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function makeMatchConditions(mustMatch, mustNotMatch) {
|
|
19
|
-
const conditions = [];
|
|
20
|
-
for (const field in mustMatch) {
|
|
21
|
-
if (mustNotMatch[field]) {
|
|
22
|
-
const mustNotMatchValues = new Set(mustNotMatch[field]);
|
|
23
|
-
const mustMatchValues = new Set(mustMatch[field]);
|
|
24
|
-
const commonValues = intersection(mustNotMatchValues, mustMatchValues);
|
|
25
|
-
if (commonValues.size > 0) {
|
|
26
|
-
console.error(`Conflicting match conditions for field ${field}, the template will be ignored.`, commonValues);
|
|
27
|
-
return [() => false];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
conditions.push(ProductTemplatesHelpers.fieldMustMatch(field, mustMatch[field]));
|
|
31
|
-
}
|
|
32
|
-
for (const field in mustNotMatch) {
|
|
33
|
-
conditions.push(ProductTemplatesHelpers.fieldMustNotMatch(field, mustNotMatch[field]));
|
|
34
|
-
}
|
|
35
|
-
return conditions;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function makeDefinedConditions(ifDefined, ifNotDefined) {
|
|
39
|
-
const conditions = [];
|
|
40
|
-
if (ifDefined) {
|
|
41
|
-
const fieldNames = ifDefined.split(',');
|
|
42
|
-
conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));
|
|
43
|
-
}
|
|
44
|
-
if (ifNotDefined) {
|
|
45
|
-
const fieldNames = ifNotDefined.split(',');
|
|
46
|
-
conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));
|
|
47
|
-
}
|
|
48
|
-
return conditions;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
52
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
53
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
54
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
55
|
-
else
|
|
56
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
57
|
-
if (d = decorators[i])
|
|
58
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
59
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
60
|
-
};
|
|
61
|
-
const AtomicProductFieldCondition$1 = /*@__PURE__*/ proxyCustomElement(class AtomicProductFieldCondition extends HTMLElement {
|
|
62
|
-
constructor() {
|
|
63
|
-
super();
|
|
64
|
-
this.__registerHost();
|
|
65
|
-
/**
|
|
66
|
-
* Verifies whether the specified fields match the specified values.
|
|
67
|
-
* @type {Record<string, string[]>}
|
|
68
|
-
*/
|
|
69
|
-
this.mustMatch = {};
|
|
70
|
-
/**
|
|
71
|
-
* Verifies whether the specified fields do not match the specified values.
|
|
72
|
-
* @type {Record<string, string[]>}
|
|
73
|
-
*/
|
|
74
|
-
this.mustNotMatch = {};
|
|
75
|
-
this.conditions = [];
|
|
76
|
-
this.shouldBeRemoved = false;
|
|
77
|
-
this.ifDefined = undefined;
|
|
78
|
-
this.ifNotDefined = undefined;
|
|
79
|
-
this.mustMatch = {};
|
|
80
|
-
this.mustNotMatch = {};
|
|
81
|
-
}
|
|
82
|
-
componentWillLoad() {
|
|
83
|
-
this.conditions = makeDefinedConditions(this.ifDefined, this.ifNotDefined);
|
|
84
|
-
this.conditions.push(...makeMatchConditions(this.mustMatch, this.mustNotMatch));
|
|
85
|
-
}
|
|
86
|
-
render() {
|
|
87
|
-
if (!this.conditions.every((condition) => condition(this.product))) {
|
|
88
|
-
this.shouldBeRemoved = true;
|
|
89
|
-
return '';
|
|
90
|
-
}
|
|
91
|
-
return h("slot", null);
|
|
92
|
-
}
|
|
93
|
-
componentDidLoad() {
|
|
94
|
-
this.shouldBeRemoved && this.host.remove();
|
|
95
|
-
}
|
|
96
|
-
get host() { return this; }
|
|
97
|
-
}, [4, "atomic-product-field-condition", {
|
|
98
|
-
"ifDefined": [513, "if-defined"],
|
|
99
|
-
"ifNotDefined": [513, "if-not-defined"],
|
|
100
|
-
"mustMatch": [16],
|
|
101
|
-
"mustNotMatch": [16]
|
|
102
|
-
}]);
|
|
103
|
-
__decorate([
|
|
104
|
-
MapProp({ splitValues: true })
|
|
105
|
-
], AtomicProductFieldCondition$1.prototype, "mustMatch", void 0);
|
|
106
|
-
__decorate([
|
|
107
|
-
MapProp({ splitValues: true })
|
|
108
|
-
], AtomicProductFieldCondition$1.prototype, "mustNotMatch", void 0);
|
|
109
|
-
__decorate([
|
|
110
|
-
ProductContext()
|
|
111
|
-
], AtomicProductFieldCondition$1.prototype, "product", void 0);
|
|
112
|
-
function defineCustomElement$1() {
|
|
113
|
-
if (typeof customElements === "undefined") {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
const components = ["atomic-product-field-condition"];
|
|
117
|
-
components.forEach(tagName => { switch (tagName) {
|
|
118
|
-
case "atomic-product-field-condition":
|
|
119
|
-
if (!customElements.get(tagName)) {
|
|
120
|
-
customElements.define(tagName, AtomicProductFieldCondition$1);
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
} });
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const AtomicProductFieldCondition = AtomicProductFieldCondition$1;
|
|
127
|
-
const defineCustomElement = defineCustomElement$1;
|
|
128
|
-
|
|
129
|
-
export { AtomicProductFieldCondition, defineCustomElement };
|
|
130
|
-
|
|
131
|
-
//# sourceMappingURL=atomic-product-field-condition.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"file":"atomic-product-field-condition.js","mappings":"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","names":["AtomicProductFieldCondition"],"sources":["src/utils/set.ts","src/components/common/product-template/product-template-common.ts","src/components/common/product-template/stencil-product-template-common.tsx","src/components/commerce/atomic-product-field-condition/atomic-product-field-condition.tsx"],"sourcesContent":["// TODO: Replace by Set.prototype.intersection in July 2025\nexport function intersection<T>(setA: Set<T>, setB: Set<T>): Set<T> {\n const result = new Set<T>();\n for (const elem of setA) {\n if (setB.has(elem)) {\n result.add(elem);\n }\n }\n return result;\n}\n","import {\n type ProductTemplateCondition,\n ProductTemplatesHelpers,\n} from '@coveo/headless/commerce';\nimport {intersection} from '../../../utils/set';\nimport {isElementNode, isVisualNode} from '../../../utils/utils';\nimport {tableElementTagName} from '../../search/atomic-table-result/table-element-utils';\nimport {isResultSectionNode} from '../layout/sections';\n\ntype TemplateNodeType =\n | 'section'\n | 'metadata'\n | 'table-column-definition'\n | 'other';\n\nexport function getTemplateNodeType(node: Node): TemplateNodeType {\n if (isResultSectionNode(node)) {\n return 'section';\n }\n if (!isVisualNode(node)) {\n return 'metadata';\n }\n if (\n isElementNode(node) &&\n node.tagName.toLowerCase() === tableElementTagName\n ) {\n return 'table-column-definition';\n }\n return 'other';\n}\n\nexport function makeMatchConditions(\n mustMatch: Record<string, string[]>,\n mustNotMatch: Record<string, string[]>\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n for (const field in mustMatch) {\n if (mustNotMatch[field]) {\n const mustNotMatchValues = new Set(mustNotMatch[field]);\n const mustMatchValues = new Set(mustMatch[field]);\n const commonValues = intersection(mustNotMatchValues, mustMatchValues);\n if (commonValues.size > 0) {\n console.error(\n `Conflicting match conditions for field ${field}, the template will be ignored.`,\n commonValues\n );\n return [() => false];\n }\n }\n conditions.push(\n ProductTemplatesHelpers.fieldMustMatch(field, mustMatch[field])\n );\n }\n\n for (const field in mustNotMatch) {\n conditions.push(\n ProductTemplatesHelpers.fieldMustNotMatch(field, mustNotMatch[field])\n );\n }\n return conditions;\n}\n\nexport function makeDefinedConditions(\n ifDefined?: string,\n ifNotDefined?: string\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n if (ifDefined) {\n const fieldNames = ifDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));\n }\n\n if (ifNotDefined) {\n const fieldNames = ifNotDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));\n }\n return conditions;\n}\n","import {aggregate, isElementNode, isVisualNode} from '@/src/utils/utils';\nimport {\n ProductTemplate,\n ProductTemplateCondition,\n ProductTemplatesHelpers,\n} from '@coveo/headless/commerce';\nimport {h} from '@stencil/core';\nimport {tableElementTagName} from '../../search/atomic-table-result/table-element-utils';\nimport {ItemTarget} from '../layout/display-options';\nimport {isResultSectionNode} from '../layout/sections';\n\nexport {makeMatchConditions} from './product-template-common';\n\nexport type TemplateContent = DocumentFragment;\n\ninterface ProductTemplateCommonProps {\n allowEmpty?: boolean;\n host: HTMLDivElement;\n validParents: string[];\n setError: (error: Error) => void;\n}\n\ntype TemplateNodeType =\n | 'section'\n | 'metadata'\n | 'table-column-definition'\n | 'other';\n\nexport function getTemplateNodeType(node: Node): TemplateNodeType {\n if (isResultSectionNode(node)) {\n return 'section';\n }\n if (!isVisualNode(node)) {\n return 'metadata';\n }\n if (\n isElementNode(node) &&\n node.tagName.toLowerCase() === tableElementTagName\n ) {\n return 'table-column-definition';\n }\n return 'other';\n}\n\nfunction groupNodesByType(nodes: NodeList) {\n return aggregate(Array.from(nodes), (node) => getTemplateNodeType(node));\n}\n\n/**\n * @deprecated Use `ProductTemplateController` Reactive controller instead.\n */\nexport class ProductTemplateCommon {\n private host: HTMLDivElement;\n public matchConditions: ProductTemplateCondition[] = [];\n private gridCellLinkTarget?: ItemTarget;\n\n constructor({\n host,\n setError,\n validParents,\n allowEmpty = false,\n }: ProductTemplateCommonProps) {\n this.host = host;\n this.validateTemplate(host, setError, validParents, allowEmpty);\n }\n\n validateTemplate(\n host: HTMLDivElement,\n setError: (error: Error) => void,\n validParents: string[],\n allowEmpty = true\n ) {\n const hasValidParent = validParents\n .map((p) => p.toUpperCase())\n .includes(host.parentElement?.nodeName || '');\n const tagName = host.nodeName.toLowerCase();\n\n if (!hasValidParent) {\n setError(\n new Error(\n `The \"${tagName}\" component has to be the child of one of the following: ${validParents\n .map((p) => `\"${p.toLowerCase()}\"`)\n .join(', ')}.`\n )\n );\n return;\n }\n\n if (\n host.parentElement?.attributes.getNamedItem('display')?.value === 'grid'\n ) {\n this.gridCellLinkTarget = host.parentElement?.attributes.getNamedItem(\n 'grid-cell-link-target'\n )?.value as ItemTarget;\n }\n\n const template = host.querySelector('template');\n if (!template) {\n setError(\n new Error(\n `The \"${tagName}\" component must contain a \"template\" element as a child.`\n )\n );\n return;\n }\n\n if (!allowEmpty && !template.innerHTML.trim()) {\n setError(\n new Error(`The \"template\" tag inside \"${tagName}\" cannot be empty.`)\n );\n return;\n }\n\n if (template.content.querySelector('script')) {\n console.warn(\n 'Any \"script\" tags defined inside of \"template\" elements are not supported and will not be executed when the products are rendered.',\n host\n );\n }\n\n const {section: sectionNodes, other: otherNodes} = groupNodesByType(\n template.content.childNodes\n );\n if (sectionNodes?.length && otherNodes?.length) {\n console.warn(\n 'Product templates should only contain section elements or non-section elements. Future updates could unpredictably affect this product template.',\n host,\n {sectionNodes, otherNodes}\n );\n }\n }\n\n getTemplate(\n conditions: ProductTemplateCondition[],\n error: Error\n ): ProductTemplate<TemplateContent> | null {\n if (error) {\n return null;\n }\n\n return {\n conditions: conditions.concat(this.matchConditions),\n content: getTemplateElement(this.host).content!,\n linkContent: this.getLinkTemplateElement(this.host).content!,\n priority: 1,\n };\n }\n\n renderIfError(error: Error) {\n if (error) {\n return (\n <atomic-component-error\n element={this.host}\n error={error}\n ></atomic-component-error>\n );\n }\n }\n getDefaultLinkTemplateElement() {\n const linkTemplate = document.createElement('template');\n linkTemplate.innerHTML = `<atomic-product-link>${this.gridCellLinkTarget ? `<a slot=\"attributes\" target=\"${this.gridCellLinkTarget}\"></a>` : ''}</atomic-product-link>`;\n return linkTemplate;\n }\n\n getLinkTemplateElement(host: HTMLElement) {\n return (\n host.querySelector<HTMLTemplateElement>('template[slot=\"link\"]') ??\n this.getDefaultLinkTemplateElement()\n );\n }\n}\n\nfunction getTemplateElement(host: HTMLElement) {\n return host.querySelector<HTMLTemplateElement>('template:not([slot])')!;\n}\n\nexport function makeDefinedConditions(\n ifDefined?: string,\n ifNotDefined?: string\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n if (ifDefined) {\n const fieldNames = ifDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));\n }\n\n if (ifNotDefined) {\n const fieldNames = ifNotDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));\n }\n return conditions;\n}\n","import {Product, ProductTemplateCondition} from '@coveo/headless/commerce';\nimport {Component, Prop, h, Element} from '@stencil/core';\nimport {MapProp} from '../../../utils/props-utils';\nimport {\n makeDefinedConditions,\n makeMatchConditions,\n} from '../../common/product-template/stencil-product-template-common';\nimport {ProductContext} from '../product-template-component-utils/stencil-product-template-decorators';\n\n/**\n * The `atomic-product-field-condition` component takes a list of conditions that, if fulfilled, apply the template in which it's defined.\n * The condition properties can be based on any top-level product property of the `product` object, not restricted to fields (e.g., `ec_name`).\n * @alpha\n */\n@Component({\n tag: 'atomic-product-field-condition',\n shadow: false,\n})\nexport class AtomicProductFieldCondition {\n @Element() host!: HTMLElement;\n\n /**\n * Verifies whether the specified fields are defined.\n */\n @Prop({reflect: true}) ifDefined?: string;\n /**\n * Verifies whether the specified fields are not defined.\n */\n @Prop({reflect: true}) ifNotDefined?: string;\n\n /**\n * Verifies whether the specified fields match the specified values.\n * @type {Record<string, string[]>}\n */\n @Prop() @MapProp({splitValues: true}) mustMatch: Record<string, string[]> =\n {};\n\n /**\n * Verifies whether the specified fields do not match the specified values.\n * @type {Record<string, string[]>}\n */\n @Prop() @MapProp({splitValues: true}) mustNotMatch: Record<string, string[]> =\n {};\n\n private conditions: ProductTemplateCondition[] = [];\n private shouldBeRemoved = false;\n\n @ProductContext() private product!: Product;\n\n public componentWillLoad() {\n this.conditions = makeDefinedConditions(this.ifDefined, this.ifNotDefined);\n this.conditions.push(\n ...makeMatchConditions(this.mustMatch, this.mustNotMatch)\n );\n }\n\n public render() {\n if (!this.conditions.every((condition) => condition(this.product))) {\n this.shouldBeRemoved = true;\n return '';\n }\n\n return <slot />;\n }\n\n public componentDidLoad() {\n this.shouldBeRemoved && this.host.remove();\n }\n}\n"],"version":3}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { I as ItemContext, i as itemContext } from './stencil-item-decorators.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A [StencilJS property decorator](https://stenciljs.com/) to be used for product template components.
|
|
5
|
-
* This allows the Stencil component to fetch the current product from its rendered parent, the `atomic-product` component.
|
|
6
|
-
*
|
|
7
|
-
* Example:
|
|
8
|
-
* ```
|
|
9
|
-
* @ProductContext() private product!: Product;
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* For more information and examples, view the [Utilities section](https://github.com/coveo/ui-kit/tree/master/packages/atomic#utilities) of the Coveo Atomic README.
|
|
13
|
-
*
|
|
14
|
-
* @deprecated should only be used for Stencil components. For Lit components, use `createProductContextController` from \@/src/decorators/commerce/product-template-decorators.ts
|
|
15
|
-
*/
|
|
16
|
-
function ProductContext(opts = { folded: false }) {
|
|
17
|
-
return ItemContext({ parentName: 'atomic-product', folded: opts.folded });
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Retrieves `Product` on a rendered `atomic-product`.
|
|
21
|
-
*
|
|
22
|
-
* This method is useful for building custom product template elements, see [Create a Product List](https://docs.coveo.com/en/atomic/latest/cc-search/create-custom-components/native-components/#custom-product-template-component-example) for more information.
|
|
23
|
-
*
|
|
24
|
-
* 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).
|
|
25
|
-
*
|
|
26
|
-
* @param element - The element that the event is dispatched to, which must be the child of a rendered "atomic-product".
|
|
27
|
-
* @returns A promise that resolves on initialization of the parent "atomic-product" element, or rejects when there is no parent "atomic-product" element.
|
|
28
|
-
*
|
|
29
|
-
* @deprecated should only be used for Stencil components. For Lit components, use `fetchProductContext` from \@/src/decorators/commerce/product-template-decorators.ts
|
|
30
|
-
*/
|
|
31
|
-
function productContext(element) {
|
|
32
|
-
return itemContext(element, 'atomic-product');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { ProductContext as P, productContext as p };
|
|
36
|
-
|
|
37
|
-
//# sourceMappingURL=stencil-product-template-decorators.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"file":"stencil-product-template-decorators.js","mappings":";;AASA;;;;;;;;;;;;;SAagB,cAAc,CAAC,OAA0B,EAAC,MAAM,EAAE,KAAK,EAAC;IACtE,OAAO,WAAW,CAAC,EAAC,UAAU,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;AAC1E,CAAC;AASD;;;;;;;;;;;;SAYgB,cAAc,CAAoB,OAAgB;IAChE,OAAO,WAAW,CAAI,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACnD;;;;","names":[],"sources":["src/components/commerce/product-template-component-utils/stencil-product-template-decorators.tsx"],"sourcesContent":["import {Product} from '@coveo/headless/commerce';\nimport {\n InteractiveItemContext,\n InteractiveItemContextEvent,\n ItemContext,\n ItemContextEvent,\n itemContext,\n} from '../../common/item-list/stencil-item-decorators';\n\n/**\n * A [StencilJS property decorator](https://stenciljs.com/) to be used for product template components.\n * This allows the Stencil component to fetch the current product from its rendered parent, the `atomic-product` component.\n *\n * Example:\n * ```\n * @ProductContext() private product!: Product;\n * ```\n *\n * For more information and examples, view the [Utilities section](https://github.com/coveo/ui-kit/tree/master/packages/atomic#utilities) of the Coveo Atomic README.\n *\n * @deprecated should only be used for Stencil components. For Lit components, use `createProductContextController` from \\@/src/decorators/commerce/product-template-decorators.ts\n */\nexport function ProductContext(opts: {folded: boolean} = {folded: false}) {\n return ItemContext({parentName: 'atomic-product', folded: opts.folded});\n}\n\nexport function InteractiveProductContext() {\n return InteractiveItemContext();\n}\n\nexport type ProductContextEvent<T = Product> = ItemContextEvent<T>;\nexport type InteractiveProductContextEvent = InteractiveItemContextEvent;\n\n/**\n * Retrieves `Product` on a rendered `atomic-product`.\n *\n * This method is useful for building custom product template elements, see [Create a Product List](https://docs.coveo.com/en/atomic/latest/cc-search/create-custom-components/native-components/#custom-product-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-product\".\n * @returns A promise that resolves on initialization of the parent \"atomic-product\" element, or rejects when there is no parent \"atomic-product\" element.\n *\n * @deprecated should only be used for Stencil components. For Lit components, use `fetchProductContext` from \\@/src/decorators/commerce/product-template-decorators.ts\n */\nexport function productContext<T extends Product>(element: Element) {\n return itemContext<T>(element, 'atomic-product');\n}\n"],"version":3}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as t,h as o,g as i}from"./p-dc3df5ce.js";import{M as e}from"./p-86428057.js";import"./p-f284897c.js";import{ProductTemplatesHelpers as s}from"@coveo/headless/commerce";import{P as n}from"./p-fe23d27e.js";import"@coveo/bueno";import"./p-bc96b8f6.js";import"./p-0462f723.js";import"./p-3dc06261.js";import"./p-c9074946.js";import"./p-1580513b.js";function r(t,o){const i=new Set;for(const e of t){if(o.has(e)){i.add(e)}}return i}function c(t,o){const i=[];for(const e in t){if(o[e]){const i=new Set(o[e]);const s=new Set(t[e]);const n=r(i,s);if(n.size>0){console.error(`Conflicting match conditions for field ${e}, the template will be ignored.`,n);return[()=>false]}}i.push(s.fieldMustMatch(e,t[e]))}for(const t in o){i.push(s.fieldMustNotMatch(t,o[t]))}return i}function f(t,o){const i=[];if(t){const o=t.split(",");i.push(s.fieldsMustBeDefined(o))}if(o){const t=o.split(",");i.push(s.fieldsMustNotBeDefined(t))}return i}var p=undefined&&undefined.__decorate||function(t,o,i,e){var s=arguments.length,n=s<3?o:e===null?e=Object.getOwnPropertyDescriptor(o,i):e,r;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")n=Reflect.decorate(t,o,i,e);else for(var c=t.length-1;c>=0;c--)if(r=t[c])n=(s<3?r(n):s>3?r(o,i,n):r(o,i))||n;return s>3&&n&&Object.defineProperty(o,i,n),n};const u=class{constructor(o){t(this,o);this.mustMatch={};this.mustNotMatch={};this.conditions=[];this.shouldBeRemoved=false;this.ifDefined=undefined;this.ifNotDefined=undefined;this.mustMatch={};this.mustNotMatch={}}componentWillLoad(){this.conditions=f(this.ifDefined,this.ifNotDefined);this.conditions.push(...c(this.mustMatch,this.mustNotMatch))}render(){if(!this.conditions.every((t=>t(this.product)))){this.shouldBeRemoved=true;return""}return o("slot",null)}componentDidLoad(){this.shouldBeRemoved&&this.host.remove()}get host(){return i(this)}};p([e({splitValues:true})],u.prototype,"mustMatch",void 0);p([e({splitValues:true})],u.prototype,"mustNotMatch",void 0);p([n()],u.prototype,"product",void 0);export{u as atomic_product_field_condition};
|
|
2
|
-
//# sourceMappingURL=p-a0b3c6e2.entry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["intersection","setA","setB","result","Set","elem","has","add","makeMatchConditions","mustMatch","mustNotMatch","conditions","field","mustNotMatchValues","mustMatchValues","commonValues","size","console","error","push","ProductTemplatesHelpers","fieldMustMatch","fieldMustNotMatch","makeDefinedConditions","ifDefined","ifNotDefined","fieldNames","split","fieldsMustBeDefined","fieldsMustNotBeDefined","AtomicProductFieldCondition","this","shouldBeRemoved","componentWillLoad","render","every","condition","product","h","componentDidLoad","host","remove","__decorate","MapProp","splitValues","ProductContext"],"sources":["src/utils/set.ts","src/components/common/product-template/product-template-common.ts","src/components/common/product-template/stencil-product-template-common.tsx","src/components/commerce/atomic-product-field-condition/atomic-product-field-condition.tsx"],"sourcesContent":["// TODO: Replace by Set.prototype.intersection in July 2025\nexport function intersection<T>(setA: Set<T>, setB: Set<T>): Set<T> {\n const result = new Set<T>();\n for (const elem of setA) {\n if (setB.has(elem)) {\n result.add(elem);\n }\n }\n return result;\n}\n","import {\n type ProductTemplateCondition,\n ProductTemplatesHelpers,\n} from '@coveo/headless/commerce';\nimport {intersection} from '../../../utils/set';\nimport {isElementNode, isVisualNode} from '../../../utils/utils';\nimport {tableElementTagName} from '../../search/atomic-table-result/table-element-utils';\nimport {isResultSectionNode} from '../layout/sections';\n\ntype TemplateNodeType =\n | 'section'\n | 'metadata'\n | 'table-column-definition'\n | 'other';\n\nexport function getTemplateNodeType(node: Node): TemplateNodeType {\n if (isResultSectionNode(node)) {\n return 'section';\n }\n if (!isVisualNode(node)) {\n return 'metadata';\n }\n if (\n isElementNode(node) &&\n node.tagName.toLowerCase() === tableElementTagName\n ) {\n return 'table-column-definition';\n }\n return 'other';\n}\n\nexport function makeMatchConditions(\n mustMatch: Record<string, string[]>,\n mustNotMatch: Record<string, string[]>\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n for (const field in mustMatch) {\n if (mustNotMatch[field]) {\n const mustNotMatchValues = new Set(mustNotMatch[field]);\n const mustMatchValues = new Set(mustMatch[field]);\n const commonValues = intersection(mustNotMatchValues, mustMatchValues);\n if (commonValues.size > 0) {\n console.error(\n `Conflicting match conditions for field ${field}, the template will be ignored.`,\n commonValues\n );\n return [() => false];\n }\n }\n conditions.push(\n ProductTemplatesHelpers.fieldMustMatch(field, mustMatch[field])\n );\n }\n\n for (const field in mustNotMatch) {\n conditions.push(\n ProductTemplatesHelpers.fieldMustNotMatch(field, mustNotMatch[field])\n );\n }\n return conditions;\n}\n\nexport function makeDefinedConditions(\n ifDefined?: string,\n ifNotDefined?: string\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n if (ifDefined) {\n const fieldNames = ifDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));\n }\n\n if (ifNotDefined) {\n const fieldNames = ifNotDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));\n }\n return conditions;\n}\n","import {aggregate, isElementNode, isVisualNode} from '@/src/utils/utils';\nimport {\n ProductTemplate,\n ProductTemplateCondition,\n ProductTemplatesHelpers,\n} from '@coveo/headless/commerce';\nimport {h} from '@stencil/core';\nimport {tableElementTagName} from '../../search/atomic-table-result/table-element-utils';\nimport {ItemTarget} from '../layout/display-options';\nimport {isResultSectionNode} from '../layout/sections';\n\nexport {makeMatchConditions} from './product-template-common';\n\nexport type TemplateContent = DocumentFragment;\n\ninterface ProductTemplateCommonProps {\n allowEmpty?: boolean;\n host: HTMLDivElement;\n validParents: string[];\n setError: (error: Error) => void;\n}\n\ntype TemplateNodeType =\n | 'section'\n | 'metadata'\n | 'table-column-definition'\n | 'other';\n\nexport function getTemplateNodeType(node: Node): TemplateNodeType {\n if (isResultSectionNode(node)) {\n return 'section';\n }\n if (!isVisualNode(node)) {\n return 'metadata';\n }\n if (\n isElementNode(node) &&\n node.tagName.toLowerCase() === tableElementTagName\n ) {\n return 'table-column-definition';\n }\n return 'other';\n}\n\nfunction groupNodesByType(nodes: NodeList) {\n return aggregate(Array.from(nodes), (node) => getTemplateNodeType(node));\n}\n\n/**\n * @deprecated Use `ProductTemplateController` Reactive controller instead.\n */\nexport class ProductTemplateCommon {\n private host: HTMLDivElement;\n public matchConditions: ProductTemplateCondition[] = [];\n private gridCellLinkTarget?: ItemTarget;\n\n constructor({\n host,\n setError,\n validParents,\n allowEmpty = false,\n }: ProductTemplateCommonProps) {\n this.host = host;\n this.validateTemplate(host, setError, validParents, allowEmpty);\n }\n\n validateTemplate(\n host: HTMLDivElement,\n setError: (error: Error) => void,\n validParents: string[],\n allowEmpty = true\n ) {\n const hasValidParent = validParents\n .map((p) => p.toUpperCase())\n .includes(host.parentElement?.nodeName || '');\n const tagName = host.nodeName.toLowerCase();\n\n if (!hasValidParent) {\n setError(\n new Error(\n `The \"${tagName}\" component has to be the child of one of the following: ${validParents\n .map((p) => `\"${p.toLowerCase()}\"`)\n .join(', ')}.`\n )\n );\n return;\n }\n\n if (\n host.parentElement?.attributes.getNamedItem('display')?.value === 'grid'\n ) {\n this.gridCellLinkTarget = host.parentElement?.attributes.getNamedItem(\n 'grid-cell-link-target'\n )?.value as ItemTarget;\n }\n\n const template = host.querySelector('template');\n if (!template) {\n setError(\n new Error(\n `The \"${tagName}\" component must contain a \"template\" element as a child.`\n )\n );\n return;\n }\n\n if (!allowEmpty && !template.innerHTML.trim()) {\n setError(\n new Error(`The \"template\" tag inside \"${tagName}\" cannot be empty.`)\n );\n return;\n }\n\n if (template.content.querySelector('script')) {\n console.warn(\n 'Any \"script\" tags defined inside of \"template\" elements are not supported and will not be executed when the products are rendered.',\n host\n );\n }\n\n const {section: sectionNodes, other: otherNodes} = groupNodesByType(\n template.content.childNodes\n );\n if (sectionNodes?.length && otherNodes?.length) {\n console.warn(\n 'Product templates should only contain section elements or non-section elements. Future updates could unpredictably affect this product template.',\n host,\n {sectionNodes, otherNodes}\n );\n }\n }\n\n getTemplate(\n conditions: ProductTemplateCondition[],\n error: Error\n ): ProductTemplate<TemplateContent> | null {\n if (error) {\n return null;\n }\n\n return {\n conditions: conditions.concat(this.matchConditions),\n content: getTemplateElement(this.host).content!,\n linkContent: this.getLinkTemplateElement(this.host).content!,\n priority: 1,\n };\n }\n\n renderIfError(error: Error) {\n if (error) {\n return (\n <atomic-component-error\n element={this.host}\n error={error}\n ></atomic-component-error>\n );\n }\n }\n getDefaultLinkTemplateElement() {\n const linkTemplate = document.createElement('template');\n linkTemplate.innerHTML = `<atomic-product-link>${this.gridCellLinkTarget ? `<a slot=\"attributes\" target=\"${this.gridCellLinkTarget}\"></a>` : ''}</atomic-product-link>`;\n return linkTemplate;\n }\n\n getLinkTemplateElement(host: HTMLElement) {\n return (\n host.querySelector<HTMLTemplateElement>('template[slot=\"link\"]') ??\n this.getDefaultLinkTemplateElement()\n );\n }\n}\n\nfunction getTemplateElement(host: HTMLElement) {\n return host.querySelector<HTMLTemplateElement>('template:not([slot])')!;\n}\n\nexport function makeDefinedConditions(\n ifDefined?: string,\n ifNotDefined?: string\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n if (ifDefined) {\n const fieldNames = ifDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));\n }\n\n if (ifNotDefined) {\n const fieldNames = ifNotDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));\n }\n return conditions;\n}\n","import {Product, ProductTemplateCondition} from '@coveo/headless/commerce';\nimport {Component, Prop, h, Element} from '@stencil/core';\nimport {MapProp} from '../../../utils/props-utils';\nimport {\n makeDefinedConditions,\n makeMatchConditions,\n} from '../../common/product-template/stencil-product-template-common';\nimport {ProductContext} from '../product-template-component-utils/stencil-product-template-decorators';\n\n/**\n * The `atomic-product-field-condition` component takes a list of conditions that, if fulfilled, apply the template in which it's defined.\n * The condition properties can be based on any top-level product property of the `product` object, not restricted to fields (e.g., `ec_name`).\n * @alpha\n */\n@Component({\n tag: 'atomic-product-field-condition',\n shadow: false,\n})\nexport class AtomicProductFieldCondition {\n @Element() host!: HTMLElement;\n\n /**\n * Verifies whether the specified fields are defined.\n */\n @Prop({reflect: true}) ifDefined?: string;\n /**\n * Verifies whether the specified fields are not defined.\n */\n @Prop({reflect: true}) ifNotDefined?: string;\n\n /**\n * Verifies whether the specified fields match the specified values.\n * @type {Record<string, string[]>}\n */\n @Prop() @MapProp({splitValues: true}) mustMatch: Record<string, string[]> =\n {};\n\n /**\n * Verifies whether the specified fields do not match the specified values.\n * @type {Record<string, string[]>}\n */\n @Prop() @MapProp({splitValues: true}) mustNotMatch: Record<string, string[]> =\n {};\n\n private conditions: ProductTemplateCondition[] = [];\n private shouldBeRemoved = false;\n\n @ProductContext() private product!: Product;\n\n public componentWillLoad() {\n this.conditions = makeDefinedConditions(this.ifDefined, this.ifNotDefined);\n this.conditions.push(\n ...makeMatchConditions(this.mustMatch, this.mustNotMatch)\n );\n }\n\n public render() {\n if (!this.conditions.every((condition) => condition(this.product))) {\n this.shouldBeRemoved = true;\n return '';\n }\n\n return <slot />;\n }\n\n public componentDidLoad() {\n this.shouldBeRemoved && this.host.remove();\n }\n}\n"],"mappings":"2WACgBA,EAAgBC,EAAcC,GAC5C,MAAMC,EAAS,IAAIC,IACnB,IAAK,MAAMC,KAAQJ,EAAM,CACvB,GAAIC,EAAKI,IAAID,GAAO,CAClBF,EAAOI,IAAIF,E,EAGf,OAAOF,CACT,C,SCsBgBK,EACdC,EACAC,GAEA,MAAMC,EAAyC,GAC/C,IAAK,MAAMC,KAASH,EAAW,CAC7B,GAAIC,EAAaE,GAAQ,CACvB,MAAMC,EAAqB,IAAIT,IAAIM,EAAaE,IAChD,MAAME,EAAkB,IAAIV,IAAIK,EAAUG,IAC1C,MAAMG,EAAef,EAAaa,EAAoBC,GACtD,GAAIC,EAAaC,KAAO,EAAG,CACzBC,QAAQC,MACN,0CAA0CN,mCAC1CG,GAEF,MAAO,CAAC,IAAM,M,EAGlBJ,EAAWQ,KACTC,EAAwBC,eAAeT,EAAOH,EAAUG,I,CAI5D,IAAK,MAAMA,KAASF,EAAc,CAChCC,EAAWQ,KACTC,EAAwBE,kBAAkBV,EAAOF,EAAaE,I,CAGlE,OAAOD,CACT,C,SCoHgBY,EACdC,EACAC,GAEA,MAAMd,EAAyC,GAC/C,GAAIa,EAAW,CACb,MAAME,EAAaF,EAAUG,MAAM,KACnChB,EAAWQ,KAAKC,EAAwBQ,oBAAoBF,G,CAG9D,GAAID,EAAc,CAChB,MAAMC,EAAaD,EAAaE,MAAM,KACtChB,EAAWQ,KAAKC,EAAwBS,uBAAuBH,G,CAEjE,OAAOf,CACT,C,iXC7KamB,EAA2B,M,yBAgBAC,KAAAtB,UACpC,GAMoCsB,KAAArB,aACpC,GAEMqB,KAAApB,WAAyC,GACzCoB,KAAAC,gBAAkB,M,oEAVxB,G,kBAOA,E,CAOK,iBAAAC,GACLF,KAAKpB,WAAaY,EAAsBQ,KAAKP,UAAWO,KAAKN,cAC7DM,KAAKpB,WAAWQ,QACXX,EAAoBuB,KAAKtB,UAAWsB,KAAKrB,c,CAIzC,MAAAwB,GACL,IAAKH,KAAKpB,WAAWwB,OAAOC,GAAcA,EAAUL,KAAKM,WAAW,CAClEN,KAAKC,gBAAkB,KACvB,MAAO,E,CAGT,OAAOM,EAAA,Y,CAGF,gBAAAC,GACLR,KAAKC,iBAAmBD,KAAKS,KAAKC,Q,6BAhCEC,EAAA,CAA7BC,EAAQ,CAACC,YAAa,Q,gCAOOF,EAAA,CAA7BC,EAAQ,CAACC,YAAa,Q,mCAMLF,EAAA,CAAzBG,K","ignoreList":[]}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
const index = require('./index-757bc886.js');
|
|
6
|
-
const propsUtils = require('./props-utils-1e4ba1b0.js');
|
|
7
|
-
require('./purify-85b542e2.js');
|
|
8
|
-
const commerce = require('@coveo/headless/commerce');
|
|
9
|
-
const stencilProductTemplateDecorators = require('./stencil-product-template-decorators-1edee0eb.js');
|
|
10
|
-
require('@coveo/bueno');
|
|
11
|
-
require('./utils-7153ae6b.js');
|
|
12
|
-
require('./_commonjsHelpers-b3309d7b.js');
|
|
13
|
-
require('./stencil-item-decorators-43a96f33.js');
|
|
14
|
-
require('./dom-utils-d4790328.js');
|
|
15
|
-
require('./event-utils-9bfcf3c5.js');
|
|
16
|
-
|
|
17
|
-
// TODO: Replace by Set.prototype.intersection in July 2025
|
|
18
|
-
function intersection(setA, setB) {
|
|
19
|
-
const result = new Set();
|
|
20
|
-
for (const elem of setA) {
|
|
21
|
-
if (setB.has(elem)) {
|
|
22
|
-
result.add(elem);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return result;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function makeMatchConditions(mustMatch, mustNotMatch) {
|
|
29
|
-
const conditions = [];
|
|
30
|
-
for (const field in mustMatch) {
|
|
31
|
-
if (mustNotMatch[field]) {
|
|
32
|
-
const mustNotMatchValues = new Set(mustNotMatch[field]);
|
|
33
|
-
const mustMatchValues = new Set(mustMatch[field]);
|
|
34
|
-
const commonValues = intersection(mustNotMatchValues, mustMatchValues);
|
|
35
|
-
if (commonValues.size > 0) {
|
|
36
|
-
console.error(`Conflicting match conditions for field ${field}, the template will be ignored.`, commonValues);
|
|
37
|
-
return [() => false];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
conditions.push(commerce.ProductTemplatesHelpers.fieldMustMatch(field, mustMatch[field]));
|
|
41
|
-
}
|
|
42
|
-
for (const field in mustNotMatch) {
|
|
43
|
-
conditions.push(commerce.ProductTemplatesHelpers.fieldMustNotMatch(field, mustNotMatch[field]));
|
|
44
|
-
}
|
|
45
|
-
return conditions;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function makeDefinedConditions(ifDefined, ifNotDefined) {
|
|
49
|
-
const conditions = [];
|
|
50
|
-
if (ifDefined) {
|
|
51
|
-
const fieldNames = ifDefined.split(',');
|
|
52
|
-
conditions.push(commerce.ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));
|
|
53
|
-
}
|
|
54
|
-
if (ifNotDefined) {
|
|
55
|
-
const fieldNames = ifNotDefined.split(',');
|
|
56
|
-
conditions.push(commerce.ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));
|
|
57
|
-
}
|
|
58
|
-
return conditions;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
62
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
63
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
64
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
65
|
-
else
|
|
66
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
67
|
-
if (d = decorators[i])
|
|
68
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
69
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
70
|
-
};
|
|
71
|
-
const AtomicProductFieldCondition = class {
|
|
72
|
-
constructor(hostRef) {
|
|
73
|
-
index.registerInstance(this, hostRef);
|
|
74
|
-
/**
|
|
75
|
-
* Verifies whether the specified fields match the specified values.
|
|
76
|
-
* @type {Record<string, string[]>}
|
|
77
|
-
*/
|
|
78
|
-
this.mustMatch = {};
|
|
79
|
-
/**
|
|
80
|
-
* Verifies whether the specified fields do not match the specified values.
|
|
81
|
-
* @type {Record<string, string[]>}
|
|
82
|
-
*/
|
|
83
|
-
this.mustNotMatch = {};
|
|
84
|
-
this.conditions = [];
|
|
85
|
-
this.shouldBeRemoved = false;
|
|
86
|
-
this.ifDefined = undefined;
|
|
87
|
-
this.ifNotDefined = undefined;
|
|
88
|
-
this.mustMatch = {};
|
|
89
|
-
this.mustNotMatch = {};
|
|
90
|
-
}
|
|
91
|
-
componentWillLoad() {
|
|
92
|
-
this.conditions = makeDefinedConditions(this.ifDefined, this.ifNotDefined);
|
|
93
|
-
this.conditions.push(...makeMatchConditions(this.mustMatch, this.mustNotMatch));
|
|
94
|
-
}
|
|
95
|
-
render() {
|
|
96
|
-
if (!this.conditions.every((condition) => condition(this.product))) {
|
|
97
|
-
this.shouldBeRemoved = true;
|
|
98
|
-
return '';
|
|
99
|
-
}
|
|
100
|
-
return index.h("slot", null);
|
|
101
|
-
}
|
|
102
|
-
componentDidLoad() {
|
|
103
|
-
this.shouldBeRemoved && this.host.remove();
|
|
104
|
-
}
|
|
105
|
-
get host() { return index.getElement(this); }
|
|
106
|
-
};
|
|
107
|
-
__decorate([
|
|
108
|
-
propsUtils.MapProp({ splitValues: true })
|
|
109
|
-
], AtomicProductFieldCondition.prototype, "mustMatch", void 0);
|
|
110
|
-
__decorate([
|
|
111
|
-
propsUtils.MapProp({ splitValues: true })
|
|
112
|
-
], AtomicProductFieldCondition.prototype, "mustNotMatch", void 0);
|
|
113
|
-
__decorate([
|
|
114
|
-
stencilProductTemplateDecorators.ProductContext()
|
|
115
|
-
], AtomicProductFieldCondition.prototype, "product", void 0);
|
|
116
|
-
|
|
117
|
-
exports.atomic_product_field_condition = AtomicProductFieldCondition;
|
|
118
|
-
|
|
119
|
-
//# sourceMappingURL=atomic-product-field-condition.cjs.entry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"file":"atomic-product-field-condition.entry.cjs.js","mappings":"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","names":["ProductTemplatesHelpers","h","MapProp","ProductContext"],"sources":["src/utils/set.ts","src/components/common/product-template/product-template-common.ts","src/components/common/product-template/stencil-product-template-common.tsx","src/components/commerce/atomic-product-field-condition/atomic-product-field-condition.tsx"],"sourcesContent":["// TODO: Replace by Set.prototype.intersection in July 2025\nexport function intersection<T>(setA: Set<T>, setB: Set<T>): Set<T> {\n const result = new Set<T>();\n for (const elem of setA) {\n if (setB.has(elem)) {\n result.add(elem);\n }\n }\n return result;\n}\n","import {\n type ProductTemplateCondition,\n ProductTemplatesHelpers,\n} from '@coveo/headless/commerce';\nimport {intersection} from '../../../utils/set';\nimport {isElementNode, isVisualNode} from '../../../utils/utils';\nimport {tableElementTagName} from '../../search/atomic-table-result/table-element-utils';\nimport {isResultSectionNode} from '../layout/sections';\n\ntype TemplateNodeType =\n | 'section'\n | 'metadata'\n | 'table-column-definition'\n | 'other';\n\nexport function getTemplateNodeType(node: Node): TemplateNodeType {\n if (isResultSectionNode(node)) {\n return 'section';\n }\n if (!isVisualNode(node)) {\n return 'metadata';\n }\n if (\n isElementNode(node) &&\n node.tagName.toLowerCase() === tableElementTagName\n ) {\n return 'table-column-definition';\n }\n return 'other';\n}\n\nexport function makeMatchConditions(\n mustMatch: Record<string, string[]>,\n mustNotMatch: Record<string, string[]>\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n for (const field in mustMatch) {\n if (mustNotMatch[field]) {\n const mustNotMatchValues = new Set(mustNotMatch[field]);\n const mustMatchValues = new Set(mustMatch[field]);\n const commonValues = intersection(mustNotMatchValues, mustMatchValues);\n if (commonValues.size > 0) {\n console.error(\n `Conflicting match conditions for field ${field}, the template will be ignored.`,\n commonValues\n );\n return [() => false];\n }\n }\n conditions.push(\n ProductTemplatesHelpers.fieldMustMatch(field, mustMatch[field])\n );\n }\n\n for (const field in mustNotMatch) {\n conditions.push(\n ProductTemplatesHelpers.fieldMustNotMatch(field, mustNotMatch[field])\n );\n }\n return conditions;\n}\n\nexport function makeDefinedConditions(\n ifDefined?: string,\n ifNotDefined?: string\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n if (ifDefined) {\n const fieldNames = ifDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));\n }\n\n if (ifNotDefined) {\n const fieldNames = ifNotDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));\n }\n return conditions;\n}\n","import {aggregate, isElementNode, isVisualNode} from '@/src/utils/utils';\nimport {\n ProductTemplate,\n ProductTemplateCondition,\n ProductTemplatesHelpers,\n} from '@coveo/headless/commerce';\nimport {h} from '@stencil/core';\nimport {tableElementTagName} from '../../search/atomic-table-result/table-element-utils';\nimport {ItemTarget} from '../layout/display-options';\nimport {isResultSectionNode} from '../layout/sections';\n\nexport {makeMatchConditions} from './product-template-common';\n\nexport type TemplateContent = DocumentFragment;\n\ninterface ProductTemplateCommonProps {\n allowEmpty?: boolean;\n host: HTMLDivElement;\n validParents: string[];\n setError: (error: Error) => void;\n}\n\ntype TemplateNodeType =\n | 'section'\n | 'metadata'\n | 'table-column-definition'\n | 'other';\n\nexport function getTemplateNodeType(node: Node): TemplateNodeType {\n if (isResultSectionNode(node)) {\n return 'section';\n }\n if (!isVisualNode(node)) {\n return 'metadata';\n }\n if (\n isElementNode(node) &&\n node.tagName.toLowerCase() === tableElementTagName\n ) {\n return 'table-column-definition';\n }\n return 'other';\n}\n\nfunction groupNodesByType(nodes: NodeList) {\n return aggregate(Array.from(nodes), (node) => getTemplateNodeType(node));\n}\n\n/**\n * @deprecated Use `ProductTemplateController` Reactive controller instead.\n */\nexport class ProductTemplateCommon {\n private host: HTMLDivElement;\n public matchConditions: ProductTemplateCondition[] = [];\n private gridCellLinkTarget?: ItemTarget;\n\n constructor({\n host,\n setError,\n validParents,\n allowEmpty = false,\n }: ProductTemplateCommonProps) {\n this.host = host;\n this.validateTemplate(host, setError, validParents, allowEmpty);\n }\n\n validateTemplate(\n host: HTMLDivElement,\n setError: (error: Error) => void,\n validParents: string[],\n allowEmpty = true\n ) {\n const hasValidParent = validParents\n .map((p) => p.toUpperCase())\n .includes(host.parentElement?.nodeName || '');\n const tagName = host.nodeName.toLowerCase();\n\n if (!hasValidParent) {\n setError(\n new Error(\n `The \"${tagName}\" component has to be the child of one of the following: ${validParents\n .map((p) => `\"${p.toLowerCase()}\"`)\n .join(', ')}.`\n )\n );\n return;\n }\n\n if (\n host.parentElement?.attributes.getNamedItem('display')?.value === 'grid'\n ) {\n this.gridCellLinkTarget = host.parentElement?.attributes.getNamedItem(\n 'grid-cell-link-target'\n )?.value as ItemTarget;\n }\n\n const template = host.querySelector('template');\n if (!template) {\n setError(\n new Error(\n `The \"${tagName}\" component must contain a \"template\" element as a child.`\n )\n );\n return;\n }\n\n if (!allowEmpty && !template.innerHTML.trim()) {\n setError(\n new Error(`The \"template\" tag inside \"${tagName}\" cannot be empty.`)\n );\n return;\n }\n\n if (template.content.querySelector('script')) {\n console.warn(\n 'Any \"script\" tags defined inside of \"template\" elements are not supported and will not be executed when the products are rendered.',\n host\n );\n }\n\n const {section: sectionNodes, other: otherNodes} = groupNodesByType(\n template.content.childNodes\n );\n if (sectionNodes?.length && otherNodes?.length) {\n console.warn(\n 'Product templates should only contain section elements or non-section elements. Future updates could unpredictably affect this product template.',\n host,\n {sectionNodes, otherNodes}\n );\n }\n }\n\n getTemplate(\n conditions: ProductTemplateCondition[],\n error: Error\n ): ProductTemplate<TemplateContent> | null {\n if (error) {\n return null;\n }\n\n return {\n conditions: conditions.concat(this.matchConditions),\n content: getTemplateElement(this.host).content!,\n linkContent: this.getLinkTemplateElement(this.host).content!,\n priority: 1,\n };\n }\n\n renderIfError(error: Error) {\n if (error) {\n return (\n <atomic-component-error\n element={this.host}\n error={error}\n ></atomic-component-error>\n );\n }\n }\n getDefaultLinkTemplateElement() {\n const linkTemplate = document.createElement('template');\n linkTemplate.innerHTML = `<atomic-product-link>${this.gridCellLinkTarget ? `<a slot=\"attributes\" target=\"${this.gridCellLinkTarget}\"></a>` : ''}</atomic-product-link>`;\n return linkTemplate;\n }\n\n getLinkTemplateElement(host: HTMLElement) {\n return (\n host.querySelector<HTMLTemplateElement>('template[slot=\"link\"]') ??\n this.getDefaultLinkTemplateElement()\n );\n }\n}\n\nfunction getTemplateElement(host: HTMLElement) {\n return host.querySelector<HTMLTemplateElement>('template:not([slot])')!;\n}\n\nexport function makeDefinedConditions(\n ifDefined?: string,\n ifNotDefined?: string\n): ProductTemplateCondition[] {\n const conditions: ProductTemplateCondition[] = [];\n if (ifDefined) {\n const fieldNames = ifDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustBeDefined(fieldNames));\n }\n\n if (ifNotDefined) {\n const fieldNames = ifNotDefined.split(',');\n conditions.push(ProductTemplatesHelpers.fieldsMustNotBeDefined(fieldNames));\n }\n return conditions;\n}\n","import {Product, ProductTemplateCondition} from '@coveo/headless/commerce';\nimport {Component, Prop, h, Element} from '@stencil/core';\nimport {MapProp} from '../../../utils/props-utils';\nimport {\n makeDefinedConditions,\n makeMatchConditions,\n} from '../../common/product-template/stencil-product-template-common';\nimport {ProductContext} from '../product-template-component-utils/stencil-product-template-decorators';\n\n/**\n * The `atomic-product-field-condition` component takes a list of conditions that, if fulfilled, apply the template in which it's defined.\n * The condition properties can be based on any top-level product property of the `product` object, not restricted to fields (e.g., `ec_name`).\n * @alpha\n */\n@Component({\n tag: 'atomic-product-field-condition',\n shadow: false,\n})\nexport class AtomicProductFieldCondition {\n @Element() host!: HTMLElement;\n\n /**\n * Verifies whether the specified fields are defined.\n */\n @Prop({reflect: true}) ifDefined?: string;\n /**\n * Verifies whether the specified fields are not defined.\n */\n @Prop({reflect: true}) ifNotDefined?: string;\n\n /**\n * Verifies whether the specified fields match the specified values.\n * @type {Record<string, string[]>}\n */\n @Prop() @MapProp({splitValues: true}) mustMatch: Record<string, string[]> =\n {};\n\n /**\n * Verifies whether the specified fields do not match the specified values.\n * @type {Record<string, string[]>}\n */\n @Prop() @MapProp({splitValues: true}) mustNotMatch: Record<string, string[]> =\n {};\n\n private conditions: ProductTemplateCondition[] = [];\n private shouldBeRemoved = false;\n\n @ProductContext() private product!: Product;\n\n public componentWillLoad() {\n this.conditions = makeDefinedConditions(this.ifDefined, this.ifNotDefined);\n this.conditions.push(\n ...makeMatchConditions(this.mustMatch, this.mustNotMatch)\n );\n }\n\n public render() {\n if (!this.conditions.every((condition) => condition(this.product))) {\n this.shouldBeRemoved = true;\n return '';\n }\n\n return <slot />;\n }\n\n public componentDidLoad() {\n this.shouldBeRemoved && this.host.remove();\n }\n}\n"],"version":3}
|