@useinsider/guido 3.7.2-beta.13c9a35 → 3.7.2-beta.1e8f93e

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 (43) hide show
  1. package/dist/@types/config/schemas.js +66 -70
  2. package/dist/composables/usePreviewMode.js +14 -15
  3. package/dist/config/compiler/utils/recommendationCompilerUtils.js +82 -90
  4. package/dist/config/migrator/recommendation/htmlBuilder.js +58 -59
  5. package/dist/config/migrator/recommendation/settingsMapper.js +33 -38
  6. package/dist/extensions/Blocks/Items/block.js +48 -29
  7. package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +62 -45
  8. package/dist/extensions/Blocks/Recommendation/block.js +41 -60
  9. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +32 -41
  10. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +288 -369
  11. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +84 -96
  12. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +80 -82
  13. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +7 -21
  14. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +4 -64
  15. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +5 -7
  16. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +72 -101
  17. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -31
  18. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -9
  19. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +59 -74
  20. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
  21. package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -88
  22. package/dist/src/@types/config/schemas.d.ts +0 -16
  23. package/dist/src/composables/useConfig.d.ts +0 -4
  24. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
  25. package/dist/src/extensions/Blocks/Items/block.d.ts +8 -0
  26. package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.d.ts +1 -1
  27. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -10
  28. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +3 -29
  29. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
  30. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -3
  31. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -2
  32. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +0 -16
  33. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  34. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +0 -13
  35. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +2 -3
  36. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +1 -33
  37. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -15
  38. package/dist/src/stores/config.d.ts +0 -36
  39. package/package.json +1 -1
  40. package/dist/composables/useRecommendationPreview.js +0 -100
  41. package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +0 -133
  42. package/dist/src/composables/useRecommendationPreview.d.ts +0 -10
  43. package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +0 -59
@@ -1,103 +1,103 @@
1
- var tt = Object.defineProperty;
2
- var et = (g, b, t) => b in g ? tt(g, b, { enumerable: !0, configurable: !0, writable: !0, value: t }) : g[b] = t;
3
- var I = (g, b, t) => et(g, typeof b != "symbol" ? b + "" : b, t);
4
- import { UIElementType as _, UEAttr as E, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as rt } from "../../../common-control.js";
6
- import { ATTR_PRODUCT_IMAGE as k, ATTR_PRODUCT_NAME as ot, ATTR_PRODUCT_PRICE as S, ATTR_PRODUCT_OLD_PRICE as v, ATTR_PRODUCT_OMNIBUS_PRICE as it, ATTR_PRODUCT_OMNIBUS_DISCOUNT as st, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as F, ATTR_CUSTOM_PREFIX as p, BUILT_IN_DEFAULT_ATTRIBUTES as nt } from "../../constants/selectors.js";
7
- import { DEFAULT_COMPOSITION as x, DEFAULT_VISIBILITY as M } from "../../constants/defaultConfig.js";
8
- import { RecommendationConfigService as P } from "../../services/configService.js";
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
9
  import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
10
- import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as dt, buildFillerCell as ut } from "../../templates/grid/elementRenderer.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
11
  import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
