@useinsider/guido 2.1.0-beta.8699c8a → 2.1.0-beta.8e15673

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 (132) hide show
  1. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +15 -14
  2. package/dist/composables/useHtmlValidator.js +106 -84
  3. package/dist/composables/useRecommendation.js +54 -21
  4. package/dist/config/compiler/recommendationCompilerRules.js +45 -39
  5. package/dist/config/compiler/utils/recommendationCompilerUtils.js +116 -0
  6. package/dist/config/migrator/recommendationMigrator.js +2 -2
  7. package/dist/enums/extensions/recommendationBlock.js +1 -1
  8. package/dist/enums/recommendation.js +16 -15
  9. package/dist/extensions/Blocks/Recommendation/block.js +133 -9
  10. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +4 -0
  11. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +4 -0
  12. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +66 -0
  13. package/dist/extensions/Blocks/Recommendation/constants/layout.js +22 -0
  14. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +21 -0
  15. package/dist/extensions/Blocks/Recommendation/controls/button/index.js +64 -0
  16. package/dist/extensions/Blocks/Recommendation/controls/cardBackground/index.js +80 -0
  17. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +232 -0
  18. package/dist/extensions/Blocks/Recommendation/controls/image/index.js +19 -0
  19. package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +92 -0
  20. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +102 -0
  21. package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +209 -0
  22. package/dist/extensions/Blocks/Recommendation/controls/main/filters.js +52 -0
  23. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +218 -0
  24. package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +70 -0
  25. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +160 -0
  26. package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +67 -0
  27. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +307 -0
  28. package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +21 -0
  29. package/dist/extensions/Blocks/Recommendation/controls/name/index.js +46 -0
  30. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +108 -0
  31. package/dist/extensions/Blocks/Recommendation/controls/oldPrice/index.js +44 -0
  32. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.js +48 -0
  33. package/dist/extensions/Blocks/Recommendation/controls/{omnibusDiscountTextAfterControl.js → omnibusDiscount/textAfter.js} +16 -14
  34. package/dist/extensions/Blocks/Recommendation/controls/{omnibusDiscountTextBeforeControl.js → omnibusDiscount/textBefore.js} +16 -14
  35. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/index.js +48 -0
  36. package/dist/extensions/Blocks/Recommendation/controls/{omnibusPriceTextAfterControl.js → omnibusPrice/textAfter.js} +16 -14
  37. package/dist/extensions/Blocks/Recommendation/controls/{omnibusPriceTextBeforeControl.js → omnibusPrice/textBefore.js} +14 -12
  38. package/dist/extensions/Blocks/Recommendation/controls/price/index.js +44 -0
  39. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +222 -0
  40. package/dist/extensions/Blocks/Recommendation/extension.js +40 -17
  41. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +19 -3
  42. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +13 -4
  43. package/dist/extensions/Blocks/Recommendation/services/configService.js +240 -0
  44. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +21 -10
  45. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +256 -207
  46. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +233 -0
  47. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +251 -0
  48. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +66 -0
  49. package/dist/extensions/Blocks/Recommendation/templates/index.js +12 -0
  50. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +174 -0
  51. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +73 -0
  52. package/dist/extensions/Blocks/Recommendation/templates/utils.js +134 -0
  53. package/dist/extensions/Blocks/Recommendation/types/nodeConfig.js +6 -0
  54. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +9 -9
  55. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +26 -15
  56. package/dist/extensions/Blocks/Recommendation/utils/priceFormatter.js +29 -0
  57. package/dist/extensions/Blocks/Recommendation/utils/tagName.js +46 -0
  58. package/dist/extensions/Blocks/controlFactories.js +125 -93
  59. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +225 -169
  60. package/dist/services/recommendationApi.js +11 -8
  61. package/dist/services/templateLibraryApi.js +16 -13
  62. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +1 -1
  63. package/dist/src/composables/useRecommendation.d.ts +1 -0
  64. package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +17 -0
  65. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +67 -0
  66. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +13 -0
  67. package/dist/src/extensions/Blocks/Recommendation/{constants.d.ts → constants/controlIds.d.ts} +0 -24
  68. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +49 -0
  69. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +13 -0
  70. package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +41 -0
  71. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +35 -0
  72. package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +143 -0
  73. package/dist/src/extensions/Blocks/Recommendation/controls/cardBackground/index.d.ts +31 -0
  74. package/dist/src/extensions/Blocks/Recommendation/{cardCompositionControl.d.ts → controls/cardComposition/index.d.ts} +23 -3
  75. package/dist/src/extensions/Blocks/Recommendation/controls/image/index.d.ts +35 -0
  76. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +21 -589
  77. package/dist/src/extensions/Blocks/Recommendation/controls/layout/index.d.ts +37 -0
  78. package/dist/src/extensions/Blocks/Recommendation/controls/main/algorithm.d.ts +29 -0
  79. package/dist/src/extensions/Blocks/Recommendation/controls/main/currency.d.ts +52 -0
  80. package/dist/src/extensions/Blocks/Recommendation/controls/main/filters.d.ts +22 -0
  81. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +67 -0
  82. package/dist/src/extensions/Blocks/Recommendation/controls/main/locale.d.ts +24 -0
  83. package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +60 -0
  84. package/dist/src/extensions/Blocks/Recommendation/controls/main/shuffle.d.ts +23 -0
  85. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +221 -0
  86. package/dist/src/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.d.ts +29 -0
  87. package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +97 -0
  88. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +34 -0
  89. package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +95 -0
  90. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +100 -0
  91. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.d.ts +15 -0
  92. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.d.ts +15 -0
  93. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +100 -0
  94. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.d.ts +15 -0
  95. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.d.ts +15 -0
  96. package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +95 -0
  97. package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +83 -0
  98. package/dist/src/extensions/Blocks/Recommendation/extension.d.ts +9 -0
  99. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +151 -0
  100. package/dist/src/extensions/Blocks/Recommendation/services/index.d.ts +6 -0
  101. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +138 -468
  102. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +20 -0
  103. package/dist/src/extensions/Blocks/Recommendation/templates/{migrationTemplate.d.ts → grid/migration.d.ts} +11 -4
  104. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +33 -0
  105. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +41 -0
  106. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +8 -0
  107. package/dist/src/extensions/Blocks/Recommendation/templates/list/migration.d.ts +25 -0
  108. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +18 -0
  109. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +66 -0
  110. package/dist/src/extensions/Blocks/Recommendation/types/index.d.ts +7 -0
  111. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +166 -0
  112. package/dist/src/extensions/Blocks/Recommendation/utils/priceFormatter.d.ts +33 -0
  113. package/dist/src/extensions/Blocks/Recommendation/utils/stylePreserver.d.ts +113 -0
  114. package/dist/src/extensions/Blocks/Recommendation/utils/tagName.d.ts +77 -0
  115. package/dist/static/styles/customEditorStyle.css.js +35 -11
  116. package/dist/utils/pairProductVariables.js +57 -56
  117. package/dist/utils/templatePreparation.js +15 -14
  118. package/package.json +1 -1
  119. package/dist/extensions/Blocks/Recommendation/cardCompositionControl.js +0 -187
  120. package/dist/extensions/Blocks/Recommendation/constants.js +0 -13
  121. package/dist/extensions/Blocks/Recommendation/control.js +0 -336
  122. package/dist/extensions/Blocks/Recommendation/controls/cardBackgroundColorControl.js +0 -68
  123. package/dist/extensions/Blocks/Recommendation/controls/index.js +0 -245
  124. package/dist/extensions/Blocks/Recommendation/controls/nameTextTrimControl.js +0 -74
  125. package/dist/extensions/Blocks/Recommendation/controls/spacingControl.js +0 -188
  126. package/dist/extensions/Blocks/Recommendation/templates/blockTemplate.js +0 -181
  127. package/dist/extensions/Blocks/Recommendation/templates/migrationTemplate.js +0 -189
  128. package/dist/extensions/Blocks/Recommendation/templates/templateUtils.js +0 -209
  129. package/dist/src/extensions/Blocks/Recommendation/control.d.ts +0 -38
  130. package/dist/src/extensions/Blocks/Recommendation/controls/nameTextTrimControl.d.ts +0 -16
  131. package/dist/src/extensions/Blocks/Recommendation/templates/blockTemplate.d.ts +0 -16
  132. package/dist/src/extensions/Blocks/Recommendation/templates/templateUtils.d.ts +0 -52
