@useinsider/guido 3.6.1-beta.03230b7 → 3.7.0-beta.509616e

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 (46) hide show
  1. package/README.md +14 -0
  2. package/dist/components/Guido.vue.js +1 -1
  3. package/dist/components/Guido.vue2.js +75 -72
  4. package/dist/components/organisms/header/EditorActions.vue.js +1 -1
  5. package/dist/components/organisms/header/EditorActions.vue2.js +6 -6
  6. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  7. package/dist/components/organisms/header/LeftSlot.vue2.js +9 -9
  8. package/dist/composables/useActionsApi.js +16 -15
  9. package/dist/composables/useHtmlCompiler.js +40 -22
  10. package/dist/composables/useRecommendation.js +34 -33
  11. package/dist/enums/toaster.js +1 -1
  12. package/dist/extensions/Blocks/Recommendation/block.js +35 -16
  13. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +127 -123
  14. package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +12 -11
  15. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +46 -46
  16. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +13 -9
  17. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +35 -29
  18. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +28 -28
  19. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +8 -8
  20. package/dist/extensions/Blocks/Recommendation/templates/utils.js +56 -49
  21. package/dist/extensions/Blocks/Recommendation/useRecommendationBlockWarning.js +16 -0
  22. package/dist/extensions/Blocks/Recommendation/utils/partnerCustomizations.js +21 -0
  23. package/dist/extensions/Blocks/Recommendation/utils/priceFormatter.js +17 -17
  24. package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +9 -0
  25. package/dist/guido.css +1 -1
  26. package/dist/src/components/Guido.vue.d.ts +1 -0
  27. package/dist/src/composables/useHtmlCompiler.d.ts +1 -0
  28. package/dist/src/enums/toaster.d.ts +2 -1
  29. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +13 -0
  30. package/dist/src/extensions/Blocks/Recommendation/block.test.d.ts +1 -0
  31. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +7 -0
  32. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
  33. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +8 -0
  34. package/dist/src/extensions/Blocks/Recommendation/templates/utils.test.d.ts +1 -0
  35. package/dist/src/extensions/Blocks/Recommendation/useRecommendationBlockWarning.d.ts +12 -0
  36. package/dist/src/extensions/Blocks/Recommendation/utils/partnerCustomizations.d.ts +7 -0
  37. package/dist/src/extensions/Blocks/Recommendation/utils/priceFormatter.test.d.ts +1 -0
  38. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +28 -0
  39. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.test.d.ts +1 -0
  40. package/dist/src/utils/ampErrorFilter.d.ts +2 -0
  41. package/dist/src/utils/ampErrorFilter.test.d.ts +1 -0
  42. package/dist/src/utils/templatePreparation.d.ts +16 -0
  43. package/dist/src/utils/templatePreparation.test.d.ts +1 -0
  44. package/dist/utils/ampErrorFilter.js +8 -0
  45. package/dist/utils/templatePreparation.js +59 -58
  46. package/package.json +1 -1
@@ -1,17 +1,18 @@
1
1
  var k = Object.defineProperty;