12
- import { resolveInlinePriceOrder as ht, toDisplayName as pt, isDefaultAttribute as gt, toDisplayableAttributeValue as bt, buildElementRenderer as V } from "../../templates/utils.js";
13
- import { getTableDisplayValue as _t } from "../../utils/tagName.js";
14
- import { regenerateProductRowsWithStyles as ft, getCurrentLayout as yt } from "../main/utils.js";
15
- const St = "ui-elements-recommendation-card-composition", T = ".recommendation-attribute-row", H = ".product-card-wrapper > tbody", j = ".product-info-cell > table > tbody", W = "data-card-composition", y = "data-attribute-type", O = "data-visibility", K = {
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
- }, f = 5, N = "reorderIcon_", Ct = '<svg width="14" height="10" viewBox="0 0 14 10" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><circle cx="2" cy="2.5" r="1.2"/><circle cx="7" cy="2.5" r="1.2"/><circle cx="12" cy="2.5" r="1.2"/><circle cx="2" cy="7.5" r="1.2"/><circle cx="7" cy="7.5" r="1.2"/><circle cx="12" cy="7.5" r="1.2"/></svg>', m = [
18
- { key: k, label: "Product Image" },
19
- { key: ot, label: "Product Name" },
20
- { key: S, label: "Product Price" },
21
- { key: v, label: "Product Original Price" },
22
- { key: it, label: "Omnibus Price" },
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
23
  { key: st, label: "Omnibus Discount" },
24
24
  { key: U, label: "Product Button" }
25
- ], At = new Set(m.map((g) => g.key)), $ = "customAttr_", R = "deleteAttr_";
26
- class Ut extends rt {
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
- I(this, "store", lt());
30
- I(this, "unsubscribeStore", null);
31
- I(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
- I(this, "reorderInProgress", !1);
36
+ S(this, "reorderInProgress", !1);
37
37
  }
38
38
  getId() {
39
- return St;
39
+ return bt;
40
40
  }
41
41
  // ========================================================================
42
42
  // Lifecycle
43
43
  // ========================================================================
44
44
  getTemplate() {
45
- const t = m.map((a) => `
46
- <div data-toggle-key="${a.key}" style="display: none;">
47
- ${this._GuToggle(`visibility_${a.key}`)}
45
+ const t = h.map((l) => `
46
+ <div data-toggle-key="${l.key}" style="display: none;">
47
+ ${this._GuToggle(`visibility_${l.key}`)}
48
48
  </div>
49
49
  `).join(""), r = Array.from(
50
- { length: f },
51
- (a, d) => `
52
- <div data-custom-select-key="${$}${d}" style="display: none;">
50
+ { length: g },
51
+ (l, u) => `
52
+ <div data-custom-select-key="${T}${u}" style="display: none;">
53
53
  ${this._GuSelect({
54
- name: `${$}${d}`,
54
+ name: `${T}${u}`,
55
55
  placeholder: this.api.translate("Select Attribute"),
56
56
  options: []
57
57
  })}
58
58
  </div>
59
59
  `
60
- ).join(""), e = m.length + f, i = Array.from(
60
+ ).join(""), e = h.length + g, o = Array.from(
61
61
  { length: e },
62
- (a, d) => `
63
- <div data-reorder-icon-key="${N}${d}" style="display: none;">
64
- <${_.BUTTON}
62
+ (l, u) => `
63
+ <div data-reorder-icon-key="${E}${u}" style="display: none;">
64
+ <${f.BUTTON}
65
65
  class="drag-handle-btn flat-inline flat-white"
66
- ${E.BUTTON.name}="${N}${d}"
66
+ ${I.BUTTON.name}="${E}${u}"
67
67
  >
68
- <${_.ICON}
68
+ <${f.ICON}
69
69
  src="reorder"
70
70
  class="icon-button"
71
- ></${_.ICON}>
72
- </${_.BUTTON}>
71
+ ></${f.ICON}>
72
+ </${f.BUTTON}>
73
73
  </div>
74
74
  `
75
- ).join(""), o = Array.from(
76
- { length: f },
77
- (a, d) => `
78
- <div data-custom-delete-key="${R}${d}" style="display: none;">
79
- <${_.BUTTON}
75
+ ).join(""), s = Array.from(
76
+ { length: g },
77
+ (l, u) => `
78
+ <div data-custom-delete-key="${R}${u}" style="display: none;">
79
+ <${f.BUTTON}
80
80
  class="custom-attr-delete flat-inline flat-white"
81
- ${E.BUTTON.name}="${R}${d}"
81
+ ${I.BUTTON.name}="${R}${u}"
82
82
  >
83
- <${_.ICON}
83
+ <${f.ICON}
84
84
  src="delete"
85
85
  class="icon-button"
86
- ></${_.ICON}>
87
- </${_.BUTTON}>
86
+ ></${f.ICON}>
87
+ </${f.BUTTON}>
88
88
  </div>
89
89
  `
90
- ).join(""), s = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
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"), l = 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="${s}" target="_blank" rel="noopener noreferrer">${l}</a>.
100
+ <a href="${i}" target="_blank" rel="noopener noreferrer">${c}</a>.
101
101
  </p>
102
102
  </div>
103
103
 
@@ -110,17 +110,17 @@ class Ut extends rt {
110
110
  </div>
111
111
 
112
112
  <div class="custom-delete-store" style="display: none;">
113
- ${o}
113
+ ${s}
114
114
  </div>
115
115
 
116
116
  <div class="reorder-icon-store" style="display: none;">
117
- ${i}
117
+ ${o}
118
118
  </div>
119
119
 
120
120
  <div class="orderable-list" data-composition-list></div>
121
121
 
122
122
  ${this._GuButton({
123
- name: K.ADD_ATTRIBUTE,
123
+ name: x.ADD_ATTRIBUTE,
124
124
  label: this.api.translate("Add Attribute"),
125
125
  id: "guido__btn-add-attribute"
126
126
  })}
@@ -140,19 +140,19 @@ class Ut extends rt {
140
140
  // Initialization
141
141
  // ========================================================================
142
142
  _initializeComposition() {
143
- const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(), i = this._renderOrderableItems(t, r), o = this._buildVisibilityValues(e);
144
- this.api.updateValues(o), i && this._initializeCustomSelects(r), this._updateAddButtonState();
143
+ const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(), o = this._renderOrderableItems(t, r), s = this._buildVisibilityValues(e);
144
+ this.api.updateValues(s), o && this._initializeCustomSelects(r), this._updateAddButtonState();
145
145
  }
146
146
  _registerValueChangeListeners() {
147
- m.forEach((t) => {
147
+ h.forEach((t) => {
148
148
  this.api.onValueChanged(`visibility_${t.key}`, (r) => {
149
149
  this._applyVisibilityToBlock(t.key, r);
150
150
  });
151
151
  });
152
- for (let t = 0; t < f; t++) {
153
- const r = `${$}${t}`, e = t;
154
- this.api.onValueChanged(r, (i) => {
155
- this._onCustomAttributeChanged(e, i);
152
+ for (let t = 0; t < g; t++) {
153
+ const r = `${T}${t}`, e = t;
154
+ this.api.onValueChanged(r, (o) => {
155
+ this._onCustomAttributeChanged(e, o);
156
156
  });
157
157
  }
158
158
  }
@@ -161,14 +161,14 @@ class Ut extends rt {
161
161
  // ========================================================================
162
162
  _readCompositionFromNode() {
163
163
  if (!this.currentNode || !("getAttribute" in this.currentNode))
164
- return [...x];
165
- const t = this.currentNode.getAttribute(W);
166
- return t ? t.split(",").filter(Boolean) : [...x];
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(F);
171
+ const t = this.currentNode.getAttribute(q);
172
172
  if (!t)
173
173
  return [];
174
174
  try {
@@ -180,31 +180,31 @@ class Ut extends rt {
180
180
  _readVisibilityFromRows() {
181
181
  if (!this.currentNode)
182
182
  return this._getDefaultVisibilities();
183
- const t = Array.from(this.currentNode.querySelectorAll(T)), 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 { ...M };
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 i = e.getAttribute(y), o = e.getAttribute(O);
195
- i && o !== null && (r[i] = this._parseVisibilityValue(o));
194
+ const o = e.getAttribute(y), s = e.getAttribute(v);
195
+ o && s !== null && (r[o] = this._parseVisibilityValue(s));
196
196
  }), r;
197
197
  }
198
198
  _parseVisibilityValue(t) {
199
199
  return t === "1" || t === "true";
200
200
  }
201
201
  _mergeWithDefaults(t) {
202
- return Object.entries(M).forEach(([r, e]) => {
202
+ return Object.entries(F).forEach(([r, e]) => {
203
203
  r in t || (t[r] = e);
204
204
  }), t;
205
205
  }
206
206
  _buildVisibilityValues(t) {
207
- return m.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
207
+ return h.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
208
208
  }
209
209
  // ========================================================================
210
210
  // UI Rendering (Orderable List)
@@ -218,30 +218,24 @@ class Ut extends rt {
218
218
  const e = this._getControlContainer();
219
219
  if (!e)
220
220
  return !1;
221
- const i = e.querySelector("[data-composition-list]");
222
- if (!i)
223
- return !1;
224
- const o = !P.getConfig(this.currentNode).priceMovedToNextLine;
225
- if (!(i.dataset.inlinePrices !== String(o)) && this._tryReorderInPlace(i, t))
221
+ const o = e.querySelector("[data-composition-list]");
222
+ if (!o || this._tryReorderInPlace(o, t))
226
223
  return !1;
227
- i.dataset.inlinePrices = String(o);
228
- const n = new Set(r), c = ht(t);
229
- let l = 0, a = 0;
230
- const d = t.map((u) => {
231
- if (o && (u === S || u === v))
232
- return u === c.anchor ? this._createPriceGroupItemHtml(a++, c.originalFirst) : "";
233
- if (At.has(u)) {
234
- const h = m.find((C) => C.key === u);
235
- return this._createBuiltInItemHtml(h, a++);
224
+ const s = new Set(r);
225
+ let i = 0, n = 0;
226
+ const a = t.map((c) => {
227
+ if (yt.has(c)) {
228
+ const l = h.find((u) => u.key === c);
229
+ return this._createBuiltInItemHtml(l, n++);
236
230
  }
237
- if (u.startsWith(p)) {
238
- const h = u.substring(p.length);
239
- if (n.has(h))
240
- return this._createCustomItemHtml(u, l++, a++);
231
+ if (c.startsWith(m)) {
232
+ const l = c.substring(m.length);
233
+ if (s.has(l))
234
+ return this._createCustomItemHtml(c, i++, n++);
241
235
  }
242
236
  return "";
243
237
  }).join("");
244
- return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), i.innerHTML = d, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, a), !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;
245
239
  }
246
240
  /**
247
241
  * Attempts to reorder existing orderable-item elements to match the composition order.
@@ -253,27 +247,27 @@ class Ut extends rt {
253
247
  const e = Array.from(t.querySelectorAll(".orderable-item"));
254
248
  if (e.length !== r.length)
255
249
  return !1;
256
- const i = e.map((l) => l.dataset.key).filter(Boolean);
257
- if (i.length !== r.length)
250
+ const o = e.map((c) => c.dataset.key).filter(Boolean);
251
+ if (o.length !== r.length)
258
252
  return !1;
259
- const o = [...i].sort().join(","), s = [...r].sort().join(",");
260
- if (o !== s || r.some((l) => l.startsWith(p)))
253
+ const s = [...o].sort().join(","), i = [...r].sort().join(",");
254
+ if (s !== i || r.some((c) => c.startsWith(m)))
261
255
  return !1;
262
256
  const n = /* @__PURE__ */ new Map();
263
- e.forEach((l) => {
264
- const { key: a } = l.dataset;
265
- if (a) {
266
- const d = n.get(a) || [];
267
- d.push(l), n.set(a, d);
257
+ e.forEach((c) => {
258
+ const { key: l } = c.dataset;
259
+ if (l) {
260
+ const u = n.get(l) || [];
261
+ u.push(c), n.set(l, u);
268
262
  }
269
263
  });
270
- const c = /* @__PURE__ */ new Map();
271
- return r.forEach((l) => {
272
- const a = n.get(l);
273
- if (!a)
264
+ const a = /* @__PURE__ */ new Map();
265
+ return r.forEach((c) => {
266
+ const l = n.get(c);
267
+ if (!l)
274
268
  return;
275
- const d = c.get(l) || 0;
276
- c.set(l, d + 1), a[d] && t.appendChild(a[d]);
269
+ const u = a.get(c) || 0;
270
+ a.set(c, u + 1), l[u] && t.appendChild(l[u]);
277
271
  }), !0;
278
272
  }
279
273
  _createBuiltInItemHtml(t, r) {
@@ -285,33 +279,6 @@ class Ut extends rt {
285
279
  </div>
286
280
  `;
287
281
  }
288
- /**
289
- * Inline mode: the merged "Product Prices" group item. It moves as a unit in
290
- * the main list (both keys stay adjacent) and contains a nested 2-item drag
291
- * to reorder Product Price ↔ Product Original Price — which flips the inline
292
- * render order via `resolveInlinePriceOrder`. The group keeps a single
293
- * visibility toggle (`data-action-for="productPrice"`). Nested sub-items use a
294
- * plain drag handle (no UE button → untouched by the reorder-icon rescue).
295
- */
296
- _createPriceGroupItemHtml(t, r) {
297
- var n, c;
298
- const e = ((n = m.find((l) => l.key === S)) == null ? void 0 : n.label) ?? "Product Price", i = ((c = m.find((l) => l.key === v)) == null ? void 0 : c.label) ?? "Product Original Price", o = (l, a) => `
299
- <div class="price-suborderable-item" draggable="true" data-subkey="${l}">
300
- <span class="sub-drag-handle">${Ct}</span>
301
- <span class="item-label">${this.api.translate(a)}</span>
302
- </div>`, s = r ? o(v, i) + o(S, e) : o(S, e) + o(v, i);
303
- return `
304
- <div class="orderable-item price-group-item" draggable="true"
305
- data-key="${S}" data-group="prices">
306
- <div class="price-group-header">
307
- <span class="drag-handle" data-reorder-icon-slot="${t}"></span>
308
- <span class="item-label">${this.api.translate("Product Prices")}</span>
309
- <div class="item-action" data-action-for="${S}"></div>
310
- </div>
311
- <div class="price-suborderable-list">${s}</div>
312
- </div>
313
- `;
314
- }
315
282
  _createCustomItemHtml(t, r, e) {
316
283
  return `
317
284
  <div class="orderable-item" draggable="true"
@@ -332,10 +299,10 @@ class Ut extends rt {
332
299
  _getSelectOptions(t, r = []) {
333
300
  const e = this._getAddableFilters();
334
301
  if (e.length > 0) {
335
- const o = new Set(r);
336
- return o.delete(t), e.filter((s) => !o.has(s.attributeName)).map((s) => ({
337
- text: s.displayName,
338
- value: s.attributeName
302
+ const s = new Set(r);
303
+ return s.delete(t), e.filter((i) => !s.has(i.attributeName)).map((i) => ({
304
+ text: i.displayName,
305
+ value: i.attributeName
339
306
  }));
340
307
  }
341
308
  return [{ text: this._getDisplayNameForAttribute(t), value: t }];
@@ -348,8 +315,8 @@ class Ut extends rt {
348
315
  _initializeCustomSelects(t) {
349
316
  t.length !== 0 && setTimeout(() => {
350
317
  t.forEach((r, e) => {
351
- const i = `${$}${e}`, o = this._getSelectOptions(r, t);
352
- this.api.setUIEAttribute(i, E.SELECTPICKER.items, o), this.api.updateValues({ [i]: r });
318
+ const o = `${T}${e}`, s = this._getSelectOptions(r, t);
319
+ this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
353
320
  });
354
321
  }, 0);
355
322
  }
@@ -358,11 +325,11 @@ class Ut extends rt {
358
325
  * Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
359
326
  */
360
327
  _moveTogglesIntoItems(t) {
361
- m.forEach((r) => {
362
- const e = t.querySelector(`[data-toggle-key="${r.key}"]`), i = t.querySelector(`[data-action-for="${r.key}"]`);
363
- if (e && i) {
364
- const o = e.querySelector("ue-switcher");
365
- o && i.appendChild(o);
328
+ h.forEach((r) => {
329
+ const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
330
+ if (e && o) {
331
+ const s = e.querySelector("ue-switcher");
332
+ s && o.appendChild(s);
366
333
  }
367
334
  });
368
335
  }
@@ -372,10 +339,10 @@ class Ut extends rt {
372
339
  */
373
340
  _moveSelectsIntoItems(t, r) {
374
341
  for (let e = 0; e < r; e++) {
375
- const i = `${$}${e}`, o = t.querySelector(`[data-custom-select-key="${i}"]`), s = t.querySelector(`[data-custom-select-slot="${e}"]`);
376
- if (o && s) {
377
- const n = o.querySelector("ue-select");
378
- n && s.appendChild(n);
342
+ const o = `${T}${e}`, s = t.querySelector(`[data-custom-select-key="${o}"]`), i = t.querySelector(`[data-custom-select-slot="${e}"]`);
343
+ if (s && i) {
344
+ const n = s.querySelector("ue-select");
345
+ n && i.appendChild(n);
379
346
  }
380
347
  }
381
348
  }
@@ -386,11 +353,11 @@ class Ut extends rt {
386
353
  * previously-moved toggles, making them permanently lost.
387
354
  */
388
355
  _rescueTogglesToStore(t) {
389
- m.forEach((r) => {
390
- const e = t.querySelector(`[data-toggle-key="${r.key}"]`), i = t.querySelector(`[data-action-for="${r.key}"]`);
391
- if (i) {
392
- const o = i.querySelector("ue-switcher");
393
- o && e && e.appendChild(o);
356
+ h.forEach((r) => {
357
+ const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
358
+ if (o) {
359
+ const s = o.querySelector("ue-switcher");
360
+ s && e && e.appendChild(s);
394
361
  }
395
362
  });
396
363
  }
@@ -399,11 +366,11 @@ class Ut extends rt {
399
366
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
400
367
  */
401
368
  _rescueSelectsToStore(t) {
402
- for (let r = 0; r < f; r++) {
403
- const e = `${$}${r}`, i = t.querySelector(`[data-custom-select-key="${e}"]`), o = t.querySelector(`[data-custom-select-slot="${r}"]`);
404
- if (o) {
405
- const s = o.querySelector("ue-select");
406
- s && i && i.appendChild(s);
369
+ for (let r = 0; r < g; r++) {
370
+ const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
371
+ if (s) {
372
+ const i = s.querySelector("ue-select");
373
+ i && o && o.appendChild(i);
407
374
  }
408
375
  }
409
376
  }
@@ -413,10 +380,10 @@ class Ut extends rt {
413
380
  */
414
381
  _moveDeleteButtonsIntoItems(t, r) {
415
382
  for (let e = 0; e < r; e++) {
416
- const i = `${R}${e}`, o = t.querySelector(`[data-custom-delete-key="${i}"]`), s = t.querySelector(`[data-custom-delete-slot="${e}"]`);
417
- if (o && s) {
418
- const n = o.querySelector("ue-button");
419
- n && s.appendChild(n);
383
+ const o = `${R}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
384
+ if (s && i) {
385
+ const n = s.querySelector("ue-button");
386
+ n && i.appendChild(n);
420
387
  }
421
388
  }
422
389
  }
@@ -425,11 +392,11 @@ class Ut extends rt {
425
392
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
426
393
  */
427
394
  _rescueDeleteButtonsToStore(t) {
428
- for (let r = 0; r < f; r++) {
429
- const e = `${R}${r}`, i = t.querySelector(`[data-custom-delete-key="${e}"]`), o = t.querySelector(`[data-custom-delete-slot="${r}"]`);
430
- if (o) {
431
- const s = o.querySelector("ue-button");
432
- s && i && i.appendChild(s);
395
+ for (let r = 0; r < g; r++) {
396
+ const e = `${R}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
397
+ if (s) {
398
+ const i = s.querySelector("ue-button");
399
+ i && o && o.appendChild(i);
433
400
  }
434
401
  }
435
402
  }
@@ -439,10 +406,10 @@ class Ut extends rt {
439
406
  */
440
407
  _moveReorderIconsIntoItems(t, r) {
441
408
  for (let e = 0; e < r; e++) {
442
- const i = `${N}${e}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
443
- if (o && s) {
444
- const n = o.querySelector("ue-button");
445
- n && s.appendChild(n);
409
+ const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
410
+ if (s && i) {
411
+ const n = s.querySelector("ue-button");
412
+ n && i.appendChild(n);
446
413
  }
447
414
  }
448
415
  }
@@ -451,12 +418,12 @@ class Ut extends rt {
451
418
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
452
419
  */
453
420
  _rescueReorderIconsToStore(t) {
454
- const r = m.length + f;
421
+ const r = h.length + g;
455
422
  for (let e = 0; e < r; e++) {
456
- const i = `${N}${e}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
457
- if (s) {
458
- const n = s.querySelector("ue-button");
459
- n && o && o.appendChild(n);
423
+ const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
424
+ if (i) {
425
+ const n = i.querySelector("ue-button");
426
+ n && s && s.appendChild(n);
460
427
  }
461
428
  }
462
429
  }
@@ -468,83 +435,41 @@ class Ut extends rt {
468
435
  const { signal: t } = this.eventController, r = this._getControlContainer();
469
436
  if (!r)
470
437
  return;
471
- const e = r.querySelector("[data-composition-list]"), i = r.querySelector("#guido__btn-add-attribute");
472
- e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), i && i.addEventListener("click", () => {
473
- const o = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !o.has(n.attributeName));
474
- s && this._onAddAttribute(s.attributeName, s.displayName);
438
+ const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
439
+ e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
440
+ const s = new Set(this._readCustomAttributesFromNode()), i = this._getAddableFilters().find((n) => !s.has(n.attributeName));
441
+ i && this._onAddAttribute(i.attributeName, i.displayName);
475
442
  }, { signal: t });
476
443
  }
477
- /**
478
- * Builds the composition key order from the orderable list, expanding the
479
- * inline "Product Prices" group into its two sub-keys (in nested DOM order)
480
- * so both price keys stay adjacent and in the user-chosen order.
481
- */
482
- _extractCompositionOrder(t) {
483
- const r = [];
484
- return t.querySelectorAll(".orderable-item").forEach((e) => {
485
- const i = e;
486
- i.dataset.group === "prices" ? i.querySelectorAll(".price-suborderable-item").forEach((o) => {
487
- const s = o.dataset.subkey;
488
- s && r.push(s);
489
- }) : i.dataset.key && r.push(i.dataset.key);
490
- }), r;
491
- }
492
444
  _setupDragAndDrop(t, r) {
493
- this._registerDragHandlers(t, r, {
494
- itemSelector: ".orderable-item",
495
- ignoreSelector: ".price-suborderable-item",
496
- getDropParent: () => t
497
- }), this._registerDragHandlers(t, r, {
498
- itemSelector: ".price-suborderable-item",
499
- getDropParent: (e) => e.parentElement
500
- });
501
- }
502
- /**
503
- * Wires drag/drop reordering for one item level on the shared list. Both the
504
- * top-level items and the nested price sub-items use this; they never fight
505
- * because each only sets its `dragged` ref when its own `itemSelector` matches
506
- * at dragstart (and the top-level one additionally ignores drags originating
507
- * inside `ignoreSelector`). Every drop re-reads the full composition via
508
- * `_extractCompositionOrder`, so both levels commit through `_onReorder`
509
- * identically.
510
- */
511
- _registerDragHandlers(t, r, e) {
512
- let i = null, o = null;
513
- const s = (n) => n.target.closest(e.itemSelector);
514
- t.addEventListener("dragstart", (n) => {
445
+ let e = null, o = null;
446
+ t.addEventListener("dragstart", (s) => {
515
447
  var a;
516
- const c = n.target;
517
- if (e.ignoreSelector && c.closest(e.ignoreSelector))
518
- return;
519
- const l = s(n);
520
- l && (i = l, l.classList.add("dragging"), (a = n.dataTransfer) == null || a.setData("text/plain", l.dataset.key ?? l.dataset.subkey ?? ""));
448
+ const n = s.target.closest(".orderable-item");
449
+ n && (e = n, n.classList.add("dragging"), (a = s.dataTransfer) == null || a.setData("text/plain", n.dataset.key || ""));
521
450
  }, { signal: r }), t.addEventListener("dragend", () => {
522
- i == null || i.classList.remove("dragging"), o == null || o.classList.remove("drag-over"), i = null, o = null;
523
- }, { signal: r }), t.addEventListener("dragover", (n) => {
524
- if (!i)
451
+ e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
452
+ }, { signal: r }), t.addEventListener("dragover", (s) => {
453
+ s.preventDefault();
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
+ }, { signal: r }), t.addEventListener("drop", (s) => {
457
+ s.preventDefault();
458
+ const n = s.target.closest(".orderable-item");
459
+ if (!n || !e || n === e)
525
460
  return;
526
- const c = s(n);
527
- if (!c)
528
- return;
529
- n.preventDefault();
530
- const l = c !== i ? c : null;
531
- l !== o && (o == null || o.classList.remove("drag-over"), o = l, o == null || o.classList.add("drag-over"));
532
- }, { signal: r }), t.addEventListener("drop", (n) => {
533
- var d;
534
- const c = i && s(n);
535
- if (!i || !c || c === i)
536
- return;
537
- n.preventDefault();
538
- const l = c.getBoundingClientRect(), a = n.clientY < l.top + l.height / 2;
539
- (d = e.getDropParent(c)) == null || d.insertBefore(i, a ? c : c.nextSibling), o == null || o.classList.remove("drag-over"), i.classList.remove("dragging"), i = null, o = null, this._onReorder(this._extractCompositionOrder(t));
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
+ const u = t.querySelectorAll(".orderable-item"), d = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
464
+ this._onReorder(d), e = null;
540
465
  }, { signal: r });
541
466
  }
542
467
  _setupDeleteHandler(t, r) {
543
468
  t.addEventListener("click", (e) => {
544
- const o = e.target.closest(".custom-attr-delete");
545
- if (!o)
469
+ const s = e.target.closest(".custom-attr-delete");
470
+ if (!s)
546
471
  return;
547
- const s = o.closest("[data-custom-index]"), n = s == null ? void 0 : s.dataset.customIndex;
472
+ const i = s.closest("[data-custom-index]"), n = i == null ? void 0 : i.dataset.customIndex;
548
473
  n !== void 0 && this._onDeleteCustomAttribute(Number(n));
549
474
  }, { signal: r });
550
475
  }
@@ -552,10 +477,10 @@ class Ut extends rt {
552
477
  // Actions (Add, Delete, Reorder)
553
478
  // ========================================================================
554
479
  _onAddAttribute(t, r) {
555
- const e = `${p}${t}`, i = this._readCompositionFromNode();
556
- i.push(e);
557
- const o = [...this._readCustomAttributesFromNode(), t];
558
- this._updateBothAttributes(i, o), this._injectCustomAttributeHtml(t, r, e, i), this._renderOrderableItems(i, o), this._initializeCustomSelects(o), this._updateAddButtonState();
480
+ const e = `${m}${t}`, o = this._readCompositionFromNode();
481
+ o.push(e);
482
+ const s = [...this._readCustomAttributesFromNode(), t];
483
+ this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
559
484
  }
560
485
  /**
561
486
  * Removes a single custom attribute by its index in the customAttrs array.
@@ -565,32 +490,27 @@ class Ut extends rt {
565
490
  const r = this._readCustomAttributesFromNode();
566
491
  if (r[t] === void 0)
567
492
  return;
568
- const i = this._readCompositionFromNode(), o = this._findNthCustomKeyIndex(i, t), s = i.filter((c, l) => l !== o), n = r.filter((c, l) => l !== t);
569
- this._updateBothAttributes(s, n), this._removeCustomAttributeHtml(s), this._renderOrderableItems(s, n), this._initializeCustomSelects(n), this._updateAddButtonState();
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
+ this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
570
495
  }
571
496
  /**
572
497
  * Handles changing a custom attribute's selection via its inline _GuSelect.
573
498
  * Uses the customIndex to target only the specific instance, supporting duplicates.
574
499
  */
575
500
  _onCustomAttributeChanged(t, r) {
576
- const e = this._readCustomAttributesFromNode(), i = e[t];
577
- if (i === void 0 || i === r)
501
+ const e = this._readCustomAttributesFromNode(), o = e[t];
502
+ if (o === void 0 || o === r)
578
503
  return;
579
- const o = `${p}${r}`, s = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(s, t);
580
- n !== -1 && (s[n] = o), e[t] = r;
581
- const c = this._getDisplayNameForAttribute(r);
582
- this._updateBothAttributes(s, e), this._injectCustomAttributeHtml(r, c, o, s), this._renderOrderableItems(s, e), this._initializeCustomSelects(e);
504
+ const s = `${m}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
505
+ n !== -1 && (i[n] = s), e[t] = r;
506
+ const a = this._getDisplayNameForAttribute(r);
507
+ this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, a, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
583
508
  }
584
509
  _onReorder(t) {
585
- const r = t.filter((e) => e.startsWith(p)).map((e) => e.substring(p.length));
510
+ const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
586
511
  this.reorderInProgress = !0;
587
512
  try {
588
- this._updateBothAttributes(t, r);
589
- const e = !P.getConfig(this.currentNode).priceMovedToNextLine;
590
- this._getCurrentLayout() === "grid" && !e ? this._reorderProductAttributes(t) : this.currentNode && ft({
591
- currentNode: this.currentNode,
592
- documentModifier: this.api.getDocumentModifier()
593
- });
513
+ this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
594
514
  } finally {
595
515
  this.reorderInProgress = !1;
596
516
  }
@@ -599,66 +519,66 @@ class Ut extends rt {
599
519
  // ========================================================================
600
520
  // HTML Injection / Removal (Product Card DOM)
601
521
  // ========================================================================
602
- _injectCustomAttributeHtml(t, r, e, i) {
522
+ _injectCustomAttributeHtml(t, r, e, o) {
603
523
  if (!this.currentNode)
604
524
  return;
605
- this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, i) : this._injectListAttributeRow(t, r, e, i);
525
+ this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
606
526
  }
607
- _injectGridAttributeRow(t, r, e, i) {
608
- const o = this.currentNode.querySelectorAll(H);
609
- if (!(o != null && o.length))
527
+ _injectGridAttributeRow(t, r, e, o) {
528
+ const s = this.currentNode.querySelectorAll(L);
529
+ if (!(s != null && s.length))
610
530
  return;
611
- const s = P.getConfig(this.currentNode), c = `0 ${Math.floor(s.columnSpacing / 2)}px`, l = this.api.getDocumentModifier(), a = this.store.recommendationProducts.length;
612
- let d = 0;
613
- o.forEach((u) => {
614
- var w;
615
- const h = u.querySelector(T), C = ((w = h == null ? void 0 : h.querySelectorAll(`.${at}`)) == null ? void 0 : w.length) || 1, q = (100 / C).toFixed(2), { bgStyle: G, bgAttr: z } = this._extractSegmentBgFromCard(u), D = a > 0 ? Math.min(C, a - d) : C, Y = i.map((B) => {
616
- if (B === e) {
617
- const X = Array.from(
618
- { length: D },
619
- (Tt, Q) => {
620
- const Z = this._resolveAttributeContent(
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
+ let u = 0;
533
+ s.forEach((d) => {
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
+ const z = Array.from(
538
+ { length: O },
539
+ (At, Y) => {
540
+ const X = this._resolveAttributeContent(
621
541
  t,
622
542
  r,
623
- d + Q
543
+ u + Y
624
544
  );
625
545
  return this._getGridCellHtml(
626
546
  t,
627
- Z,
628
- q,
629
- G,
630
- z,
631
- c
547
+ X,
548
+ B,
549
+ j,
550
+ W,
551
+ a
632
552
  );
633
553
  }
634
- ).join(""), J = ut(q, c).repeat(C - D);
635
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${O}="1">${X}${J}</tr>`;
554
+ ).join(""), G = dt(B, a).repeat($ - O);
555
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${z}${G}</tr>`;
636
556
  }
637
- const L = u.querySelector(
638
- `${T}[${y}="${B}"]`
557
+ const N = d.querySelector(
558
+ `${C}[${y}="${k}"]`
639
559
  );
640
- return L && "getOuterHTML" in L ? L.getOuterHTML() : "";
560
+ return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
641
561
  }).join("");
642
- d += D, a > 0 && d >= a && (d = 0), l.modifyHtml(u).setInnerHtml(Y);
643
- }), l.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}`));
644
564
  }
645
- _injectListAttributeRow(t, r, e, i) {
646
- const o = this.currentNode.querySelectorAll(j);
647
- if (!(o != null && o.length))
565
+ _injectListAttributeRow(t, r, e, o) {
566
+ const s = this.currentNode.querySelectorAll(M);
567
+ if (!(s != null && s.length))
648
568
  return;
649
- const s = i.filter((c) => c !== k && c !== U), n = this.api.getDocumentModifier();
650
- o.forEach((c, l) => {
651
- const a = s.map((d) => {
652
- if (d === e) {
653
- const h = this._resolveAttributeContent(t, r, l);
654
- return this._getListRowHtml(t, h, e);
569
+ const i = o.filter((a) => a !== D && a !== U), n = this.api.getDocumentModifier();
570
+ s.forEach((a, c) => {
571
+ const l = i.map((u) => {
572
+ if (u === e) {
573
+ const b = this._resolveAttributeContent(t, r, c);
574
+ return this._getListRowHtml(t, b, e);
655
575
  }
656
- const u = c.querySelector(
657
- `${T}[${y}="${d}"]`
576
+ const d = a.querySelector(
577
+ `${C}[${y}="${u}"]`
658
578
  );
659
- return u && "getOuterHTML" in u ? u.getOuterHTML() : "";
579
+ return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
660
580
  }).join("");
661
- n.modifyHtml(c).setInnerHtml(a);
581
+ n.modifyHtml(a).setInnerHtml(l);
662
582
  }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
663
583
  }
664
584
  /**
@@ -670,16 +590,16 @@ class Ut extends rt {
670
590
  return;
671
591
  const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
672
592
  if (r === "grid") {
673
- const i = this.currentNode.querySelectorAll(H);
674
- i == null || i.forEach((o) => {
675
- const s = this._buildCompositionHtml(o, t);
676
- e.modifyHtml(o).setInnerHtml(s);
593
+ const o = this.currentNode.querySelectorAll(L);
594
+ o == null || o.forEach((s) => {
595
+ const i = this._buildCompositionHtml(s, t);
596
+ e.modifyHtml(s).setInnerHtml(i);
677
597
  });
678
598
  } else {
679
- const i = t.filter((s) => s !== k && s !== U), o = this.currentNode.querySelectorAll(j);
680
- o == null || o.forEach((s) => {
681
- const n = this._buildCompositionHtml(s, i);
682
- e.modifyHtml(s).setInnerHtml(n);
599
+ const o = t.filter((i) => i !== D && i !== U), s = this.currentNode.querySelectorAll(M);
600
+ s == null || s.forEach((i) => {
601
+ const n = this._buildCompositionHtml(i, o);
602
+ e.modifyHtml(i).setInnerHtml(n);
683
603
  });
684
604
  }
685
605
  e.apply(new A(this.api.translate("Remove custom attribute")));
@@ -695,7 +615,7 @@ class Ut extends rt {
695
615
  * producing a flicker on the custom attribute dropdowns.
696
616
  */
697
617
  _updateBothAttributes(t, r) {
698
- this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(W, t.join(",")).setAttribute(F, 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")));
699
619
  }
700
620
  /**
701
621
  * Reorders attribute rows within each product card based on composition order.
@@ -704,13 +624,13 @@ class Ut extends rt {
704
624
  _reorderProductAttributes(t) {
705
625
  if (!this.currentNode)
706
626
  return;
707
- const r = this.currentNode.querySelectorAll(H);
627
+ const r = this.currentNode.querySelectorAll(L);
708
628
  if (!(r != null && r.length))
709
629
  return;
710
630
  const e = this.api.getDocumentModifier();
711
- r.forEach((i) => {
712
- const o = this._buildCompositionHtml(i, t);
713
- e.modifyHtml(i).setInnerHtml(o);
631
+ r.forEach((o) => {
632
+ const s = this._buildCompositionHtml(o, t);
633
+ e.modifyHtml(o).setInnerHtml(s);
714
634
  }), e.apply(new A(this.api.translate("Reorder product attributes")));
715
635
  }
716
636
  /**
@@ -718,9 +638,9 @@ class Ut extends rt {
718
638
  * Queries existing rows from the container by data-attribute-type.
719
639
  */
720
640
  _buildCompositionHtml(t, r) {
721
- return r.reduce((e, i) => {
722
- const o = t.querySelector(`${T}[${y}="${i}"]`);
723
- return o && "getOuterHTML" in o ? e + o.getOuterHTML() : e;
641
+ return r.reduce((e, o) => {
642
+ const s = t.querySelector(`${C}[${y}="${o}"]`);
643
+ return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
724
644
  }, "");
725
645
  }
726
646
  // ========================================================================
@@ -729,14 +649,14 @@ class Ut extends rt {
729
649
  _applyVisibilityToBlock(t, r) {
730
650
  if (!this.currentNode)
731
651
  return;
732
- const e = this.currentNode.querySelectorAll(`${T}[${y}="${t}"]`);
652
+ const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
733
653
  if (!(e != null && e.length))
734
654
  return;
735
- const i = r ? "1" : "0", o = r ? this.api.translate("visible") : this.api.translate("hidden"), s = `${this.api.translate("Set visibility")}: ${t} → ${o}`, n = this.api.getDocumentModifier();
736
- e.forEach((c) => {
737
- const l = _t(c), a = r ? l : "none";
738
- n.modifyHtml(c).setStyle("display", a).setAttribute(O, i);
739
- }), n.apply(new A(s));
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();
656
+ e.forEach((a) => {
657
+ const c = ft(a), l = r ? c : "none";
658
+ n.modifyHtml(a).setStyle("display", l).setAttribute(v, o);
659
+ }), n.apply(new A(i));
740
660
  }
741
661
  // ========================================================================
742
662
  // Utilities
@@ -748,16 +668,16 @@ class Ut extends rt {
748
668
  */
749
669
  _findNthCustomKeyIndex(t, r) {
750
670
  let e = 0;
751
- for (let i = 0; i < t.length; i++)
752
- if (t[i].startsWith(p)) {
671
+ for (let o = 0; o < t.length; o++)
672
+ if (t[o].startsWith(m)) {
753
673
  if (e === r)
754
- return i;
674
+ return o;
755
675
  e++;
756
676
  }
757
677
  return -1;
758
678
  }
759
679
  _getCurrentLayout() {
760
- return this.store.recommendationConfigs.orientation || yt(this.currentNode);
680
+ return this.store.recommendationConfigs.orientation || gt(this.currentNode);
761
681
  }
762
682
  /**
763
683
  * Extracts background color properties from existing card elements.
@@ -766,21 +686,21 @@ class Ut extends rt {
766
686
  * Used when injecting new attribute cells to match the card's current background.
767
687
  */
768
688
  _extractSegmentBgFromCard(t) {
769
- var i;
689
+ var o;
770
690
  const r = t.querySelector(".product-card-segment");
771
691
  if (r && "getAttribute" in r) {
772
- const s = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
773
- if (s) {
692
+ const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
693
+ if (i) {
774
694
  const n = r.getAttribute("bgcolor") || "";
775
- return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
695
+ return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
776
696
  }
777
697
  }
778
- const e = (i = this.currentNode) == null ? void 0 : i.querySelector(".product-card-wrapper");
698
+ const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
779
699
  if (e && "getStyle" in e) {
780
- const o = e.getStyle("background-color");
781
- if (o && o !== "transparent") {
782
- const s = "getAttribute" in e && e.getAttribute("bgcolor") || "";
783
- return { bgStyle: `background-color: ${o};`, bgAttr: s };
700
+ const s = e.getStyle("background-color");
701
+ if (s && s !== "transparent") {
702
+ const i = "getAttribute" in e && e.getAttribute("bgcolor") || "";
703
+ return { bgStyle: `background-color: ${s};`, bgAttr: i };
784
704
  }
785
705
  }
786
706
  return { bgStyle: "", bgAttr: "" };
@@ -790,18 +710,17 @@ class Ut extends rt {
790
710
  return t ? t.querySelector("[data-card-composition-control]") : null;
791
711
  }
792
712
  /**
793
- * Ensures composition reorder is enabled. Both grid and list layouts now
794
- * support reordering top-level items and the nested price sub-items are all
795
- * draggable. (Items render with `draggable="true"`; this just clears any stale
796
- * disabled state.)
713
+ * Adds/removes orderable-disabled class based on layout orientation.
714
+ * List layout hides drag handles via CSS and disables draggable attribute
715
+ * to prevent native browser drag-and-drop from working without the handle.
797
716
  */
798
717
  _updateOrderableState() {
799
- const t = this._getControlContainer();
800
- if (!t)
718
+ const r = this._getCurrentLayout() === "list", e = this._getControlContainer();
719
+ if (!e)
801
720
  return;
802
- const r = t.querySelector("[data-composition-list]");
803
- r && (r.classList.remove("orderable-disabled"), r.querySelectorAll(".orderable-item").forEach((e) => {
804
- e.setAttribute("draggable", "true");
721
+ const o = e.querySelector("[data-composition-list]");
722
+ o && (o.classList.toggle("orderable-disabled", r), o.querySelectorAll(".orderable-item").forEach((s) => {
723
+ s.setAttribute("draggable", r ? "false" : "true");
805
724
  }));
806
725
  }
807
726
  /**
@@ -809,11 +728,11 @@ class Ut extends rt {
809
728
  * or when all available filters have already been added (no unused attributes left).
810
729
  */
811
730
  _updateAddButtonState() {
812
- const t = this._readCustomAttributesFromNode(), r = t.length >= f, e = new Set(t), i = this._getAddableFilters(), o = i.length > 0 && i.every((s) => e.has(s.attributeName));
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));
813
732
  this.api.setUIEAttribute(
814
- K.ADD_ATTRIBUTE,
815
- E.BUTTON.disabled,
816
- r || o ? "true" : "false"
733
+ x.ADD_ATTRIBUTE,
734
+ I.BUTTON.disabled,
735
+ r || s ? "true" : "false"
817
736
  );
818
737
  }
819
738
  /**
@@ -826,8 +745,8 @@ class Ut extends rt {
826
745
  this.unsubscribeStore = this.store.$subscribe(() => {
827
746
  const e = this.store.recommendationConfigs.orientation;
828
747
  e !== t && (t = e, this._updateOrderableState());
829
- const i = Object.keys(this.store.filterList).sort().join(",");
830
- i !== r && (r = i, this._initializeComposition());
748
+ const o = Object.keys(this.store.filterList).sort().join(",");
749
+ o !== r && (r = o, this._initializeComposition());
831
750
  });
832
751
  }
833
752
  /**
@@ -835,7 +754,7 @@ class Ut extends rt {
835
754
  * excluding default attributes already covered by built-in toggle items.
836
755
  */
837
756
  _getAddableFilters() {
838
- return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && nt.has(t.attributeName)));
757
+ return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && it.has(t.attributeName)));
839
758
  }
840
759
  /**
841
760
  * Looks up the display name for an attribute from the store's filterList.
@@ -843,7 +762,7 @@ class Ut extends rt {
843
762
  */
844
763
  _getDisplayNameForAttribute(t) {
845
764
  const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
846
- return r ? r.displayName : pt(t);
765
+ return r ? r.displayName : ht(t);
847
766
  }
848
767
  /**
849
768
  * Resolves the display content for a custom attribute cell.
@@ -851,29 +770,29 @@ class Ut extends rt {
851
770
  */
852
771
  _resolveAttributeContent(t, r, e) {
853
772
  var n;
854
- const o = this.store.recommendationProducts[e], s = gt(t, this.store.filterList) ? o == null ? void 0 : o[t] : (n = o == null ? void 0 : o.product_attributes) == null ? void 0 : n[t];
855
- return bt(s) ?? 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;
856
775
  }
857
- _getGridCellHtml(t, r, e, i = "", o = "", s = "") {
858
- const n = `${p}${t}`, c = V(ct, [n], this.store.filterList), l = {
776
+ _getGridCellHtml(t, r, e, o = "", s = "", i = "") {
777
+ const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
859
778
  [t]: r,
860
779
  product_attributes: { [t]: r }
861
780
  };
862
- let a = c[n](l);
863
- return a = a.replace("<td", `<td width="${e}%"`), s && (a = a.replace(
864
- `padding: ${dt}`,
865
- `padding: ${s}`
866
- )), i && (a = a.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${i}"`)), o && (a = a.replace(/border="0"/, `border="0" bgcolor="${o}"`)), a;
781
+ let l = a[n](c);
782
+ return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
783
+ `padding: ${ut}`,
784
+ `padding: ${i}`
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;
867
786
  }
868
787
  _getListRowHtml(t, r, e) {
869
- const i = V(mt, [e], this.store.filterList), o = {
788
+ const o = w(mt, [e], this.store.filterList), s = {
870
789
  [t]: r,
871
790
  product_attributes: { [t]: r }
872
- }, n = i[e](o).replace(/<tr>/, "").replace(/<\/tr>/, "");
873
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${O}="1">${n}</tr>`;
791
+ }, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
792
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
874
793
  }
875
794
  }
876
795
  export {
877
- St as COMPOSITION_CONTROL_BLOCK_ID,
796
+ bt as COMPOSITION_CONTROL_BLOCK_ID,
878
797
  Ut as RecommendationCardCompositionControl
879
798
  };