@coveo/atomic 3.31.2-pre.8be4e70346 → 3.31.2-pre.8c3f1d1fa1

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.
Files changed (119) hide show
  1. package/dist/atomic/_atomic.esm.js +1 -1
  2. package/dist/atomic/atomic.esm.js.map +1 -1
  3. package/dist/atomic/components/_index.d.ts +0 -2
  4. package/dist/atomic/components/_index.js +0 -1
  5. package/dist/atomic/components/analytics-config.js +1 -1
  6. package/dist/atomic/components/components/commerce/atomic-commerce-interface/analytics-config.js +2 -0
  7. package/dist/atomic/components/components/commerce/atomic-commerce-interface/atomic-commerce-interface.js +21 -27
  8. package/dist/atomic/components/components/commerce/atomic-commerce-recommendation-interface/atomic-commerce-recommendation-interface.js +22 -36
  9. package/dist/atomic/components/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.js +3 -0
  10. package/dist/atomic/components/components/commerce/atomic-product-description/atomic-product-description.js +149 -0
  11. package/dist/atomic/components/components/commerce/atomic-product-description/atomic-product-description.tw.css.js +3 -0
  12. package/dist/atomic/components/components/commerce/atomic-product-template/atomic-product-template.js +1 -0
  13. package/dist/atomic/components/components/commerce/index.js +1 -0
  14. package/dist/atomic/components/components/commerce/lazy-index.js +1 -0
  15. package/dist/atomic/components/components/common/interface/analytics-config.js +38 -0
  16. package/dist/atomic/components/components/common/interface/interface-controller.js +89 -0
  17. package/dist/atomic/components/global/environment.js +1 -1
  18. package/dist/atomic/components/index.js.map +1 -1
  19. package/dist/atomic/components/stencil-facet-show-more-less.js +7 -1
  20. package/dist/atomic/components/stencil-facet-show-more-less.js.map +1 -1
  21. package/dist/atomic/p-1e0f2e91.entry.js +2 -0
  22. package/dist/atomic/{p-8bb323e8.entry.js.map → p-1e0f2e91.entry.js.map} +1 -1
  23. package/dist/atomic/p-29c272bb.entry.js +2 -0
  24. package/dist/atomic/{p-4e77fe24.entry.js.map → p-29c272bb.entry.js.map} +1 -1
  25. package/dist/atomic/{p-1d3750da.entry.js → p-2bcb51de.entry.js} +2 -2
  26. package/dist/atomic/p-417b1b64.js +2 -0
  27. package/dist/atomic/{p-c100197d.js.map → p-417b1b64.js.map} +1 -1
  28. package/dist/atomic/p-44a3c052.entry.js +2 -0
  29. package/dist/atomic/{p-e215ba76.entry.js.map → p-44a3c052.entry.js.map} +1 -1
  30. package/dist/atomic/p-91477908.entry.js +2 -0
  31. package/dist/atomic/{p-3f881919.entry.js.map → p-91477908.entry.js.map} +1 -1
  32. package/dist/atomic/{p-9d8a346d.entry.js → p-afd64c6b.entry.js} +2 -2
  33. package/dist/atomic/{p-031c75d8.entry.js → p-b5ba5b33.entry.js} +2 -2
  34. package/dist/atomic/{p-8a3cd647.js → p-e235380a.js} +2 -2
  35. package/dist/atomic/p-e8ba8acd.entry.js +2 -0
  36. package/dist/atomic/{p-0873c1b8.entry.js.map → p-e8ba8acd.entry.js.map} +1 -1
  37. package/dist/cjs/_loader.cjs.js +1 -1
  38. package/dist/cjs/{analytics-config-e0753630.js → analytics-config-dd7bf210.js} +2 -2
  39. package/dist/cjs/{analytics-config-e0753630.js.map → analytics-config-dd7bf210.js.map} +1 -1
  40. package/dist/cjs/atomic-category-facet.cjs.entry.js +1 -2
  41. package/dist/cjs/atomic-category-facet.cjs.entry.js.map +1 -1
  42. package/dist/cjs/atomic-color-facet.cjs.entry.js +1 -2
  43. package/dist/cjs/atomic-color-facet.cjs.entry.js.map +1 -1
  44. package/dist/cjs/atomic-commerce-category-facet_4.cjs.entry.js +1 -2
  45. package/dist/cjs/atomic-commerce-category-facet_4.cjs.entry.js.map +1 -1
  46. package/dist/cjs/atomic-facet.cjs.entry.js +1 -2
  47. package/dist/cjs/atomic-facet.cjs.entry.js.map +1 -1
  48. package/dist/cjs/atomic-insight-facet.cjs.entry.js +1 -2
  49. package/dist/cjs/atomic-insight-facet.cjs.entry.js.map +1 -1
  50. package/dist/cjs/atomic-insight-interface.cjs.entry.js +1 -1
  51. package/dist/cjs/atomic-recs-interface.cjs.entry.js +1 -1
  52. package/dist/cjs/atomic-search-interface.cjs.entry.js +1 -1
  53. package/dist/cjs/atomic.cjs.js +1 -1
  54. package/dist/cjs/index-757bc886.js +0 -4
  55. package/dist/cjs/{stencil-facet-show-more-less-21d22973.js → stencil-facet-show-more-less-541e1544.js} +10 -4
  56. package/dist/cjs/stencil-facet-show-more-less-541e1544.js.map +1 -0
  57. package/dist/cjs/version.cjs.js +2 -2
  58. package/dist/esm/_loader.js +1 -1
  59. package/dist/esm/{analytics-config-7239091b.js → analytics-config-caa1011f.js} +2 -2
  60. package/dist/esm/{analytics-config-7239091b.js.map → analytics-config-caa1011f.js.map} +1 -1
  61. package/dist/esm/atomic-category-facet.entry.js +1 -2
  62. package/dist/esm/atomic-category-facet.entry.js.map +1 -1
  63. package/dist/esm/atomic-color-facet.entry.js +1 -2
  64. package/dist/esm/atomic-color-facet.entry.js.map +1 -1
  65. package/dist/esm/atomic-commerce-category-facet_4.entry.js +1 -2
  66. package/dist/esm/atomic-commerce-category-facet_4.entry.js.map +1 -1
  67. package/dist/esm/atomic-facet.entry.js +1 -2
  68. package/dist/esm/atomic-facet.entry.js.map +1 -1
  69. package/dist/esm/atomic-insight-facet.entry.js +1 -2
  70. package/dist/esm/atomic-insight-facet.entry.js.map +1 -1
  71. package/dist/esm/atomic-insight-interface.entry.js +1 -1
  72. package/dist/esm/atomic-recs-interface.entry.js +1 -1
  73. package/dist/esm/atomic-search-interface.entry.js +1 -1
  74. package/dist/esm/atomic.js +1 -1
  75. package/dist/esm/index-3f35faca.js +0 -4
  76. package/dist/esm/{stencil-facet-show-more-less-4b023ee3.js → stencil-facet-show-more-less-1198472f.js} +8 -2
  77. package/dist/esm/stencil-facet-show-more-less-1198472f.js.map +1 -0
  78. package/dist/esm/version.js +2 -2
  79. package/dist/types/components/commerce/atomic-commerce-interface/atomic-commerce-interface.d.ts +3 -4
  80. package/dist/types/components/commerce/atomic-commerce-recommendation-interface/atomic-commerce-recommendation-interface.d.ts +5 -6
  81. package/dist/types/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.d.ts +3 -0
  82. package/dist/types/components/commerce/atomic-product-description/atomic-product-description.d.ts +21 -10
  83. package/dist/types/components/commerce/atomic-product-template/atomic-product-template.d.ts +1 -0
  84. package/dist/types/components/commerce/index.d.ts +1 -0
  85. package/dist/types/components/common/interface/i18n.d.ts +1 -1
  86. package/dist/types/components/common/interface/{interface-common.d.ts → interface-controller.d.ts} +14 -11
  87. package/dist/types/components.d.ts +0 -51
  88. package/docs/atomic-docs.json +31 -154
  89. package/package.json +3 -3
  90. package/dist/atomic/components/atomic-product-description.d.ts +0 -11
  91. package/dist/atomic/components/atomic-product-description.js +0 -153
  92. package/dist/atomic/components/atomic-product-description.js.map +0 -1
  93. package/dist/atomic/components/components/common/interface/interface-common.js +0 -95
  94. package/dist/atomic/components/plus.js +0 -10
  95. package/dist/atomic/components/plus.js.map +0 -1
  96. package/dist/atomic/p-0873c1b8.entry.js +0 -2
  97. package/dist/atomic/p-3f881919.entry.js +0 -2
  98. package/dist/atomic/p-4e77fe24.entry.js +0 -2
  99. package/dist/atomic/p-8bb323e8.entry.js +0 -2
  100. package/dist/atomic/p-8f20d930.js +0 -2
  101. package/dist/atomic/p-8f20d930.js.map +0 -1
  102. package/dist/atomic/p-c100197d.js +0 -2
  103. package/dist/atomic/p-e215ba76.entry.js +0 -2
  104. package/dist/atomic/p-f2d31b97.entry.js +0 -2
  105. package/dist/atomic/p-f2d31b97.entry.js.map +0 -1
  106. package/dist/cjs/atomic-product-description.cjs.entry.js +0 -141
  107. package/dist/cjs/atomic-product-description.cjs.entry.js.map +0 -1
  108. package/dist/cjs/plus-07843914.js +0 -13
  109. package/dist/cjs/plus-07843914.js.map +0 -1
  110. package/dist/cjs/stencil-facet-show-more-less-21d22973.js.map +0 -1
  111. package/dist/esm/atomic-product-description.entry.js +0 -137
  112. package/dist/esm/atomic-product-description.entry.js.map +0 -1
  113. package/dist/esm/plus-00840ff6.js +0 -10
  114. package/dist/esm/plus-00840ff6.js.map +0 -1
  115. package/dist/esm/stencil-facet-show-more-less-4b023ee3.js.map +0 -1
  116. /package/dist/atomic/{p-1d3750da.entry.js.map → p-2bcb51de.entry.js.map} +0 -0
  117. /package/dist/atomic/{p-9d8a346d.entry.js.map → p-afd64c6b.entry.js.map} +0 -0
  118. /package/dist/atomic/{p-031c75d8.entry.js.map → p-b5ba5b33.entry.js.map} +0 -0
  119. /package/dist/atomic/{p-8a3cd647.js.map → p-e235380a.js.map} +0 -0