2
- var y = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
- var d = (a, r, t) => y(a, typeof r != "symbol" ? r + "" : r, t);
4
- import { BlockId as B } from "../../../enums/block.js";
5
- import { getMigrationBannerHtml as D } from "../../../utils/migrationBannerHtml.js";
6
- import { Block as R, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ var B = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
+ var d = (a, r, t) => B(a, typeof r != "symbol" ? r + "" : r, t);
4
+ import { BlockId as R } from "../../../enums/block.js";
5
+ import { getMigrationBannerHtml as y } from "../../../utils/migrationBannerHtml.js";
6
+ import { Block as D, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
7
  import { regenerateMobileProductRows as b } from "./controls/main/utils.js";
8
8
  import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as A } from "./controls/mobileLayout/cssRules.js";
9
9
  import { RecommendationConfigService as c } from "./services/configService.js";
10
10
  import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
11
11
  import { getDefaultTemplate as E } from "./templates/grid/template.js";
12
- const _ = B.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
13
- let I = !1;
14
- class q extends R {
12
+ import { useRecommendationBlockWarning as M } from "./useRecommendationBlockWarning.js";
13
+ const I = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
14
+ let _ = !1;
15
+ class H extends D {
15
16
  constructor() {
16
17
  super();
17
18
  /**
@@ -21,7 +22,7 @@ class q extends R {
21
22
  d(this, "_pendingBlockId", null);
22
23
  }
23
24
  getId() {
24
- return _;
25
+ return I;
25
26
  }
26
27
  getIcon() {
27
28
  return "recommendation-icon";
@@ -38,8 +39,8 @@ class q extends R {
38
39
  );
39
40
  }
40
41
  getSettingsPanelTitleHtml() {
41
- return D(
42
- _,
42
+ return y(
43
+ I,
43
44
  this.api.translate("Recommendation Block"),
44
45
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
45
46
  );
@@ -95,7 +96,7 @@ class q extends R {
95
96
  documentModifier: this.api.getDocumentModifier()
96
97
  }));
97
98
  }
98
- s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
99
+ s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
99
100
  }
100
101
  /**
101
102
  * Called when the document changes or template is loaded
@@ -117,7 +118,7 @@ class q extends R {
117
118
  }
118
119
  this._healLingeringDuplicate(t), c.needsMigration(t) && this._migrateFromLegacy(t);
119
120
  try {
120
- I || (p(this.api), I = !0);
121
+ _ || (p(this.api), _ = !0);
121
122
  const e = c.getConfig(t), i = this._getBlockElement(t);
122
123
  if (i) {
123
124
  const n = !e.mobileLayoutEnabled;
@@ -137,6 +138,24 @@ class q extends R {
137
138
  const e = this._getRecommendationId(t);
138
139
  e && g().removeBlockState(e);
139
140
  }
141
+ /**
142
+ * Warns (dark advisory toaster) when the design holds more than one live
143
+ * recommendation block. Triggered from the user-add paths only (fresh drop
144
+ * and duplicate) — never from document-load/migration, so opening a template
145
+ * that already has multiple blocks does not fire it. `onCreated` also runs
146
+ * for a reco block that arrives inside a saved structure (SD-143028), so this
147
+ * covers that case too — no separate `module_dropped` handling is needed.
148
+ *
149
+ * Counting lives in `useRecommendationBlockWarning`, whose DOM-based logic
150
+ * ignores the empty shells deletions leave behind (SD-143028). Wrapped in
151
+ * try/catch because the document root may be unavailable during initial load.
152
+ */
153
+ _warnIfMultipleBlocks() {
154
+ try {
155
+ M().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
156
+ } catch {
157
+ }
158
+ }
140
159
  /**
141
160
  * Generates the next unique recommendation ID by scanning all existing blocks
142
161
  * in the document and finding the maximum existing ID + 1.
@@ -209,7 +228,7 @@ class q extends R {
209
228
  /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
210
229
  _handleDuplicate(t, e) {
211
230
  const i = this._reassignDuplicateId(t, e), n = g();
212
- n.cloneBlockState(e, i), n.setCurrentBlock(i);
231
+ n.cloneBlockState(e, i), n.setCurrentBlock(i), this._warnIfMultipleBlocks();
213
232
  }
214
233
  /**
215
234
  * Core id-reassignment for a duplicated block: rewrites the DOM
@@ -291,6 +310,6 @@ class q extends R {
291
310
  }
292
311
  }
293
312
  export {
294
- _ as BLOCK_ID,
295
- q as RecommendationBlock
313
+ I as BLOCK_ID,
314
+ H as RecommendationBlock
296
315
  };
@@ -1,42 +1,42 @@
1
- var X = Object.defineProperty;
2
- var J = (p, _, t) => _ in p ? X(p, _, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[_] = t;
3
- var C = (p, _, t) => J(p, typeof _ != "symbol" ? _ + "" : _, t);
4
- import { UIElementType as f, UEAttr as $, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as Q } from "../../../common-control.js";
6
- import { ATTR_PRODUCT_IMAGE as L, ATTR_PRODUCT_NAME as Z, ATTR_PRODUCT_PRICE as tt, ATTR_PRODUCT_OLD_PRICE as et, ATTR_PRODUCT_OMNIBUS_PRICE as rt, ATTR_PRODUCT_OMNIBUS_DISCOUNT as ot, ATTR_PRODUCT_BUTTON as D, ATTR_DATA_CUSTOM_ATTRIBUTES as k, ATTR_CUSTOM_PREFIX as m, BUILT_IN_DEFAULT_ATTRIBUTES as st } from "../../constants/selectors.js";
7
- import { DEFAULT_COMPOSITION as q, DEFAULT_VISIBILITY as P } from "../../constants/defaultConfig.js";
8
- import { RecommendationConfigService as it } from "../../services/configService.js";
9
- import { useRecommendationExtensionStore as nt } from "../../store/recommendation.js";
10
- import { ATTRIBUTE_CELL_CLASS as lt, gridElementRenderer as at, DEFAULT_CELL_PADDING as ct } from "../../templates/grid/elementRenderer.js";
11
- import { listElementRenderer as ut } from "../../templates/list/elementRenderer.js";
12
- import { toDisplayName as dt, isDefaultAttribute as mt, buildElementRenderer as F } from "../../templates/utils.js";
13
- import { getTableDisplayValue as ht } from "../../utils/tagName.js";
14
- import { getCurrentLayout as pt } from "../main/utils.js";
15
- const _t = "ui-elements-recommendation-card-composition", S = ".recommendation-attribute-row", N = ".product-card-wrapper > tbody", w = ".product-info-cell > table > tbody", M = "data-card-composition", y = "data-attribute-type", I = "data-visibility", x = {
1
+ var J = Object.defineProperty;
2
+ var Q = (p, _, t) => _ in p ? J(p, _, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[_] = t;
3
+ var S = (p, _, t) => Q(p, typeof _ != "symbol" ? _ + "" : _, t);
4
+ import { UIElementType as f, UEAttr as I, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as Z } from "../../../common-control.js";
6
+ import { ATTR_PRODUCT_IMAGE as D, ATTR_PRODUCT_NAME as tt, ATTR_PRODUCT_PRICE as et, ATTR_PRODUCT_OLD_PRICE as rt, ATTR_PRODUCT_OMNIBUS_PRICE as ot, ATTR_PRODUCT_OMNIBUS_DISCOUNT as st, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as q, ATTR_CUSTOM_PREFIX as m, BUILT_IN_DEFAULT_ATTRIBUTES as it } from "../../constants/selectors.js";
7
+ import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as F } from "../../constants/defaultConfig.js";
8
+ import { RecommendationConfigService as nt } from "../../services/configService.js";
9
+ import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
10
+ import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as ut, buildFillerCell as dt } from "../../templates/grid/elementRenderer.js";
11
+ import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
12
+ import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as _t, buildElementRenderer as w } from "../../templates/utils.js";
13
+ import { getTableDisplayValue as ft } from "../../utils/tagName.js";
14
+ import { getCurrentLayout as gt } from "../main/utils.js";
15
+ const bt = "ui-elements-recommendation-card-composition", C = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", M = ".product-info-cell > table > tbody", V = "data-card-composition", y = "data-attribute-type", v = "data-visibility", x = {
16
16
  ADD_ATTRIBUTE: "addAttribute"
17
- }, g = 5, v = "reorderIcon_", h = [
18
- { key: L, label: "Product Image" },
19
- { key: Z, label: "Product Name" },
20
- { key: tt, label: "Product Price" },
21
- { key: et, label: "Product Original Price" },
22
- { key: rt, label: "Omnibus Price" },
23
- { key: ot, label: "Omnibus Discount" },
24
- { key: D, label: "Product Button" }
25
- ], ft = new Set(h.map((p) => p.key)), T = "customAttr_", E = "deleteAttr_";
26
- class Nt extends Q {
17
+ }, g = 5, E = "reorderIcon_", h = [
18
+ { key: D, label: "Product Image" },
19
+ { key: tt, label: "Product Name" },
20
+ { key: et, label: "Product Price" },
21
+ { key: rt, label: "Product Original Price" },
22
+ { key: ot, label: "Omnibus Price" },
23
+ { key: st, label: "Omnibus Discount" },
24
+ { key: U, label: "Product Button" }
25
+ ], yt = new Set(h.map((p) => p.key)), T = "customAttr_", R = "deleteAttr_";
26
+ class Ut extends Z {
27
27
  constructor() {
28
28
  super(...arguments);
29
- C(this, "store", nt());
30
- C(this, "unsubscribeStore", null);
31
- C(this, "eventController", null);
29
+ S(this, "store", lt());
30
+ S(this, "unsubscribeStore", null);
31
+ S(this, "eventController", null);
32
32
  /**
33
33
  * Guard flag: when true, onTemplateNodeUpdated skips _initializeComposition.
34
34
  * Used during _onReorder to prevent multiple intermediate rebuilds.
35
35
  */
36
- C(this, "reorderInProgress", !1);
36
+ S(this, "reorderInProgress", !1);
37
37
  }
38
38
  getId() {
39
- return _t;
39
+ return bt;
40
40
  }
41
41
  // ========================================================================
42
42
  // Lifecycle
@@ -60,10 +60,10 @@ class Nt extends Q {
60
60
  ).join(""), e = h.length + g, o = Array.from(
61
61
  { length: e },
62
62
  (l, u) => `
63
- <div data-reorder-icon-key="${v}${u}" style="display: none;">
63
+ <div data-reorder-icon-key="${E}${u}" style="display: none;">
64
64
  <${f.BUTTON}
65
65
  class="drag-handle-btn flat-inline flat-white"
66
- ${$.BUTTON.name}="${v}${u}"
66
+ ${I.BUTTON.name}="${E}${u}"
67
67
  >
68
68
  <${f.ICON}
69
69
  src="reorder"
@@ -75,10 +75,10 @@ class Nt extends Q {
75
75
  ).join(""), s = Array.from(
76
76
  { length: g },
77
77
  (l, u) => `
78
- <div data-custom-delete-key="${E}${u}" style="display: none;">
78
+ <div data-custom-delete-key="${R}${u}" style="display: none;">
79
79
  <${f.BUTTON}
80
80
  class="custom-attr-delete flat-inline flat-white"
81
- ${$.BUTTON.name}="${E}${u}"
81
+ ${I.BUTTON.name}="${R}${u}"
82
82
  >
83
83
  <${f.ICON}
84
84
  src="delete"
@@ -89,15 +89,15 @@ class Nt extends Q {
89
89
  `
90
90
  ).join(""), i = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
91
91
  "Drag and drop the card elements to reorder them, adjust their visibility or add new attributes up to 5."
92
- ), c = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
92
+ ), a = this.api.translate("For more information, you can"), c = this.api.translate("visit Academy");
93
93
  return `
94
94
  <div class="recommendation-controls-container" data-card-composition-control>
95
95
  <div class="container">
96
96
  <p class="card-composition-description">
97
97
  ${n}
98
- ${c}
98
+ ${a}
99
99
  <!-- cspell:disable-next-line -->
100
- <a href="${i}" target="_blank" rel="noopener noreferrer">${a}</a>.
100
+ <a href="${i}" target="_blank" rel="noopener noreferrer">${c}</a>.
101
101
  </p>
102
102
  </div>
103
103
 
@@ -161,14 +161,14 @@ class Nt extends Q {
161
161
  // ========================================================================
162
162
  _readCompositionFromNode() {
163
163
  if (!this.currentNode || !("getAttribute" in this.currentNode))
164
- return [...q];
165
- const t = this.currentNode.getAttribute(M);
166
- return t ? t.split(",").filter(Boolean) : [...q];
164
+ return [...P];
165
+ const t = this.currentNode.getAttribute(V);
166
+ return t ? t.split(",").filter(Boolean) : [...P];
167
167
  }
168
168
  _readCustomAttributesFromNode() {
169
169
  if (!this.currentNode || !("getAttribute" in this.currentNode))
170
170
  return [];
171
- const t = this.currentNode.getAttribute(k);
171
+ const t = this.currentNode.getAttribute(q);
172
172
  if (!t)
173
173
  return [];
174
174
  try {
@@ -180,18 +180,18 @@ class Nt extends Q {
180
180
  _readVisibilityFromRows() {
181
181
  if (!this.currentNode)
182
182
  return this._getDefaultVisibilities();
183
- const t = Array.from(this.currentNode.querySelectorAll(S)), r = this._extractVisibilityFromRows(t);
183
+ const t = Array.from(this.currentNode.querySelectorAll(C)), r = this._extractVisibilityFromRows(t);
184
184
  return this._mergeWithDefaults(r);
185
185
  }
186
186
  _getDefaultVisibilities() {
187
- return { ...P };
187
+ return { ...F };
188
188
  }
189
189
  _extractVisibilityFromRows(t) {
190
190
  const r = {};
191
191
  return t.forEach((e) => {
192
192
  if (!("getAttribute" in e))
193
193
  return;
194
- const o = e.getAttribute(y), s = e.getAttribute(I);
194
+ const o = e.getAttribute(y), s = e.getAttribute(v);
195
195
  o && s !== null && (r[o] = this._parseVisibilityValue(s));
196
196
  }), r;
197
197
  }
@@ -199,7 +199,7 @@ class Nt extends Q {
199
199
  return t === "1" || t === "true";
200
200
  }
201
201
  _mergeWithDefaults(t) {
202
- return Object.entries(P).forEach(([r, e]) => {
202
+ return Object.entries(F).forEach(([r, e]) => {
203
203
  r in t || (t[r] = e);
204
204
  }), t;
205
205
  }
@@ -223,19 +223,19 @@ class Nt extends Q {
223
223
  return !1;
224
224
  const s = new Set(r);
225
225
  let i = 0, n = 0;
226
- const c = t.map((a) => {
227
- if (ft.has(a)) {
228
- const l = h.find((u) => u.key === a);
226
+ const a = t.map((c) => {
227
+ if (yt.has(c)) {
228
+ const l = h.find((u) => u.key === c);
229
229
  return this._createBuiltInItemHtml(l, n++);
230
230
  }
231
- if (a.startsWith(m)) {
232
- const l = a.substring(m.length);
231
+ if (c.startsWith(m)) {
232
+ const l = c.substring(m.length);
233
233
  if (s.has(l))
234
- return this._createCustomItemHtml(a, i++, n++);
234
+ return this._createCustomItemHtml(c, i++, n++);
235
235
  }
236
236
  return "";
237
237
  }).join("");
238
- return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = c, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
238
+ return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = a, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
239
239
  }
240
240
  /**
241
241
  * Attempts to reorder existing orderable-item elements to match the composition order.
@@ -247,27 +247,27 @@ class Nt extends Q {
247
247
  const e = Array.from(t.querySelectorAll(".orderable-item"));
248
248
  if (e.length !== r.length)
249
249
  return !1;
250
- const o = e.map((a) => a.dataset.key).filter(Boolean);
250
+ const o = e.map((c) => c.dataset.key).filter(Boolean);
251
251
  if (o.length !== r.length)
252
252
  return !1;
253
253
  const s = [...o].sort().join(","), i = [...r].sort().join(",");
254
- if (s !== i || r.some((a) => a.startsWith(m)))
254
+ if (s !== i || r.some((c) => c.startsWith(m)))
255
255
  return !1;
256
256
  const n = /* @__PURE__ */ new Map();
257
- e.forEach((a) => {
258
- const { key: l } = a.dataset;
257
+ e.forEach((c) => {
258
+ const { key: l } = c.dataset;
259
259
  if (l) {
260
260
  const u = n.get(l) || [];
261
- u.push(a), n.set(l, u);
261
+ u.push(c), n.set(l, u);
262
262
  }
263
263
  });
264
- const c = /* @__PURE__ */ new Map();
265
- return r.forEach((a) => {
266
- const l = n.get(a);
264
+ const a = /* @__PURE__ */ new Map();
265
+ return r.forEach((c) => {
266
+ const l = n.get(c);
267
267
  if (!l)
268
268
  return;
269
- const u = c.get(a) || 0;
270
- c.set(a, u + 1), l[u] && t.appendChild(l[u]);
269
+ const u = a.get(c) || 0;
270
+ a.set(c, u + 1), l[u] && t.appendChild(l[u]);
271
271
  }), !0;
272
272
  }
273
273
  _createBuiltInItemHtml(t, r) {
@@ -316,7 +316,7 @@ class Nt extends Q {
316
316
  t.length !== 0 && setTimeout(() => {
317
317
  t.forEach((r, e) => {
318
318
  const o = `${T}${e}`, s = this._getSelectOptions(r, t);
319
- this.api.setUIEAttribute(o, $.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
319
+ this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
320
320
  });
321
321
  }, 0);
322
322
  }
@@ -380,7 +380,7 @@ class Nt extends Q {
380
380
  */
381
381
  _moveDeleteButtonsIntoItems(t, r) {
382
382
  for (let e = 0; e < r; e++) {
383
- const o = `${E}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
383
+ const o = `${R}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
384
384
  if (s && i) {
385
385
  const n = s.querySelector("ue-button");
386
386
  n && i.appendChild(n);
@@ -393,7 +393,7 @@ class Nt extends Q {
393
393
  */
394
394
  _rescueDeleteButtonsToStore(t) {
395
395
  for (let r = 0; r < g; r++) {
396
- const e = `${E}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
396
+ const e = `${R}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
397
397
  if (s) {
398
398
  const i = s.querySelector("ue-button");
399
399
  i && o && o.appendChild(i);
@@ -406,7 +406,7 @@ class Nt extends Q {
406
406
  */
407
407
  _moveReorderIconsIntoItems(t, r) {
408
408
  for (let e = 0; e < r; e++) {
409
- const o = `${v}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
409
+ const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
410
410
  if (s && i) {
411
411
  const n = s.querySelector("ue-button");
412
412
  n && i.appendChild(n);
@@ -420,7 +420,7 @@ class Nt extends Q {
420
420
  _rescueReorderIconsToStore(t) {
421
421
  const r = h.length + g;
422
422
  for (let e = 0; e < r; e++) {
423
- const o = `${v}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
423
+ const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
424
424
  if (i) {
425
425
  const n = i.querySelector("ue-button");
426
426
  n && s && s.appendChild(n);
@@ -444,22 +444,22 @@ class Nt extends Q {
444
444
  _setupDragAndDrop(t, r) {
445
445
  let e = null, o = null;
446
446
  t.addEventListener("dragstart", (s) => {
447
- var c;
447
+ var a;
448
448
  const n = s.target.closest(".orderable-item");
449
- n && (e = n, n.classList.add("dragging"), (c = s.dataTransfer) == null || c.setData("text/plain", n.dataset.key || ""));
449
+ n && (e = n, n.classList.add("dragging"), (a = s.dataTransfer) == null || a.setData("text/plain", n.dataset.key || ""));
450
450
  }, { signal: r }), t.addEventListener("dragend", () => {
451
451
  e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
452
452
  }, { signal: r }), t.addEventListener("dragover", (s) => {
453
453
  s.preventDefault();
454
- const n = s.target.closest(".orderable-item"), c = n && n !== e ? n : null;
455
- c !== o && (o == null || o.classList.remove("drag-over"), o = c, o == null || o.classList.add("drag-over"));
454
+ const n = s.target.closest(".orderable-item"), a = n && n !== e ? n : null;
455
+ a !== o && (o == null || o.classList.remove("drag-over"), o = a, o == null || o.classList.add("drag-over"));
456
456
  }, { signal: r }), t.addEventListener("drop", (s) => {
457
457
  s.preventDefault();
458
458
  const n = s.target.closest(".orderable-item");
459
459
  if (!n || !e || n === e)
460
460
  return;
461
- const c = n.getBoundingClientRect(), a = c.top + c.height / 2;
462
- s.clientY < a ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
461
+ const a = n.getBoundingClientRect(), c = a.top + a.height / 2;
462
+ s.clientY < c ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
463
463
  const u = t.querySelectorAll(".orderable-item"), d = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
464
464
  this._onReorder(d), e = null;
465
465
  }, { signal: r });
@@ -490,7 +490,7 @@ class Nt extends Q {
490
490
  const r = this._readCustomAttributesFromNode();
491
491
  if (r[t] === void 0)
492
492
  return;
493
- const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((c, a) => a !== s), n = r.filter((c, a) => a !== t);
493
+ const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((a, c) => c !== s), n = r.filter((a, c) => c !== t);
494
494
  this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
495
495
  }
496
496
  /**
@@ -503,8 +503,8 @@ class Nt extends Q {
503
503
  return;
504
504
  const s = `${m}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
505
505
  n !== -1 && (i[n] = s), e[t] = r;
506
- const c = this._getDisplayNameForAttribute(r);
507
- this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, c, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
506
+ const a = this._getDisplayNameForAttribute(r);
507
+ this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, a, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
508
508
  }
509
509
  _onReorder(t) {
510
510
  const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
@@ -525,56 +525,60 @@ class Nt extends Q {
525
525
  this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
526
526
  }
527
527
  _injectGridAttributeRow(t, r, e, o) {
528
- const s = this.currentNode.querySelectorAll(N);
528
+ const s = this.currentNode.querySelectorAll(L);
529
529
  if (!(s != null && s.length))
530
530
  return;
531
- const i = it.getConfig(this.currentNode), c = `0 ${Math.floor(i.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
531
+ const i = nt.getConfig(this.currentNode), a = `0 ${Math.floor(i.columnSpacing / 2)}px`, c = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
532
532
  let u = 0;
533
533
  s.forEach((d) => {
534
- var U;
535
- const b = d.querySelector(S), R = ((U = b == null ? void 0 : b.querySelectorAll(`.${lt}`)) == null ? void 0 : U.length) || 1, V = (100 / R).toFixed(2), { bgStyle: j, bgAttr: W } = this._extractSegmentBgFromCard(d), K = o.map((B) => {
536
- if (B === e) {
534
+ var H;
535
+ const b = d.querySelector(C), $ = ((H = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : H.length) || 1, B = (100 / $).toFixed(2), { bgStyle: j, bgAttr: W } = this._extractSegmentBgFromCard(d), O = l > 0 ? Math.min($, l - u) : $, K = o.map((k) => {
536
+ if (k === e) {
537
537
  const z = Array.from(
538
- { length: R },
539
- (gt, H) => {
540
- const G = l > 0 ? (u + H) % l : H, Y = this._resolveAttributeContent(t, r, G);
538
+ { length: O },
539
+ (At, Y) => {
540
+ const X = this._resolveAttributeContent(
541
+ t,
542
+ r,
543
+ u + Y
544
+ );
541
545
  return this._getGridCellHtml(
542
546
  t,
543
- Y,
544
- V,
547
+ X,
548
+ B,
545
549
  j,
546
550
  W,
547
- c
551
+ a
548
552
  );
549
553
  }
550
- ).join("");
551
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${I}="1">${z}</tr>`;
554
+ ).join(""), G = dt(B, a).repeat($ - O);
555
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${z}${G}</tr>`;
552
556
  }
553
- const O = d.querySelector(
554
- `${S}[${y}="${B}"]`
557
+ const N = d.querySelector(
558
+ `${C}[${y}="${k}"]`
555
559
  );
556
- return O && "getOuterHTML" in O ? O.getOuterHTML() : "";
560
+ return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
557
561
  }).join("");
558
- u += R, l > 0 && u >= l && (u = 0), a.modifyHtml(d).setInnerHtml(K);
559
- }), a.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
562
+ u += O, l > 0 && u >= l && (u = 0), c.modifyHtml(d).setInnerHtml(K);
563
+ }), c.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
560
564
  }
561
565
  _injectListAttributeRow(t, r, e, o) {
562
- const s = this.currentNode.querySelectorAll(w);
566
+ const s = this.currentNode.querySelectorAll(M);
563
567
  if (!(s != null && s.length))
564
568
  return;
565
- const i = o.filter((c) => c !== L && c !== D), n = this.api.getDocumentModifier();
566
- s.forEach((c, a) => {
569
+ const i = o.filter((a) => a !== D && a !== U), n = this.api.getDocumentModifier();
570
+ s.forEach((a, c) => {
567
571
  const l = i.map((u) => {
568
572
  if (u === e) {
569
- const b = this._resolveAttributeContent(t, r, a);
573
+ const b = this._resolveAttributeContent(t, r, c);
570
574
  return this._getListRowHtml(t, b, e);
571
575
  }
572
- const d = c.querySelector(
573
- `${S}[${y}="${u}"]`
576
+ const d = a.querySelector(
577
+ `${C}[${y}="${u}"]`
574
578
  );
575
579
  return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
576
580
  }).join("");
577
- n.modifyHtml(c).setInnerHtml(l);
581
+ n.modifyHtml(a).setInnerHtml(l);
578
582
  }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
579
583
  }
580
584
  /**
@@ -586,13 +590,13 @@ class Nt extends Q {
586
590
  return;
587
591
  const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
588
592
  if (r === "grid") {
589
- const o = this.currentNode.querySelectorAll(N);
593
+ const o = this.currentNode.querySelectorAll(L);
590
594
  o == null || o.forEach((s) => {
591
595
  const i = this._buildCompositionHtml(s, t);
592
596
  e.modifyHtml(s).setInnerHtml(i);
593
597
  });
594
598
  } else {
595
- const o = t.filter((i) => i !== L && i !== D), s = this.currentNode.querySelectorAll(w);
599
+ const o = t.filter((i) => i !== D && i !== U), s = this.currentNode.querySelectorAll(M);
596
600
  s == null || s.forEach((i) => {
597
601
  const n = this._buildCompositionHtml(i, o);
598
602
  e.modifyHtml(i).setInnerHtml(n);
@@ -611,7 +615,7 @@ class Nt extends Q {
611
615
  * producing a flicker on the custom attribute dropdowns.
612
616
  */
613
617
  _updateBothAttributes(t, r) {
614
- this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(M, t.join(",")).setAttribute(k, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
618
+ this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(V, t.join(",")).setAttribute(q, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
615
619
  }
616
620
  /**
617
621
  * Reorders attribute rows within each product card based on composition order.
@@ -620,7 +624,7 @@ class Nt extends Q {
620
624
  _reorderProductAttributes(t) {
621
625
  if (!this.currentNode)
622
626
  return;
623
- const r = this.currentNode.querySelectorAll(N);
627
+ const r = this.currentNode.querySelectorAll(L);
624
628
  if (!(r != null && r.length))
625
629
  return;
626
630
  const e = this.api.getDocumentModifier();
@@ -635,7 +639,7 @@ class Nt extends Q {
635
639
  */
636
640
  _buildCompositionHtml(t, r) {
637
641
  return r.reduce((e, o) => {
638
- const s = t.querySelector(`${S}[${y}="${o}"]`);
642
+ const s = t.querySelector(`${C}[${y}="${o}"]`);
639
643
  return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
640
644
  }, "");
641
645
  }
@@ -645,13 +649,13 @@ class Nt extends Q {
645
649
  _applyVisibilityToBlock(t, r) {
646
650
  if (!this.currentNode)
647
651
  return;
648
- const e = this.currentNode.querySelectorAll(`${S}[${y}="${t}"]`);
652
+ const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
649
653
  if (!(e != null && e.length))
650
654
  return;
651
655
  const o = r ? "1" : "0", s = r ? this.api.translate("visible") : this.api.translate("hidden"), i = `${this.api.translate("Set visibility")}: ${t} → ${s}`, n = this.api.getDocumentModifier();
652
- e.forEach((c) => {
653
- const a = ht(c), l = r ? a : "none";
654
- n.modifyHtml(c).setStyle("display", l).setAttribute(I, o);
656
+ e.forEach((a) => {
657
+ const c = ft(a), l = r ? c : "none";
658
+ n.modifyHtml(a).setStyle("display", l).setAttribute(v, o);
655
659
  }), n.apply(new A(i));
656
660
  }
657
661
  // ========================================================================
@@ -673,7 +677,7 @@ class Nt extends Q {
673
677
  return -1;
674
678
  }
675
679
  _getCurrentLayout() {
676
- return this.store.recommendationConfigs.orientation || pt(this.currentNode);
680
+ return this.store.recommendationConfigs.orientation || gt(this.currentNode);
677
681
  }
678
682
  /**
679
683
  * Extracts background color properties from existing card elements.
@@ -727,7 +731,7 @@ class Nt extends Q {
727
731
  const t = this._readCustomAttributesFromNode(), r = t.length >= g, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
728
732
  this.api.setUIEAttribute(
729
733
  x.ADD_ATTRIBUTE,
730
- $.BUTTON.disabled,
734
+ I.BUTTON.disabled,
731
735
  r || s ? "true" : "false"
732
736
  );
733
737
  }
@@ -750,7 +754,7 @@ class Nt extends Q {
750
754
  * excluding default attributes already covered by built-in toggle items.
751
755
  */
752
756
  _getAddableFilters() {
753
- return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && st.has(t.attributeName)));
757
+ return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && it.has(t.attributeName)));
754
758
  }
755
759
  /**
756
760
  * Looks up the display name for an attribute from the store's filterList.
@@ -758,7 +762,7 @@ class Nt extends Q {
758
762
  */
759
763
  _getDisplayNameForAttribute(t) {
760
764
  const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
761
- return r ? r.displayName : dt(t);
765
+ return r ? r.displayName : ht(t);
762
766
  }
763
767
  /**
764
768
  * Resolves the display content for a custom attribute cell.
@@ -766,29 +770,29 @@ class Nt extends Q {
766
770
  */
767
771
  _resolveAttributeContent(t, r, e) {
768
772
  var n;
769
- const s = this.store.recommendationProducts[e], i = mt(t, this.store.filterList) ? s == null ? void 0 : s[t] : (n = s == null ? void 0 : s.product_attributes) == null ? void 0 : n[t];
770
- return typeof i == "string" ? i : typeof i == "number" ? String(i) : r;
773
+ const s = this.store.recommendationProducts[e], i = pt(t, this.store.filterList) ? s == null ? void 0 : s[t] : (n = s == null ? void 0 : s.product_attributes) == null ? void 0 : n[t];
774
+ return _t(i) ?? r;
771
775
  }
772
776
  _getGridCellHtml(t, r, e, o = "", s = "", i = "") {
773
- const n = `${m}${t}`, c = F(at, [n], this.store.filterList), a = {
777
+ const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
774
778
  [t]: r,
775
779
  product_attributes: { [t]: r }
776
780
  };
777
- let l = c[n](a);
781
+ let l = a[n](c);
778
782
  return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
779
- `padding: ${ct}`,
783
+ `padding: ${ut}`,
780
784
  `padding: ${i}`
781
785
  )), o && (l = l.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), s && (l = l.replace(/border="0"/, `border="0" bgcolor="${s}"`)), l;
782
786
  }
783
787
  _getListRowHtml(t, r, e) {
784
- const o = F(ut, [e], this.store.filterList), s = {
788
+ const o = w(mt, [e], this.store.filterList), s = {
785
789
  [t]: r,
786
790
  product_attributes: { [t]: r }
787
791
  }, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
788
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${I}="1">${n}</tr>`;
792
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
789
793
  }
790
794
  }
791
795
  export {
792
- _t as COMPOSITION_CONTROL_BLOCK_ID,
793
- Nt as RecommendationCardCompositionControl
796
+ bt as COMPOSITION_CONTROL_BLOCK_ID,
797
+ Ut as RecommendationCardCompositionControl
794
798
  };