@@ -0,0 +1,52 @@
1
+ var n = Object.defineProperty;
2
+ var o = (i, e, t) => e in i ? n(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
3
+ var r = (i, e, t) => o(i, typeof e != "symbol" ? e + "" : e, t);
4
+ import { CommonControl as s } from "../../../common-control.js";
5
+ import { useRecommendationExtensionStore as l } from "../../store/recommendation.js";
6
+ const d = "recommendation-filters-control", a = {
7
+ FILTERS: "filterStatus"
8
+ };
9
+ class h extends s {
10
+ constructor() {
11
+ super(...arguments);
12
+ r(this, "store", l());
13
+ r(this, "addFilterListener", () => {
14
+ });
15
+ r(this, "addFilterButton", null);
16
+ }
17
+ getId() {
18
+ return d;
19
+ }
20
+ getTemplate() {
21
+ return `
22
+ <div class="filters-control-container">
23
+ ${this._GuTwoColumns([
24
+ this._GuLabel({ text: "Filters" }),
25
+ this._GuButton({
26
+ name: a.FILTERS,
27
+ label: "Add Filter",
28
+ id: "guido__btn-add-filter"
29
+ })
30
+ ])}
31
+ </div>
32
+ `;
33
+ }
34
+ onRender() {
35
+ this._setupButtonListener();
36
+ }
37
+ onDestroy() {
38
+ var t;
39
+ (t = this.addFilterButton) == null || t.removeEventListener("click", this.addFilterListener);
40
+ }
41
+ _onFilterSelectClick() {
42
+ this.store.openFilterDrawer();
43
+ }
44
+ _setupButtonListener() {
45
+ var t;
46
+ this.addFilterListener = this._onFilterSelectClick.bind(this), this.addFilterButton = this.getContainer().querySelector("#guido__btn-add-filter"), (t = this.addFilterButton) == null || t.addEventListener("click", this.addFilterListener);
47
+ }
48
+ }
49
+ export {
50
+ d as FILTERS_CONTROL_ID,
51
+ h as FiltersControl
52
+ };
@@ -0,0 +1,218 @@
1
+ var d = Object.defineProperty;
2
+ var m = (c, s, t) => s in c ? d(c, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[s] = t;
3
+ var n = (c, s, t) => m(c, typeof s != "symbol" ? s + "" : s, t);
4
+ import { CommonControl as h } from "../../../common-control.js";
5
+ import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
6
+ import { AlgorithmControl as f } from "./algorithm.js";
7
+ import { ALGORITHM_CONTROL_ID as M } from "./algorithm.js";
8
+ import { CurrencyControl as p } from "./currency.js";
9
+ import { CURRENCY_CONTROL_ID as W } from "./currency.js";
10
+ import { FiltersControl as g } from "./filters.js";
11
+ import { FILTERS_CONTROL_ID as H } from "./filters.js";
12
+ import { LocaleControl as R } from "./locale.js";
13
+ import { LOCALE_CONTROL_ID as j } from "./locale.js";
14
+ import { ProductLayoutControl as _ } from "./productLayout.js";
15
+ import { PRODUCT_LAYOUT_CONTROL_ID as K } from "./productLayout.js";
16
+ import { ShuffleControl as N } from "./shuffle.js";
17
+ import { SHUFFLE_CONTROL_ID as J } from "./shuffle.js";
18
+ import { regenerateProductRowsWithStyles as b, getBlockElement as P, updateProductContentInPlace as y } from "./utils.js";
19
+ import { formatProductPrice as X, getCardComposition as Z, getCurrentLayout as tt, reapplySpacing as et, regenerateMobileProductRows as ot, regenerateProductRows as rt, setCurrencyAttributes as nt, updatePricesInPlace as it, updateSingleProductContent as st } from "./utils.js";
20
+ import { useDebounceFn as a } from "../../../../../node_modules/@vueuse/shared/index.js";
21
+ const I = "recommendation-id", T = "ui-elements-recommendation-block";
22
+ class B extends h {
23
+ constructor() {
24
+ super(...arguments);
25
+ n(this, "store", C());
26
+ n(this, "storeUnsubscription", () => {
27
+ });
28
+ // Sub-control instances for lifecycle management
29
+ n(this, "algorithmControl", null);
30
+ n(this, "localeControl", null);
31
+ n(this, "currencyControl", null);
32
+ n(this, "productLayoutControl", null);
33
+ n(this, "filtersControl", null);
34
+ n(this, "shuffleControl", null);
35
+ /**
36
+ * Debounced product fetch to prevent rapid API calls during config changes
37
+ */
38
+ n(this, "_debouncedFetchProducts", a(() => {
39
+ this.store.fetchRecommendationProducts();
40
+ }, 500));
41
+ /**
42
+ * Debounced regeneration when products arrive from API
43
+ * Tries in-place update first to preserve styles, falls back to full regeneration
44
+ */
45
+ n(this, "_debouncedRegenerateWithProducts", a(() => {
46
+ const t = this.store.recommendationProducts;
47
+ if (!this.currentNode || !this.api)
48
+ return;
49
+ const e = this.api.getDocumentModifier();
50
+ y({
51
+ currentNode: this.currentNode,
52
+ documentModifier: e,
53
+ products: t
54
+ }) || this._regenerateWithProducts(t);
55
+ }, 100));
56
+ }
57
+ getId() {
58
+ return T;
59
+ }
60
+ getTemplate() {
61
+ return this.algorithmControl = new f(), this.localeControl = new R(), this.currencyControl = new p(), this.productLayoutControl = new _(), this.filtersControl = new g(), this.shuffleControl = new N(), `
62
+ <div class="recommendation-controls-container">
63
+ ${this.algorithmControl.getTemplate()}
64
+ ${this.localeControl.getTemplate()}
65
+ ${this.currencyControl.getTemplate()}
66
+ ${this.filtersControl.getTemplate()}
67
+ ${this.productLayoutControl.getTemplate()}
68
+ ${this.shuffleControl.getTemplate()}
69
+ </div>
70
+ `;
71
+ }
72
+ async onRender() {
73
+ var e;
74
+ const t = this._getRecommendationIdFromNode(this.currentNode) ?? this.store.currentRecommendationId;
75
+ if (t !== null && this.store.setCurrentBlock(t), this._listenStateUpdates(), t !== null && ((e = this.store.blockStates[t]) != null && e.isInitialized)) {
76
+ this._initializeSubControls();
77
+ return;
78
+ }
79
+ await this._fetchBlockData(t), this._initializeSubControls();
80
+ }
81
+ /**
82
+ * Immediately regenerate products with styles (no debounce)
83
+ * Used for initial load after fetch completes
84
+ */
85
+ _regenerateWithProducts(t) {
86
+ if (!this.currentNode || !this.api) {
87
+ console.warn("[Recommendation] Cannot regenerate - missing currentNode or api");
88
+ return;
89
+ }
90
+ b({
91
+ currentNode: this.currentNode,
92
+ documentModifier: this.api.getDocumentModifier(),
93
+ products: t
94
+ });
95
+ }
96
+ onTemplateNodeUpdated(t) {
97
+ var i;
98
+ super.onTemplateNodeUpdated(t);
99
+ const e = this._getRecommendationIdFromNode(t);
100
+ e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !((i = this.store.blockStates[e]) != null && i.isInitialized) && this._fetchBlockData(e), [
101
+ this.algorithmControl,
102
+ this.localeControl,
103
+ this.currencyControl,
104
+ this.productLayoutControl,
105
+ this.filtersControl,
106
+ this.shuffleControl
107
+ ].forEach((r) => {
108
+ var l;
109
+ r != null && r.api && (r.currentNode = t, (l = r.onTemplateNodeUpdated) == null || l.call(r, t));
110
+ });
111
+ }
112
+ onDestroy() {
113
+ this.storeUnsubscription(), [
114
+ this.algorithmControl,
115
+ this.localeControl,
116
+ this.currencyControl,
117
+ this.productLayoutControl,
118
+ this.filtersControl,
119
+ this.shuffleControl
120
+ ].forEach((e) => {
121
+ var o;
122
+ return (o = e == null ? void 0 : e.onDestroy) == null ? void 0 : o.call(e);
123
+ });
124
+ }
125
+ /**
126
+ * Initialize all sub-controls with the shared API context
127
+ * Each sub-control manages its own form values and event listeners
128
+ */
129
+ _initializeSubControls() {
130
+ [
131
+ this.algorithmControl,
132
+ this.localeControl,
133
+ this.currencyControl,
134
+ this.productLayoutControl,
135
+ this.filtersControl,
136
+ this.shuffleControl
137
+ ].forEach((e) => {
138
+ var o;
139
+ e && (e.api = this.api, e.currentNode = this.currentNode, (o = e.onRender) == null || o.call(e));
140
+ });
141
+ }
142
+ /**
143
+ * Fetches initial data for a block (filters, algorithms, products).
144
+ * Shared by onRender() and onTemplateNodeUpdated() to avoid duplication.
145
+ * Marks the block as initialized to prevent redundant fetches on re-selection.
146
+ */
147
+ async _fetchBlockData(t) {
148
+ t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
149
+ this.store.fetchRecommendationFilters(),
150
+ this.store.fetchRecommendationCreateData(),
151
+ this.store.fetchRecommendationProducts()
152
+ ])).forEach((o, i) => {
153
+ o.status === "rejected" && console.warn(`Recommendation block: ${[
154
+ "fetchRecommendationFilters",
155
+ "fetchRecommendationCreateData",
156
+ "fetchRecommendationProducts"
157
+ ][i]} failed`, o.reason);
158
+ });
159
+ }
160
+ /**
161
+ * Reads the recommendation-id attribute from the block element within the node
162
+ */
163
+ _getRecommendationIdFromNode(t) {
164
+ const e = P(t);
165
+ if (!e || !("getAttribute" in e))
166
+ return null;
167
+ const o = e.getAttribute(I);
168
+ if (!o)
169
+ return null;
170
+ const i = parseInt(o);
171
+ return Number.isNaN(i) ? null : i;
172
+ }
173
+ /**
174
+ * Listen to store changes that require product refresh or regeneration.
175
+ *
176
+ * Uses configVersion counter (incremented only by patchCurrentBlockConfig)
177
+ * to distinguish user-initiated config changes from internal mutations
178
+ * (e.g., fetchRecommendationCreateData setting preferred currency).
179
+ */
180
+ _listenStateUpdates() {
181
+ const { store: t } = this;
182
+ let e = t.recommendationProducts, o = t.$state.configVersion;
183
+ this.storeUnsubscription = t.$subscribe(() => {
184
+ const i = t.$state.configVersion;
185
+ i !== o && (o = i, this._debouncedFetchProducts());
186
+ const r = t.recommendationProducts, l = r !== e, u = Array.isArray(r) && r.length > 0;
187
+ l && u && (e = r, this._debouncedRegenerateWithProducts());
188
+ });
189
+ }
190
+ }
191
+ export {
192
+ M as ALGORITHM_CONTROL_ID,
193
+ f as AlgorithmControl,
194
+ T as CONTROL_BLOCK_ID,
195
+ W as CURRENCY_CONTROL_ID,
196
+ p as CurrencyControl,
197
+ H as FILTERS_CONTROL_ID,
198
+ g as FiltersControl,
199
+ j as LOCALE_CONTROL_ID,
200
+ R as LocaleControl,
201
+ K as PRODUCT_LAYOUT_CONTROL_ID,
202
+ _ as ProductLayoutControl,
203
+ B as RecommendationBlockControl,
204
+ J as SHUFFLE_CONTROL_ID,
205
+ N as ShuffleControl,
206
+ X as formatProductPrice,
207
+ P as getBlockElement,
208
+ Z as getCardComposition,
209
+ tt as getCurrentLayout,
210
+ et as reapplySpacing,
211
+ ot as regenerateMobileProductRows,
212
+ rt as regenerateProductRows,
213
+ b as regenerateProductRowsWithStyles,
214
+ nt as setCurrencyAttributes,
215
+ it as updatePricesInPlace,
216
+ y as updateProductContentInPlace,
217
+ st as updateSingleProductContent
218
+ };
@@ -0,0 +1,70 @@
1
+ var s = Object.defineProperty;
2
+ var r = (o, t, e) => t in o ? s(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
3
+ var a = (o, t, e) => r(o, typeof t != "symbol" ? t + "" : t, e);
4
+ import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as m } from "../../../common-control.js";
6
+ import { RecommendationConfigService as i } from "../../services/configService.js";
7
+ import { useRecommendationExtensionStore as c } from "../../store/recommendation.js";
8
+ const g = "recommendation-locale-control", n = {
9
+ LOCALE: "language"
10
+ };
11
+ class C extends m {
12
+ constructor() {
13
+ super(...arguments);
14
+ // Store is used ONLY for API-fetched data (language options), not for config
15
+ a(this, "store", c());
16
+ }
17
+ getId() {
18
+ return g;
19
+ }
20
+ getTemplate() {
21
+ return `
22
+ <div class="locale-control-container">
23
+ ${this._GuTwoColumns([
24
+ this._GuLabel({ text: "Recommendation Locale" }),
25
+ this._GuSelect({
26
+ name: n.LOCALE,
27
+ placeholder: "Select Recommendation Locale",
28
+ options: this.store.getLanguages
29
+ })
30
+ ])}
31
+ </div>
32
+ `;
33
+ }
34
+ onRender() {
35
+ this._initializeSelectItems(), this._setFormValues(), this._listenToFormUpdates();
36
+ }
37
+ onTemplateNodeUpdated(e) {
38
+ super.onTemplateNodeUpdated(e), this._setFormValues();
39
+ }
40
+ _setFormValues() {
41
+ const e = i.getConfig(this.currentNode);
42
+ this.api.updateValues({
43
+ [n.LOCALE]: e.language
44
+ });
45
+ }
46
+ _initializeSelectItems() {
47
+ this.api.setUIEAttribute(
48
+ n.LOCALE,
49
+ l.SELECTPICKER.items,
50
+ this.store.getLanguages
51
+ );
52
+ }
53
+ _onLocaleChange(e) {
54
+ this.currentNode && (i.updateConfig(
55
+ this.api,
56
+ this.currentNode,
57
+ { language: e },
58
+ `Changed language to ${e}`
59
+ ), this.store.patchCurrentBlockConfig({ language: e }));
60
+ }
61
+ _listenToFormUpdates() {
62
+ this.api.onValueChanged(n.LOCALE, (e) => {
63
+ this._onLocaleChange(e);
64
+ });
65
+ }
66
+ }
67
+ export {
68
+ g as LOCALE_CONTROL_ID,
69
+ C as LocaleControl
70
+ };
@@ -0,0 +1,160 @@
1
+ var _ = Object.defineProperty;
2
+ var c = (i, o, t) => o in i ? _(i, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[o] = t;
3
+ var d = (i, o, t) => c(i, typeof o != "symbol" ? o + "" : o, t);
4
+ import { EditorStatePropertyType as u, PreviewDeviceMode as R } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as h } from "../../../common-control.js";
6
+ import { MAX_PRODUCT_COUNT as C, MAX_PRODUCTS_PER_ROW as p, MAX_MOBILE_PRODUCTS_PER_ROW as m } from "../../constants/layout.js";
7
+ import { RecommendationConfigService as s } from "../../services/configService.js";
8
+ import { useRecommendationExtensionStore as l } from "../../store/recommendation.js";
9
+ import { ensureMobileCssRulesExist as O } from "../mobileLayout/cssRules.js";
10
+ import { getCurrentLayout as I, regenerateMobileProductRows as g, regenerateProductRowsWithStyles as b } from "./utils.js";
11
+ import { useDebounceFn as N } from "../../../../../node_modules/@vueuse/shared/index.js";
12
+ const P = "recommendation-product-layout-control", e = {
13
+ PRODUCT_COUNT: "size",
14
+ PRODUCT_IN_ROW: "cardsInRow",
15
+ PRODUCT_IN_ROW_LABEL: "cardsInRowLabel",
16
+ MOBILE_CARDS_IN_ROW: "mobileCardsInRow",
17
+ MOBILE_CARDS_IN_ROW_LABEL: "mobileCardsInRowLabel"
18
+ };
19
+ class S extends h {
20
+ constructor() {
21
+ super(...arguments);
22
+ // Store is used for backward compatibility with product fetching and regeneration
23
+ d(this, "store", l());
24
+ d(this, "storeUnsubscription", () => {
25
+ });
26
+ d(this, "_debouncedRegenerateProductRows", N(() => {
27
+ this._regenerateProductRows();
28
+ }, 500));
29
+ }
30
+ getId() {
31
+ return P;
32
+ }
33
+ getTemplate() {
34
+ return `
35
+ <div class="product-layout-control-container">
36
+ ${this._GuTwoColumns([
37
+ this._GuLabel({ text: "Number of Products" }),
38
+ this._GuCounter({ name: e.PRODUCT_COUNT, maxValue: C }),
39
+ this._GuLabel({
40
+ text: "Products in One Row on Desktop",
41
+ name: e.PRODUCT_IN_ROW_LABEL
42
+ }),
43
+ this._GuCounter({ name: e.PRODUCT_IN_ROW, maxValue: p }),
44
+ this._GuLabel({
45
+ text: "Products in One Row on Mobile",
46
+ name: e.MOBILE_CARDS_IN_ROW_LABEL
47
+ }),
48
+ this._GuCounter({
49
+ name: e.MOBILE_CARDS_IN_ROW,
50
+ maxValue: m
51
+ })
52
+ ])}
53
+ </div>
54
+ `;
55
+ }
56
+ onRender() {
57
+ this._setFormValues(), this._updateProductsInRowVisibility(), this._listenToFormUpdates(), this._listenStateUpdates(), this._subscribeToEditorModeChanges();
58
+ }
59
+ onTemplateNodeUpdated(t) {
60
+ super.onTemplateNodeUpdated(t), this._setFormValues(), this._updateProductsInRowVisibility();
61
+ }
62
+ onDestroy() {
63
+ this.storeUnsubscription();
64
+ }
65
+ _setFormValues() {
66
+ const t = s.getConfig(this.currentNode);
67
+ this.api.updateValues({
68
+ [e.PRODUCT_COUNT]: t.size,
69
+ [e.PRODUCT_IN_ROW]: t.cardsInRow,
70
+ [e.MOBILE_CARDS_IN_ROW]: t.mobileCardsInRow
71
+ });
72
+ }
73
+ /**
74
+ * Checks if the editor is currently in mobile preview mode
75
+ * using Stripo's EditorStatePropertyType API.
76
+ */
77
+ _isMobileMode() {
78
+ return this.api.getEditorState()[u.previewDeviceMode] === R.MOBILE;
79
+ }
80
+ /**
81
+ * Updates counter visibility based on layout orientation and editor mode.
82
+ * - List layout: hide both counters (products always full-width)
83
+ * - Grid + desktop mode: show desktop counter, hide mobile counter
84
+ * - Grid + mobile mode: show mobile counter, hide desktop counter
85
+ */
86
+ _updateProductsInRowVisibility() {
87
+ const r = (s.getConfig(this.currentNode).layout || I(this.currentNode)) === "grid", n = this._isMobileMode();
88
+ this.api.setVisibility(e.PRODUCT_IN_ROW, r && !n), this.api.setVisibility(e.PRODUCT_IN_ROW_LABEL, r && !n), this.api.setVisibility(e.MOBILE_CARDS_IN_ROW, r && n), this.api.setVisibility(e.MOBILE_CARDS_IN_ROW_LABEL, r && n);
89
+ }
90
+ /**
91
+ * Subscribes to editor preview mode changes via Stripo API.
92
+ * When the user switches between desktop/mobile preview, toggles
93
+ * which "Products in One Row" counter is visible.
94
+ */
95
+ _subscribeToEditorModeChanges() {
96
+ this.api.onEditorStatePropUpdated(
97
+ u.previewDeviceMode,
98
+ () => {
99
+ this._updateProductsInRowVisibility();
100
+ }
101
+ );
102
+ }
103
+ _onProductCountChange(t) {
104
+ this.currentNode && (s.updateConfig(
105
+ this.api,
106
+ this.currentNode,
107
+ { size: t },
108
+ `Changed product count to ${t}`
109
+ ), this.store.patchCurrentBlockConfig({ size: t }), this._debouncedRegenerateProductRows());
110
+ }
111
+ _onProductsInRowChange(t) {
112
+ this.currentNode && (s.updateConfig(
113
+ this.api,
114
+ this.currentNode,
115
+ { cardsInRow: t },
116
+ `Changed products per row to ${t}`
117
+ ), this.store.patchCurrentBlockConfig({ cardsInRow: t }), this._debouncedRegenerateProductRows());
118
+ }
119
+ _onMobileCardsInRowChange(t) {
120
+ this.currentNode && (s.updateConfig(
121
+ this.api,
122
+ this.currentNode,
123
+ { mobileCardsInRow: t },
124
+ `Changed mobile products per row to ${t}`
125
+ ), O(this.api), g({
126
+ currentNode: this.currentNode,
127
+ documentModifier: this.api.getDocumentModifier()
128
+ }));
129
+ }
130
+ _regenerateProductRows() {
131
+ b({
132
+ currentNode: this.currentNode,
133
+ documentModifier: this.api.getDocumentModifier()
134
+ });
135
+ }
136
+ _listenToFormUpdates() {
137
+ this.api.onValueChanged(e.PRODUCT_COUNT, (t) => {
138
+ this._onProductCountChange(t.toString());
139
+ }), this.api.onValueChanged(e.PRODUCT_IN_ROW, (t) => {
140
+ this._onProductsInRowChange(Number(t));
141
+ }), this.api.onValueChanged(e.MOBILE_CARDS_IN_ROW, (t) => {
142
+ this._onMobileCardsInRowChange(Number(t));
143
+ });
144
+ }
145
+ /**
146
+ * Subscribe to store changes to update visibility when layout changes
147
+ * This is still needed because layout changes come from LayoutControl
148
+ */
149
+ _listenStateUpdates() {
150
+ let t = this.store.recommendationConfigs.orientation;
151
+ this.storeUnsubscription = this.store.$subscribe(() => {
152
+ const a = this.store.recommendationConfigs.orientation;
153
+ a !== t && (t = a, this._updateProductsInRowVisibility());
154
+ });
155
+ }
156
+ }
157
+ export {
158
+ P as PRODUCT_LAYOUT_CONTROL_ID,
159
+ S as ProductLayoutControl
160
+ };
@@ -0,0 +1,67 @@
1
+ var r = Object.defineProperty;
2
+ var u = (o, t, e) => t in o ? r(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
3
+ var n = (o, t, e) => u(o, typeof t != "symbol" ? t + "" : t, e);
4
+ import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as f } from "../../../common-control.js";
6
+ import { RecommendationConfigService as i } from "../../services/configService.js";
7
+ import { useRecommendationExtensionStore as d } from "../../store/recommendation.js";
8
+ const h = "recommendation-shuffle-control", s = {
9
+ SHUFFLE_PRODUCTS: "shuffleProducts"
10
+ };
11
+ class g extends f {
12
+ constructor() {
13
+ super(...arguments);
14
+ // Store is used for backward compatibility with product fetching
15
+ n(this, "store", d());
16
+ }
17
+ getId() {
18
+ return h;
19
+ }
20
+ getTemplate() {
21
+ return `
22
+ <div class="shuffle-control-container">
23
+ ${this._GuTwoColumns([
24
+ this._GuLabel({ text: "Shuffle Recommended Products" }),
25
+ this._GuToggle(s.SHUFFLE_PRODUCTS)
26
+ ])}
27
+ </div>
28
+ `;
29
+ }
30
+ onRender() {
31
+ this._initializeToggle(), this._setFormValues(), this._listenToFormUpdates();
32
+ }
33
+ onTemplateNodeUpdated(e) {
34
+ super.onTemplateNodeUpdated(e), this._setFormValues();
35
+ }
36
+ _setFormValues() {
37
+ const e = i.getConfig(this.currentNode);
38
+ this.api.updateValues({
39
+ [s.SHUFFLE_PRODUCTS]: e.shuffleProducts
40
+ });
41
+ }
42
+ _initializeToggle() {
43
+ const e = i.getConfig(this.currentNode);
44
+ this.api.setUIEAttribute(
45
+ s.SHUFFLE_PRODUCTS,
46
+ l.SELECTPICKER.items,
47
+ e.shuffleProducts
48
+ );
49
+ }
50
+ _onShuffleChange(e) {
51
+ this.currentNode && (i.updateConfig(
52
+ this.api,
53
+ this.currentNode,
54
+ { shuffleProducts: e },
55
+ `${e ? "Enabled" : "Disabled"} product shuffle`
56
+ ), this.store.patchCurrentBlockConfig({ shuffleProducts: e }));
57
+ }
58
+ _listenToFormUpdates() {
59
+ this.api.onValueChanged(s.SHUFFLE_PRODUCTS, (e) => {
60
+ this._onShuffleChange(!!e);
61
+ });
62
+ }
63
+ }
64
+ export {
65
+ h as SHUFFLE_CONTROL_ID,
66
+ g as ShuffleControl
67
+ };