@@ -4,16 +4,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { buildContext, loadContextActions, } from '@coveo/headless/commerce';
7
+ import { buildContext, loadConfigurationActions, loadContextActions, } from '@coveo/headless/commerce';
8
8
  import { provide } from '@lit/context';
9
9
  import i18next from 'i18next';
10
10
  import { html, LitElement, unsafeCSS } from 'lit';
11
11
  import { customElement, property, state } from 'lit/decorators.js';
12
+ import { booleanConverter } from "../../../converters/boolean-converter.js";
13
+ import { errorGuard } from "../../../decorators/error-guard.js";
12
14
  import { watch } from "../../../decorators/watch";
13
15
  import { withTailwindStyles } from "../../../decorators/with-tailwind-styles.js";
14
16
  import { ChildrenUpdateCompleteMixin } from "../../../mixins/children-update-complete-mixin.js";
15
17
  import { markParentAsReady } from "../../../utils/init-queue";
16
- import { CommonAtomicInterfaceHelper, } from '../../common/interface/interface-common.js';
18
+ import { augmentAnalyticsConfigWithAtomicVersion } from '../../common/interface/analytics-config.js';
19
+ import { InterfaceController, } from '../../common/interface/interface-controller.js';
17
20
  import { bindingsContext } from '../../context/bindings-context.js';
18
21
  import styles from './atomic-commerce-recommendation-interface.tw.css';
19
22
  import { createCommerceRecommendationStore, } from './store.js';
@@ -27,6 +30,7 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
27
30
  constructor() {
28
31
  super();
29
32
  this.bindings = {};
33
+ this.interfaceController = new InterfaceController(this, 'CoveoAtomic');
30
34
  /**
31
35
  * The CSS selector for the container the interface will scroll back to.
32
36
  */
@@ -50,9 +54,8 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
50
54
  */
51
55
  this.analytics = true;
52
56
  this.handleInitialization = (event) => {
53
- this.commonInterfaceHelper.onComponentInitializing(event);
57
+ this.interfaceController.onComponentInitializing(event);
54
58
  };
55
- this.commonInterfaceHelper = new CommonAtomicInterfaceHelper(this, 'CoveoAtomic');
56
59
  this.store = createCommerceRecommendationStore();
57
60
  const { promise, resolve } = Promise.withResolvers();
58
61
  this.i18Initialized = promise;
@@ -67,6 +70,10 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
67
70
  * Initializes the connection with an already preconfigured [headless commerce engine](https://docs.coveo.com/en/headless/latest/reference/commerce/).
68
71
  */
69
72
  initializeWithEngine(engine) {
73
+ engine.dispatch(loadConfigurationActions(engine).updateAnalyticsConfiguration({
74
+ trackingId: engine.configuration.analytics.trackingId,
75
+ ...augmentAnalyticsConfigWithAtomicVersion(),
76
+ }));
70
77
  return this.internalInitialization(() => {
71
78
  this.engine = engine;
72
79
  });
@@ -91,11 +98,11 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
91
98
  * ```
92
99
  */
93
100
  updateLocale(language, country, currency) {
94
- if (!this.commonInterfaceHelper.engineIsCreated(this.engine) ||
101
+ if (!this.interfaceController.engineIsCreated(this.engine) ||
95
102
  !this.context) {
96
103
  return;
97
104
  }
98
- language && this.commonInterfaceHelper.onLanguageChange(language);
105
+ language && this.interfaceController.onLanguageChange(language);
99
106
  const { setContext } = loadContextActions(this.engine);
100
107
  this.engine.dispatch(setContext({
101
108
  ...this.context.state,
@@ -105,29 +112,25 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
105
112
  }));
106
113
  }
107
114
  toggleAnalytics() {
108
- this.commonInterfaceHelper.onAnalyticsChange();
115
+ this.interfaceController.onAnalyticsChange();
109
116
  }
110
117
  updateIconAssetsPath() {
111
118
  this.store.state.iconAssetsPath = this.iconAssetsPath;
112
119
  }
113
120
  async updateLanguage() {
114
- if (!this.commonInterfaceHelper.engineIsCreated(this.engine) ||
121
+ if (!this.interfaceController.engineIsCreated(this.engine) ||
115
122
  !this.language ||
116
123
  !this.context) {
117
124
  return;
118
125
  }
119
126
  this.engine.logger.warn('The `language` property will be removed in the next major version of Atomic (v4). Rather than using this property, set the initial language through the engine configuration when calling `initializeWithEngine`, and update the language as needed using the `updateLocale` method.');
120
127
  this.context.setLanguage(this.language);
121
- return this.commonInterfaceHelper.onLanguageChange();
128
+ return this.interfaceController.onLanguageChange();
122
129
  }
123
130
  disconnectedCallback() {
124
131
  super.disconnectedCallback();
125
132
  this.removeEventListener('atomic/initializeComponent', this.handleInitialization);
126
133
  this.removeEventListener('atomic/scrollToTop', this.scrollToTop);
127
- const ariaLive = this.querySelector('atomic-aria-live');
128
- if (ariaLive) {
129
- ariaLive.remove();
130
- }
131
134
  }
132
135
  render() {
133
136
  return html `<slot></slot>`;
@@ -142,23 +145,15 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
142
145
  }
143
146
  async internalInitialization(initEngine) {
144
147
  await Promise.all([
145
- this.commonInterfaceHelper.onInitialization(initEngine),
148
+ this.interfaceController.onInitialization(initEngine),
146
149
  this.i18Initialized,
147
150
  ]);
148
- this.initAriaLive();
149
151
  this.initContext();
150
152
  this.language && this.updateLanguage();
151
153
  this.bindings = this.getBindings();
152
154
  markParentAsReady(this);
153
155
  this.initLanguage();
154
156
  }
155
- initAriaLive() {
156
- if (Array.from(this.children).some((element) => element.tagName === 'ATOMIC-ARIA-LIVE')) {
157
- return;
158
- }
159
- const ariaLive = document.createElement('atomic-aria-live');
160
- this.prepend(ariaLive);
161
- }
162
157
  initContext() {
163
158
  this.context = buildContext(this.engine);
164
159
  }
@@ -168,21 +163,11 @@ let AtomicCommerceRecommendationInterface = class AtomicCommerceRecommendationIn
168
163
  i18n: this.i18n,
169
164
  store: this.store,
170
165
  interfaceElement: this,
171
- addAdoptedStyleSheets: (stylesheet) => {
172
- const parent = this.getRootNode();
173
- const styleSheet = stylesheet;
174
- const isDocumentOrShadowRoot = parent instanceof Document || parent instanceof ShadowRoot;
175
- if (styleSheet &&
176
- isDocumentOrShadowRoot &&
177
- !parent.adoptedStyleSheets.includes(styleSheet)) {
178
- parent.adoptedStyleSheets.push(styleSheet);
179
- }
180
- },
181
166
  };
182
167
  }
183
168
  initLanguage() {
184
169
  if (!this.language) {
185
- this.commonInterfaceHelper.onLanguageChange(this.context.state.language);
170
+ this.interfaceController.onLanguageChange(this.context.state.language);
186
171
  }
187
172
  }
188
173
  };
@@ -215,9 +200,7 @@ __decorate([
215
200
  __decorate([
216
201
  property({
217
202
  type: Boolean,
218
- converter: {
219
- fromAttribute: (value) => value !== 'false',
220
- },
203
+ converter: booleanConverter,
221
204
  reflect: true,
222
205
  })
223
206
  ], AtomicCommerceRecommendationInterface.prototype, "analytics", void 0);
@@ -230,6 +213,9 @@ __decorate([
230
213
  __decorate([
231
214
  watch('language')
232
215
  ], AtomicCommerceRecommendationInterface.prototype, "updateLanguage", null);
216
+ __decorate([
217
+ errorGuard()
218
+ ], AtomicCommerceRecommendationInterface.prototype, "render", null);
233
219
  AtomicCommerceRecommendationInterface = __decorate([
234
220
  customElement('atomic-commerce-recommendation-interface'),
235
221
  withTailwindStyles
@@ -27,6 +27,9 @@ import { renderSubmitButton } from '../../common/search-box/submit-button';
27
27
  import { SuggestionManager } from '../../common/suggestions/suggestion-manager';
28
28
  import { elementHasQuery, } from '../../common/suggestions/suggestions-common';
29
29
  import styles from './atomic-commerce-search-box.tw.css';
30
+ import '../atomic-commerce-search-box-instant-products/atomic-commerce-search-box-instant-products';
31
+ import '../atomic-commerce-search-box-query-suggestions/atomic-commerce-search-box-query-suggestions';
32
+ import '../atomic-commerce-search-box-recent-queries/atomic-commerce-search-box-recent-queries';
30
33
  /**
31
34
  * The `atomic-commerce-search-box` component enables users to perform product searches with built-in query suggestions and optional redirection to a search results page.
32
35
  *
@@ -0,0 +1,149 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Schema, StringValue } from '@coveo/bueno';
8
+ import { html, LitElement, nothing, unsafeCSS } from 'lit';
9
+ import { customElement, property, state } from 'lit/decorators.js';
10
+ import { createRef } from 'lit/directives/ref.js';
11
+ import { booleanConverter } from "../../../converters/boolean-converter.js";
12
+ import { bindingGuard } from "../../../decorators/binding-guard.js";
13
+ import { bindings } from "../../../decorators/bindings.js";
14
+ import { createProductContextController } from "../../../decorators/commerce/product-template-decorators.js";
15
+ import { errorGuard } from "../../../decorators/error-guard.js";
16
+ import { injectStylesForNoShadowDOM } from "../../../decorators/inject-styles-for-no-shadow-dom.js";
17
+ import { withTailwindStyles } from "../../../decorators/with-tailwind-styles.js";
18
+ import { renderExpandableText, } from '../../common/expandable-text/expandable-text.js';
19
+ import styles from './atomic-product-description.tw.css';
20
+ import '../atomic-product-text/atomic-product-text.js';
21
+ /**
22
+ * The `atomic-product-description` component renders the description of a product.
23
+ *
24
+ * @part expandable-text - The part that contains the product description text.
25
+ */
26
+ let AtomicProductDescription = class AtomicProductDescription extends LitElement {
27
+ initialize() { }
28
+ constructor() {
29
+ super();
30
+ this.productController = createProductContextController(this);
31
+ this.isExpanded = false;
32
+ this.isTruncated = false;
33
+ this.descriptionRef = createRef();
34
+ /**
35
+ * The number of lines after which the product description should be truncated. A value of "none" will disable truncation.
36
+ */
37
+ this.truncateAfter = '2';
38
+ /**
39
+ * The name of the description field to use.
40
+ */
41
+ this.field = 'ec_shortdesc';
42
+ /**
43
+ * Whether the description should be collapsible after being expanded.
44
+ */
45
+ this.isCollapsible = true;
46
+ this.onToggleExpand = (e) => {
47
+ if (e) {
48
+ e.stopPropagation();
49
+ }
50
+ this.isExpanded = !this.isExpanded;
51
+ };
52
+ this.resizeObserver = new ResizeObserver(() => {
53
+ if (this.descriptionRef.value) {
54
+ this.isTruncated =
55
+ this.descriptionRef.value.scrollHeight >
56
+ this.descriptionRef.value.clientHeight;
57
+ }
58
+ });
59
+ }
60
+ validateProps() {
61
+ new Schema({
62
+ truncateAfter: new StringValue({
63
+ constrainTo: ['none', '1', '2', '3', '4'],
64
+ }),
65
+ field: new StringValue({
66
+ constrainTo: ['ec_shortdesc', 'ec_description'],
67
+ }),
68
+ }).validate({
69
+ truncateAfter: this.truncateAfter,
70
+ field: this.field,
71
+ });
72
+ }
73
+ updated(changedProperties) {
74
+ super.updated(changedProperties);
75
+ if (changedProperties.has('truncateAfter') ||
76
+ changedProperties.has('field')) {
77
+ this.validateProps();
78
+ }
79
+ }
80
+ firstUpdated() {
81
+ if (this.descriptionRef.value) {
82
+ this.resizeObserver.observe(this.descriptionRef.value);
83
+ }
84
+ }
85
+ disconnectedCallback() {
86
+ super.disconnectedCallback();
87
+ this.resizeObserver.disconnect();
88
+ }
89
+ get product() {
90
+ return this.productController.item;
91
+ }
92
+ render() {
93
+ const productDescription = this.product?.[this.field] ?? null;
94
+ if (!productDescription) {
95
+ return html `${nothing}`;
96
+ }
97
+ return html `${renderExpandableText({
98
+ props: {
99
+ isExpanded: this.isExpanded,
100
+ isTruncated: this.isTruncated,
101
+ truncateAfter: this.truncateAfter,
102
+ onToggleExpand: this.onToggleExpand,
103
+ showMoreLabel: this.bindings.i18n.t('show-more'),
104
+ showLessLabel: this.bindings.i18n.t('show-less'),
105
+ isCollapsible: this.isCollapsible,
106
+ textRef: this.descriptionRef,
107
+ },
108
+ })(html `
109
+ <atomic-product-text field=${this.field}></atomic-product-text>
110
+ `)}`;
111
+ }
112
+ };
113
+ AtomicProductDescription.styles = unsafeCSS(styles);
114
+ __decorate([
115
+ state()
116
+ ], AtomicProductDescription.prototype, "bindings", void 0);
117
+ __decorate([
118
+ state()
119
+ ], AtomicProductDescription.prototype, "isExpanded", void 0);
120
+ __decorate([
121
+ state()
122
+ ], AtomicProductDescription.prototype, "isTruncated", void 0);
123
+ __decorate([
124
+ property({
125
+ type: String,
126
+ attribute: 'truncate-after',
127
+ })
128
+ ], AtomicProductDescription.prototype, "truncateAfter", void 0);
129
+ __decorate([
130
+ property()
131
+ ], AtomicProductDescription.prototype, "field", void 0);
132
+ __decorate([
133
+ property({
134
+ type: Boolean,
135
+ converter: booleanConverter,
136
+ attribute: 'is-collapsible',
137
+ })
138
+ ], AtomicProductDescription.prototype, "isCollapsible", void 0);
139
+ __decorate([
140
+ errorGuard(),
141
+ bindingGuard()
142
+ ], AtomicProductDescription.prototype, "render", null);
143
+ AtomicProductDescription = __decorate([
144
+ customElement('atomic-product-description'),
145
+ withTailwindStyles,
146
+ injectStylesForNoShadowDOM,
147
+ bindings()
148
+ ], AtomicProductDescription);
149
+ export { AtomicProductDescription };
@@ -0,0 +1,3 @@
1
+ const css = `/*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */
2
+ .expandable-text{line-height:var(--line-height)}.min-lines-1{min-height:calc(var(--line-height)*1)}.min-lines-2{min-height:calc(var(--line-height)*2)}.min-lines-3{min-height:calc(var(--line-height)*3)}.min-lines-4{min-height:calc(var(--line-height)*4)}`;
3
+ export default [css];
@@ -19,6 +19,7 @@ import '../atomic-product-children/atomic-product-children';
19
19
  import '../atomic-product-multi-value-text/atomic-product-multi-value-text';
20
20
  import '../atomic-product-price/atomic-product-price';
21
21
  import '../atomic-product-numeric-field-value/atomic-product-numeric-field-value';
22
+ import '../atomic-product-description/atomic-product-description';
22
23
  /**
23
24
  * * A product template determines the format of the query results, depending on the conditions that are defined for each template.
24
25
  *
@@ -22,6 +22,7 @@ export { AtomicCommerceSortDropdown } from './atomic-commerce-sort-dropdown/atom
22
22
  export { AtomicCommerceText } from './atomic-commerce-text/atomic-commerce-text.js';
23
23
  export { AtomicProduct } from './atomic-product/atomic-product.js';
24
24
  export { AtomicProductChildren } from './atomic-product-children/atomic-product-children.js';
25
+ export { AtomicProductDescription } from './atomic-product-description/atomic-product-description.js';
25
26
  export { AtomicProductExcerpt } from './atomic-product-excerpt/atomic-product-excerpt.js';
26
27
  export { AtomicProductLink } from './atomic-product-link/atomic-product-link.js';
27
28
  export { AtomicProductMultiValueText } from './atomic-product-multi-value-text/atomic-product-multi-value-text.js';
@@ -23,6 +23,7 @@ export default {
23
23
  'atomic-commerce-text': async () => await import('./atomic-commerce-text/atomic-commerce-text.js'),
24
24
  'atomic-product': async () => await import('./atomic-product/atomic-product.js'),
25
25
  'atomic-product-children': async () => await import('./atomic-product-children/atomic-product-children.js'),
26
+ 'atomic-product-description': async () => await import('./atomic-product-description/atomic-product-description.js'),
26
27
  'atomic-product-excerpt': async () => await import('./atomic-product-excerpt/atomic-product-excerpt.js'),
27
28
  'atomic-product-link': async () => await import('./atomic-product-link/atomic-product-link.js'),
28
29
  'atomic-product-multi-value-text': async () => await import('./atomic-product-multi-value-text/atomic-product-multi-value-text.js'),
@@ -0,0 +1,38 @@
1
+ import { getAtomicEnvironment } from '../../../global/environment';
2
+ export function augmentWithExternalMiddleware(event, payload, config) {
3
+ if (config.analytics?.analyticsClientMiddleware) {
4
+ return config.analytics.analyticsClientMiddleware(event, payload);
5
+ }
6
+ return payload;
7
+ }
8
+ export function augmentAnalyticsWithAtomicVersion(payload) {
9
+ if (payload.customData) {
10
+ payload.customData.coveoAtomicVersion = getAtomicEnvironment().version;
11
+ }
12
+ return payload;
13
+ }
14
+ export function augmentAnalyticsConfigWithDocument() {
15
+ return {
16
+ documentLocation: document.location.href,
17
+ ...(document.referrer && { originLevel3: document.referrer }),
18
+ };
19
+ }
20
+ const versionMatcher = /^(\d+\.\d+\.\d+)/;
21
+ export function augmentAnalyticsConfigWithAtomicVersion() {
22
+ return {
23
+ source: {
24
+ '@coveo/atomic': versionMatcher.exec(getAtomicEnvironment().version)?.[0] || '0.0.0',
25
+ },
26
+ };
27
+ }
28
+ export function getNextAnalyticsConfig(searchEngineConfig, enabled) {
29
+ const configuration = {
30
+ enabled,
31
+ documentLocation: document.location.href,
32
+ ...(document.referrer && { originLevel3: document.referrer }),
33
+ };
34
+ const analyticsConfiguration = searchEngineConfig.analytics ?? {};
35
+ Object.assign(analyticsConfiguration, augmentAnalyticsConfigWithAtomicVersion());
36
+ Object.assign(configuration, analyticsConfiguration);
37
+ return configuration;
38
+ }
@@ -0,0 +1,89 @@
1
+ import Backend from 'i18next-http-backend';
2
+ import { setCoveoGlobal } from "../../../global/environment";
3
+ import { loadDayjsLocale } from "../../../utils/dayjs-locales";
4
+ import { i18nBackendOptions, i18nTranslationNamespace, init18n } from './i18n';
5
+ export class InterfaceController {
6
+ constructor(host, globalVariableName) {
7
+ this.hangingComponentsInitialization = [];
8
+ this.host = host;
9
+ this.host.addController(this);
10
+ setCoveoGlobal(globalVariableName);
11
+ }
12
+ hostConnected() {
13
+ this.i18nPromise = init18n(this.host);
14
+ this.initAriaLive();
15
+ }
16
+ hostDisconnected() {
17
+ this.removeAriaLive();
18
+ }
19
+ onComponentInitializing(event) {
20
+ event.preventDefault();
21
+ event.stopPropagation();
22
+ if (this.host.engine) {
23
+ event.detail(this.host.bindings);
24
+ return;
25
+ }
26
+ this.hangingComponentsInitialization.push(event);
27
+ }
28
+ async onInitialization(initEngine) {
29
+ if (this.host.engine) {
30
+ this.host.engine.logger.warn(`The ${this.interfaceTagname} component "initialize" has already been called.`, this.host);
31
+ return;
32
+ }
33
+ this.host.updateIconAssetsPath();
34
+ initEngine();
35
+ if (this.host.registerFieldsToInclude) {
36
+ this.host.registerFieldsToInclude();
37
+ }
38
+ loadDayjsLocale(this.host.language || 'en');
39
+ await this.i18nPromise;
40
+ this.initComponents();
41
+ }
42
+ onAnalyticsChange() {
43
+ const { engine, analytics } = this.host;
44
+ if (!this.engineIsCreated(engine)) {
45
+ return;
46
+ }
47
+ if (!analytics) {
48
+ engine.disableAnalytics();
49
+ return;
50
+ }
51
+ engine.enableAnalytics();
52
+ }
53
+ onLanguageChange(newLanguage) {
54
+ const language = newLanguage ?? this.host.language;
55
+ const languageWithFallback = language ?? 'en';
56
+ const { i18n } = this.host;
57
+ loadDayjsLocale(languageWithFallback);
58
+ new Backend(i18n.services, i18nBackendOptions(this.host)).read(languageWithFallback.split('-')[0], i18nTranslationNamespace, (_, data) => {
59
+ i18n.addResourceBundle(languageWithFallback.split('-')[0], i18nTranslationNamespace, data, true, false);
60
+ i18n.changeLanguage(language);
61
+ });
62
+ }
63
+ engineIsCreated(engine) {
64
+ if (!engine) {
65
+ console.error(`You have to call "initialize" on the ${this.interfaceTagname} component before modifying the props or calling other public methods.`, this.host);
66
+ return false;
67
+ }
68
+ return true;
69
+ }
70
+ get interfaceTagname() {
71
+ return this.host.tagName.toLowerCase();
72
+ }
73
+ initComponents() {
74
+ this.hangingComponentsInitialization.forEach((event) => event.detail(this.host.bindings));
75
+ }
76
+ initAriaLive() {
77
+ if (Array.from(this.host.children).some((element) => element.tagName === 'ATOMIC-ARIA-LIVE')) {
78
+ return;
79
+ }
80
+ const ariaLive = document.createElement('atomic-aria-live');
81
+ this.host.prepend(ariaLive);
82
+ }
83
+ removeAriaLive() {
84
+ const ariaLive = this.host.querySelector('atomic-aria-live');
85
+ if (ariaLive) {
86
+ ariaLive.remove();
87
+ }
88
+ }
89
+ }
@@ -4,7 +4,7 @@ function getWindow() {
4
4
  }
5
5
  export function getAtomicEnvironment() {
6
6
  return {
7
- version: "3.31.2-pre.8be4e70346".VERSION,
7
+ version: "3.31.2-pre.8c3f1d1fa1",
8
8
  headlessVersion: VERSION,
9
9
  };
10
10
  }
@@ -1 +1 @@
1
- {"file":"index.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAca,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,WAAmB,EAAE,UAAkB;QACjD,KAAK,CACH,QAAQ,WAAW,sCAAsC,UAAU,YAAY,CAChF,CAAC;KACH;;;ACfH,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;SAIpC,gBAAgB,CAAI,OAAgB,EAAE,UAAkB;IACtE,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM;QACpC,MAAM,KAAK,GAAG,gBAAgB,CAC5B,oBAAoB,EACpB,CAAC,IAAO;YACN,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;SACtB,CACF,CAAC;QACF,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE;YACjC,MAAM,CACJ,IAAI,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CACnE,CAAC;SACH;KACF,CAAC,CAAC;AACL;;ACoDA;;;;;;;;;;SAUgB,mBAAmB,CAAoB,OAAgB;IACrE,OAAO,gBAAgB,CAAI,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACxD;;;;","names":[],"sources":["src/components/common/item-list/context/item-context-controller.ts","src/components/common/item-list/fetch-item-context.ts","src/decorators/commerce/product-template-decorators.ts"],"sourcesContent":["import type {LitElement, ReactiveController, ReactiveControllerHost} from 'lit';\nimport type {InitializableComponent} from '@/src/decorators/types.js';\nimport {buildCustomEvent} from '@/src/utils/event-utils';\n\ntype LitElementWithError = Omit<\n Pick<InitializableComponent, 'error'>,\n 'error'\n> &\n LitElement & {\n error: Error | null;\n };\n\nconst itemContextEventName = 'atomic/resolveResult';\n\nexport class MissingParentError extends Error {\n constructor(elementName: string, parentName: string) {\n super(\n `The \"${elementName}\" element must be the child of an \"${parentName}\" element.`\n );\n }\n}\n\nfunction extractFolded<T = Record<string, unknown>>(\n item: Record<string, unknown>,\n returnFolded: boolean\n): T {\n if (returnFolded) {\n if ('children' in item) {\n return item as T;\n } else {\n return {children: [], result: item} as T;\n }\n }\n\n if ('children' in item && 'result' in item) {\n return item.result as T;\n }\n return item as T;\n}\n\n/**\n * A reactive controller that manages item context data from parent components.\n * Handles fetching item data via custom events and manages error states.\n */\nexport class ItemContextController<T = Record<string, unknown>>\n implements ReactiveController\n{\n private host: ReactiveControllerHost & LitElementWithError;\n private parentName: string;\n private folded: boolean;\n private _item: T | null = null;\n private _error: MissingParentError | null = null;\n\n constructor(\n host: ReactiveControllerHost & LitElementWithError,\n options: {parentName?: string; folded?: boolean} = {}\n ) {\n this.host = host;\n this.parentName = options.parentName ?? 'atomic-result';\n this.folded = options.folded ?? false;\n host.addController(this);\n }\n\n get item(): T | null {\n return this._error ? null : this._item;\n }\n\n get error(): MissingParentError | null {\n return this._error;\n }\n\n get hasError(): boolean {\n return this._error !== null;\n }\n\n hostConnected(): void {\n this._resolveItemContext();\n }\n\n private _resolveItemContext(): void {\n const event = buildCustomEvent(\n itemContextEventName,\n (item: Record<string, unknown>) => {\n this._item = extractFolded<T>(item, this.folded);\n this._error = null;\n this.host.error = null;\n this.host.requestUpdate();\n }\n );\n\n const canceled = this.host.dispatchEvent(event);\n if (canceled) {\n const elementName = (this.host as Element).nodeName.toLowerCase();\n this._error = new MissingParentError(elementName, this.parentName);\n this._item = null;\n this.host.error = this._error;\n this.host.requestUpdate();\n }\n }\n}\n\ntype ItemContextEventHandler<T> = (item: T) => void;\nexport type ItemContextEvent<T> = CustomEvent<ItemContextEventHandler<T>>;\n","import {closest} from '../../../utils/dom-utils.js';\nimport {buildCustomEvent} from '../../../utils/event-utils.js';\nimport {MissingParentError} from './context/item-context-controller.js';\n\nconst itemContextEventName = 'atomic/resolveResult';\n\ntype ItemContextEventHandler<T> = (item: T) => void;\n\nexport function fetchItemContext<T>(element: Element, parentName: string) {\n return new Promise<T>((resolve, reject) => {\n const event = buildCustomEvent<ItemContextEventHandler<T>>(\n itemContextEventName,\n (item: T) => {\n return resolve(item);\n }\n );\n element.dispatchEvent(event);\n\n if (!closest(element, parentName)) {\n reject(\n new MissingParentError(element.nodeName.toLowerCase(), parentName)\n );\n }\n });\n}\n","import type {InteractiveProduct, Product} from '@coveo/headless/commerce';\nimport type {LitElement} from 'lit';\nimport {\n InteractiveItemContextController,\n type InteractiveItemContextEvent,\n} from '@/src/components/common/item-list/context/interactive-item-context-controller';\nimport {\n ItemContextController,\n type ItemContextEvent,\n} from '@/src/components/common/item-list/context/item-context-controller';\nimport {fetchItemContext} from '@/src/components/common/item-list/fetch-item-context';\n\n/**\n * Creates a [Lit reactive controller](https://lit.dev/docs/composition/controllers/) for managing product context in product template components.\n *\n * @param host - The Lit component instance\n * @param options - Configuration options\n * @returns ItemContextController instance configured for atomic-product\n *\n * @example\n * ```typescript\n * @customElement('my-product-component')\n * export class MyProductComponent extends LitElement {\n * private productController = createProductContextController(this);\n *\n * @state() product!: Product;\n *\n * render() {\n * this.product = this.productController.item;\n * return html`<div>${this.product?.ec_name}</div>`;\n * }\n * }\n * ```\n */\nexport function createProductContextController(\n host: LitElement & {error: Error | null},\n options: {folded?: boolean} = {}\n): ItemContextController<Product> {\n return new ItemContextController<Product>(host, {\n parentName: 'atomic-product',\n folded: options.folded ?? false,\n });\n}\n\n/**\n * Creates a [Lit reactive controller](https://lit.dev/docs/composition/controllers/) for managing interactive product context in product template components.\n *\n * @param host - The Lit component instance\n * @returns InteractiveItemContextController instance\n *\n * @example\n * ```typescript\n * @customElement('my-interactive-product-component')\n * export class MyInteractiveProductComponent extends LitElement {\n * private interactiveProductController = createInteractiveProductContextController(this);\n *\n * @state() product!: Product;\n *\n * render() {\n * this.product = this.interactiveProductController.interactiveItem;\n * return html`<div>${this.product?.ec_name}</div>`;\n * }\n * }\n * ```\n */\nexport function createInteractiveProductContextController(\n host: LitElement & {error: Error}\n): InteractiveItemContextController<InteractiveProduct> {\n return new InteractiveItemContextController<InteractiveProduct>(host);\n}\n\nexport type ProductContextEvent<T = Product> = ItemContextEvent<T>;\nexport type InteractiveProductContextEvent<\n T extends InteractiveProduct = InteractiveProduct,\n> = InteractiveItemContextEvent<T>;\n\n/**\n * Retrieves `Product` on a rendered `atomic-product`.\n *\n * This utility function 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 utility function 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 */\nexport function fetchProductContext<T extends Product>(element: Element) {\n return fetchItemContext<T>(element, 'atomic-product');\n}\n"],"version":3}
1
+ {"file":"index.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAca,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,WAAmB,EAAE,UAAkB;QACjD,KAAK,CACH,QAAQ,WAAW,sCAAsC,UAAU,YAAY,CAChF,CAAC;KACH;;;ACfH,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;SAIpC,gBAAgB,CAAI,OAAgB,EAAE,UAAkB;IACtE,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM;QACpC,MAAM,KAAK,GAAG,gBAAgB,CAC5B,oBAAoB,EACpB,CAAC,IAAO;YACN,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;SACtB,CACF,CAAC;QACF,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE;YACjC,MAAM,CACJ,IAAI,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CACnE,CAAC;SACH;KACF,CAAC,CAAC;AACL;;ACoDA;;;;;;;;;;SAUgB,mBAAmB,CAAoB,OAAgB;IACrE,OAAO,gBAAgB,CAAI,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACxD;;;;","names":[],"sources":["src/components/common/item-list/context/item-context-controller.ts","src/components/common/item-list/fetch-item-context.ts","src/decorators/commerce/product-template-decorators.ts"],"sourcesContent":["import type {LitElement, ReactiveController, ReactiveControllerHost} from 'lit';\nimport type {InitializableComponent} from '@/src/decorators/types.js';\nimport {buildCustomEvent} from '@/src/utils/event-utils';\n\ntype LitElementWithError = Omit<\n Pick<InitializableComponent, 'error'>,\n 'error'\n> &\n LitElement & {\n error: Error | null;\n };\n\nconst itemContextEventName = 'atomic/resolveResult';\n\nexport class MissingParentError extends Error {\n constructor(elementName: string, parentName: string) {\n super(\n `The \"${elementName}\" element must be the child of an \"${parentName}\" element.`\n );\n }\n}\n\nfunction extractFolded<T = Record<string, unknown>>(\n item: Record<string, unknown>,\n returnFolded: boolean\n): T {\n if (returnFolded) {\n if ('children' in item) {\n return item as T;\n } else {\n return {children: [], result: item} as T;\n }\n }\n\n if ('children' in item && 'result' in item) {\n return item.result as T;\n }\n return item as T;\n}\n\n/**\n * A reactive controller that manages item context data from parent components.\n * Handles fetching item data via custom events and manages error states.\n */\nexport class ItemContextController<T = Record<string, unknown>>\n implements ReactiveController\n{\n private host: ReactiveControllerHost & LitElementWithError;\n private parentName: string;\n private folded: boolean;\n private _item: T | null = null;\n private _error: MissingParentError | null = null;\n\n constructor(\n host: ReactiveControllerHost & LitElementWithError,\n options: {parentName?: string; folded?: boolean} = {}\n ) {\n this.host = host;\n this.parentName = options.parentName ?? 'atomic-result';\n this.folded = options.folded ?? false;\n host.addController(this);\n }\n\n get item(): T | null {\n return this._error ? null : this._item;\n }\n\n get error(): MissingParentError | null {\n return this._error;\n }\n\n get hasError(): boolean {\n return this._error !== null;\n }\n\n hostConnected(): void {\n this._resolveItemContext();\n }\n\n private _resolveItemContext(): void {\n const event = buildCustomEvent(\n itemContextEventName,\n (item: Record<string, unknown>) => {\n this._item = extractFolded<T>(item, this.folded);\n this._error = null;\n this.host.error = null;\n this.host.requestUpdate();\n }\n );\n\n const canceled = this.host.dispatchEvent(event);\n if (canceled) {\n const elementName = (this.host as Element).nodeName.toLowerCase();\n this._error = new MissingParentError(elementName, this.parentName);\n this._item = null;\n this.host.error = this._error;\n this.host.requestUpdate();\n }\n }\n}\n\ntype ItemContextEventHandler<T> = (item: T) => void;\nexport type ItemContextEvent<T> = CustomEvent<ItemContextEventHandler<T>>;\n","import {closest} from '../../../utils/dom-utils.js';\nimport {buildCustomEvent} from '../../../utils/event-utils.js';\nimport {MissingParentError} from './context/item-context-controller.js';\n\nconst itemContextEventName = 'atomic/resolveResult';\n\ntype ItemContextEventHandler<T> = (item: T) => void;\n\nexport function fetchItemContext<T>(element: Element, parentName: string) {\n return new Promise<T>((resolve, reject) => {\n const event = buildCustomEvent<ItemContextEventHandler<T>>(\n itemContextEventName,\n (item: T) => {\n return resolve(item);\n }\n );\n element.dispatchEvent(event);\n\n if (!closest(element, parentName)) {\n reject(\n new MissingParentError(element.nodeName.toLowerCase(), parentName)\n );\n }\n });\n}\n","import type {InteractiveProduct, Product} from '@coveo/headless/commerce';\nimport type {LitElement} from 'lit';\nimport {\n InteractiveItemContextController,\n type InteractiveItemContextEvent,\n} from '@/src/components/common/item-list/context/interactive-item-context-controller';\nimport {\n ItemContextController,\n type ItemContextEvent,\n} from '@/src/components/common/item-list/context/item-context-controller';\nimport {fetchItemContext} from '@/src/components/common/item-list/fetch-item-context';\n\n/**\n * Creates a [Lit reactive controller](https://lit.dev/docs/composition/controllers/) for managing product context in product template components.\n *\n * @param host - The Lit component instance\n * @param options - Configuration options\n * @returns ItemContextController instance configured for atomic-product\n *\n * @example\n * ```typescript\n * @customElement('my-product-component')\n * export class MyProductComponent extends LitElement {\n * private productController = createProductContextController(this);\n *\n * @state() product!: Product;\n *\n * render() {\n * this.product = this.productController.item;\n * return html`<div>${this.product?.ec_name}</div>`;\n * }\n * }\n * ```\n */\nexport function createProductContextController(\n host: LitElement & {error: Error | null},\n options: {folded?: boolean} = {}\n): ItemContextController<Product> {\n return new ItemContextController<Product>(host, {\n parentName: 'atomic-product',\n folded: options.folded ?? false,\n });\n}\n\n/**\n * Creates a [Lit reactive controller](https://lit.dev/docs/composition/controllers/) for managing interactive product context in product template components.\n *\n * @param host - The Lit component instance\n * @returns InteractiveItemContextController instance\n *\n * @example\n * ```typescript\n * @customElement('my-interactive-product-component')\n * export class MyInteractiveProductComponent extends LitElement {\n * private interactiveProductController = createInteractiveProductContextController(this);\n *\n * @state() product!: Product;\n *\n * render() {\n * this.product = this.interactiveProductController.interactiveItem;\n * return html`<div>${this.product?.ec_name}</div>`;\n * }\n * }\n * ```\n */\nexport function createInteractiveProductContextController(\n host: LitElement & {error: Error}\n): InteractiveItemContextController<InteractiveProduct> {\n return new InteractiveItemContextController<InteractiveProduct>(host);\n}\n\nexport type ProductContextEvent<T = Product> = ItemContextEvent<T>;\nexport type InteractiveProductContextEvent<\n T extends InteractiveProduct = InteractiveProduct,\n> = InteractiveItemContextEvent<T>;\n\n/**\n * Retrieves `Product` on a rendered `atomic-product`.\n *\n * This utility function 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 utility function 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 */\nexport function fetchProductContext<T extends Product>(element: Element) {\n return fetchItemContext<T>(element, 'atomic-product');\n}\n"],"version":3}
@@ -1,6 +1,5 @@
1
1
  import { s as shouldUpdateFacetSearchComponent } from './stencil-facet-value-label-highlight.js';
2
2
  import { h } from '@stencil/core/internal/client';
3
- import { M as MinusIcon, P as PlusIcon } from './plus.js';
4
3
  import { B as Button } from './stencil-button.js';
5
4
 
6
5
  function announceFacetSearchResultsWithAriaLive(facet, label, setAriaLive, i18n) {
@@ -17,6 +16,13 @@ function announceFacetSearchResultsWithAriaLive(facet, label, setAriaLive, i18n)
17
16
  });
18
17
  }
19
18
 
19
+ const MinusIcon = `<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m64 208h384v96h-384z"/></svg>`;
20
+
21
+ const PlusIcon = `<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
22
+ <path d="M496 208H304V16h-96v192H16v96h192v192h96V304h192"/>
23
+ </svg>
24
+ `;
25
+
20
26
  const FacetShowMoreLess = (props) => {
21
27
  const label = props.i18n.t(props.label);
22
28
  const showMore = props.i18n.t('show-more');
@@ -1 +1 @@
1
- {"file":"stencil-facet-show-more-less.js","mappings":";;;;;SAIgB,sCAAsC,CACpD,KAA0E,EAC1E,KAAa,EACb,WAAkC,EAClC,IAAU;IAEV,IAAI,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;IACxC,KAAK,CAAC,SAAS,CAAC;QACd,IACE,gCAAgC,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC;YACpE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAC7B;YACA,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;YAEpC,WAAW,CACT,IAAI,CAAC,CAAC,CAAC,4BAA4B,EAAE;gBACnC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;gBAC5C,KAAK;aACN,CAAC,CACH,CAAC;SACH;KACF,CAAC,CAAC;AACL;;MCTa,iBAAiB,GAA4C,CACxE,KAAK;IAEL,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,EAAE;QACjE,KAAK;KACN,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,EAAE;QACjE,KAAK;KACN,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,sDAAsD,CAAC;IAC1E,MAAM,WAAW,GAAG,cAAc,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE;QACxD,OAAO;KACR;IAED,QACE,WAAK,KAAK,EAAC,MAAM;QACf,EAAC,MAAM,IACL,KAAK,EAAC,cAAc,EACpB,IAAI,EAAC,WAAW,EAChB,KAAK,EAAE,GAAG,UAAU,IAAI,KAAK,CAAC,iBAAiB,GAAG,EAAE,GAAG,QAAQ,EAAE,EACjE,SAAS,EAAE,mBAAmB,EAC9B,OAAO,EAAE,MAAM,KAAK,CAAC,UAAU,EAAE,EACjC,GAAG,EAAE,KAAK,CAAC,WAAW;YAEtB,mBACE,IAAI,EAAC,qBAAqB,EAC1B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,SAAS,GACF;YACf,YAAM,KAAK,EAAC,UAAU,IAAE,QAAQ,CAAQ,CACjC;QACT,EAAC,MAAM,IACL,KAAK,EAAC,cAAc,EACpB,IAAI,EAAC,WAAW,EAChB,KAAK,EAAE,GAAG,UAAU,IAAI,KAAK,CAAC,iBAAiB,GAAG,EAAE,GAAG,QAAQ,EAAE,EACjE,SAAS,EAAE,mBAAmB,EAC9B,OAAO,EAAE,MAAM,KAAK,CAAC,UAAU,EAAE,EACjC,GAAG,EAAE,KAAK,CAAC,WAAW;YAEtB,mBACE,IAAI,EAAC,qBAAqB,EAC1B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,QAAQ,GACD;YACf,YAAM,KAAK,EAAC,UAAU,IAAE,QAAQ,CAAQ,CACjC,CACL,EACN;AACJ;;;;","names":[],"sources":["src/components/common/facets/facet-search/facet-search-aria-live.ts","src/components/common/facets/facet-show-more-less/stencil-facet-show-more-less.tsx"],"sourcesContent":["import type {Facet, FacetSearchState} from '@coveo/headless';\nimport type {i18n} from 'i18next';\nimport {shouldUpdateFacetSearchComponent} from './facet-search-utils';\n\nexport function announceFacetSearchResultsWithAriaLive(\n facet: Pick<Facet, 'subscribe'> & {state: {facetSearch: FacetSearchState}},\n label: string,\n setAriaLive: (msg: string) => void,\n i18n: i18n\n) {\n let prevState = facet.state.facetSearch;\n facet.subscribe(() => {\n if (\n shouldUpdateFacetSearchComponent(facet.state.facetSearch, prevState) &&\n facet.state.facetSearch.query\n ) {\n prevState = facet.state.facetSearch;\n\n setAriaLive(\n i18n.t('facet-search-results-count', {\n count: facet.state.facetSearch.values.length,\n label,\n })\n );\n }\n });\n}\n","import {FunctionalComponent, h} from '@stencil/core';\nimport {i18n} from 'i18next';\nimport MinusIcon from '../../../../images/minus.svg';\nimport PlusIcon from '../../../../images/plus.svg';\nimport {Button} from '../../stencil-button';\n\ninterface FacetShowMoreProps {\n label: string;\n i18n: i18n;\n canShowLessValues: boolean;\n canShowMoreValues: boolean;\n onShowMore(): void;\n onShowLess(): void;\n showMoreRef?: (element?: HTMLButtonElement) => void;\n showLessRef?: (element?: HTMLButtonElement) => void;\n}\n\nexport const FacetShowMoreLess: FunctionalComponent<FacetShowMoreProps> = (\n props\n) => {\n const label = props.i18n.t(props.label);\n const showMore = props.i18n.t('show-more');\n const showMoreFacetValues = props.i18n.t('show-more-facet-values', {\n label,\n });\n const showLess = props.i18n.t('show-less');\n const showLessFacetValues = props.i18n.t('show-less-facet-values', {\n label,\n });\n const btnClasses = 'flex items-baseline text-left p-2 text-sm max-w-full';\n const iconClasses = 'w-2 h-2 mr-1';\n if (!props.canShowLessValues && !props.canShowMoreValues) {\n return;\n }\n\n return (\n <div class=\"mt-2\">\n <Button\n style=\"text-primary\"\n part=\"show-less\"\n class={`${btnClasses} ${props.canShowLessValues ? '' : 'hidden'}`}\n ariaLabel={showLessFacetValues}\n onClick={() => props.onShowLess()}\n ref={props.showLessRef}\n >\n <atomic-icon\n part=\"show-more-less-icon\"\n class={iconClasses}\n icon={MinusIcon}\n ></atomic-icon>\n <span class=\"truncate\">{showLess}</span>\n </Button>\n <Button\n style=\"text-primary\"\n part=\"show-more\"\n class={`${btnClasses} ${props.canShowMoreValues ? '' : 'hidden'}`}\n ariaLabel={showMoreFacetValues}\n onClick={() => props.onShowMore()}\n ref={props.showMoreRef}\n >\n <atomic-icon\n part=\"show-more-less-icon\"\n class={iconClasses}\n icon={PlusIcon}\n ></atomic-icon>\n <span class=\"truncate\">{showMore}</span>\n </Button>\n </div>\n );\n};\n"],"version":3}
1
+ {"file":"stencil-facet-show-more-less.js","mappings":";;;;SAIgB,sCAAsC,CACpD,KAA0E,EAC1E,KAAa,EACb,WAAkC,EAClC,IAAU;IAEV,IAAI,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;IACxC,KAAK,CAAC,SAAS,CAAC;QACd,IACE,gCAAgC,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC;YACpE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAC7B;YACA,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;YAEpC,WAAW,CACT,IAAI,CAAC,CAAC,CAAC,4BAA4B,EAAE;gBACnC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;gBAC5C,KAAK;aACN,CAAC,CACH,CAAC;SACH;KACF,CAAC,CAAC;AACL;;;;;;;;;MCTa,iBAAiB,GAA4C,CACxE,KAAK;IAEL,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,EAAE;QACjE,KAAK;KACN,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,EAAE;QACjE,KAAK;KACN,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,sDAAsD,CAAC;IAC1E,MAAM,WAAW,GAAG,cAAc,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE;QACxD,OAAO;KACR;IAED,QACE,WAAK,KAAK,EAAC,MAAM;QACf,EAAC,MAAM,IACL,KAAK,EAAC,cAAc,EACpB,IAAI,EAAC,WAAW,EAChB,KAAK,EAAE,GAAG,UAAU,IAAI,KAAK,CAAC,iBAAiB,GAAG,EAAE,GAAG,QAAQ,EAAE,EACjE,SAAS,EAAE,mBAAmB,EAC9B,OAAO,EAAE,MAAM,KAAK,CAAC,UAAU,EAAE,EACjC,GAAG,EAAE,KAAK,CAAC,WAAW;YAEtB,mBACE,IAAI,EAAC,qBAAqB,EAC1B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,SAAS,GACF;YACf,YAAM,KAAK,EAAC,UAAU,IAAE,QAAQ,CAAQ,CACjC;QACT,EAAC,MAAM,IACL,KAAK,EAAC,cAAc,EACpB,IAAI,EAAC,WAAW,EAChB,KAAK,EAAE,GAAG,UAAU,IAAI,KAAK,CAAC,iBAAiB,GAAG,EAAE,GAAG,QAAQ,EAAE,EACjE,SAAS,EAAE,mBAAmB,EAC9B,OAAO,EAAE,MAAM,KAAK,CAAC,UAAU,EAAE,EACjC,GAAG,EAAE,KAAK,CAAC,WAAW;YAEtB,mBACE,IAAI,EAAC,qBAAqB,EAC1B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,QAAQ,GACD;YACf,YAAM,KAAK,EAAC,UAAU,IAAE,QAAQ,CAAQ,CACjC,CACL,EACN;AACJ;;;;","names":[],"sources":["src/components/common/facets/facet-search/facet-search-aria-live.ts","src/components/common/facets/facet-show-more-less/stencil-facet-show-more-less.tsx"],"sourcesContent":["import type {Facet, FacetSearchState} from '@coveo/headless';\nimport type {i18n} from 'i18next';\nimport {shouldUpdateFacetSearchComponent} from './facet-search-utils';\n\nexport function announceFacetSearchResultsWithAriaLive(\n facet: Pick<Facet, 'subscribe'> & {state: {facetSearch: FacetSearchState}},\n label: string,\n setAriaLive: (msg: string) => void,\n i18n: i18n\n) {\n let prevState = facet.state.facetSearch;\n facet.subscribe(() => {\n if (\n shouldUpdateFacetSearchComponent(facet.state.facetSearch, prevState) &&\n facet.state.facetSearch.query\n ) {\n prevState = facet.state.facetSearch;\n\n setAriaLive(\n i18n.t('facet-search-results-count', {\n count: facet.state.facetSearch.values.length,\n label,\n })\n );\n }\n });\n}\n","import {FunctionalComponent, h} from '@stencil/core';\nimport {i18n} from 'i18next';\nimport MinusIcon from '../../../../images/minus.svg';\nimport PlusIcon from '../../../../images/plus.svg';\nimport {Button} from '../../stencil-button';\n\ninterface FacetShowMoreProps {\n label: string;\n i18n: i18n;\n canShowLessValues: boolean;\n canShowMoreValues: boolean;\n onShowMore(): void;\n onShowLess(): void;\n showMoreRef?: (element?: HTMLButtonElement) => void;\n showLessRef?: (element?: HTMLButtonElement) => void;\n}\n\nexport const FacetShowMoreLess: FunctionalComponent<FacetShowMoreProps> = (\n props\n) => {\n const label = props.i18n.t(props.label);\n const showMore = props.i18n.t('show-more');\n const showMoreFacetValues = props.i18n.t('show-more-facet-values', {\n label,\n });\n const showLess = props.i18n.t('show-less');\n const showLessFacetValues = props.i18n.t('show-less-facet-values', {\n label,\n });\n const btnClasses = 'flex items-baseline text-left p-2 text-sm max-w-full';\n const iconClasses = 'w-2 h-2 mr-1';\n if (!props.canShowLessValues && !props.canShowMoreValues) {\n return;\n }\n\n return (\n <div class=\"mt-2\">\n <Button\n style=\"text-primary\"\n part=\"show-less\"\n class={`${btnClasses} ${props.canShowLessValues ? '' : 'hidden'}`}\n ariaLabel={showLessFacetValues}\n onClick={() => props.onShowLess()}\n ref={props.showLessRef}\n >\n <atomic-icon\n part=\"show-more-less-icon\"\n class={iconClasses}\n icon={MinusIcon}\n ></atomic-icon>\n <span class=\"truncate\">{showLess}</span>\n </Button>\n <Button\n style=\"text-primary\"\n part=\"show-more\"\n class={`${btnClasses} ${props.canShowMoreValues ? '' : 'hidden'}`}\n ariaLabel={showMoreFacetValues}\n onClick={() => props.onShowMore()}\n ref={props.showMoreRef}\n >\n <atomic-icon\n part=\"show-more-less-icon\"\n class={iconClasses}\n icon={PlusIcon}\n ></atomic-icon>\n <span class=\"truncate\">{showMore}</span>\n </Button>\n </div>\n );\n};\n"],"version":3}