@useinsider/guido 3.7.0-beta.24bdfa3 → 3.7.0-beta.340a6d3

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 (40) 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/Recommendation/block.js +43 -59
  7. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +32 -41
  8. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +313 -377
  9. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +72 -84
  10. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +66 -68
  11. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +7 -21
  12. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +4 -64
  13. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +5 -7
  14. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +72 -101
  15. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -31
  16. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -9
  17. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +59 -74
  18. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
  19. package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -88
  20. package/dist/src/@types/config/schemas.d.ts +0 -16
  21. package/dist/src/composables/useConfig.d.ts +0 -4
  22. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
  23. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -10
  24. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +3 -29
  25. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
  26. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -3
  27. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -2
  28. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +0 -16
  29. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  30. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +0 -13
  31. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +2 -3
  32. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +1 -33
  33. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -15
  34. package/dist/src/stores/config.d.ts +0 -36
  35. package/package.json +1 -1
  36. package/dist/composables/useRecommendationPreview.js +0 -100
  37. package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +0 -133
  38. package/dist/src/composables/useRecommendationPreview.d.ts +0 -10
  39. package/dist/src/composables/useRecommendationPreview.test.d.ts +0 -1
  40. package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +0 -59
@@ -1,95 +1,95 @@
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 Q = Object.defineProperty;
2
+ var Z = (p, g, t) => g in p ? Q(p, g, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[g] = t;
3
+ var S = (p, g, t) => Z(p, typeof g != "symbol" ? g + "" : g, t);
4
+ import { UIElementType as f, UEAttr as v, ModificationDescription as C } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as tt } from "../../../common-control.js";
6
+ import { ATTR_PRODUCT_IMAGE as H, ATTR_PRODUCT_NAME as et, ATTR_PRODUCT_PRICE as rt, ATTR_PRODUCT_OLD_PRICE as ot, ATTR_PRODUCT_OMNIBUS_PRICE as st, ATTR_PRODUCT_OMNIBUS_DISCOUNT as it, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as F, ATTR_CUSTOM_PREFIX as d, BUILT_IN_DEFAULT_ATTRIBUTES as nt } from "../../constants/selectors.js";
7
+ import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as w } from "../../constants/defaultConfig.js";
8
+ import { RecommendationConfigService as $ } 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 gt, buildElementRenderer as M } from "../../templates/utils.js";
13
+ import { getTableDisplayValue as ft } from "../../utils/tagName.js";
14
+ import { getCurrentLayout as _t } from "../main/utils.js";
15
+ const bt = "ui-elements-recommendation-card-composition", A = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", V = ".product-info-cell > table > tbody", x = "data-card-composition", y = "data-attribute-type", N = "data-visibility", j = {
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" },
23
- { key: st, label: "Omnibus Discount" },
17
+ }, _ = 5, R = "reorderIcon_", h = [
18
+ { key: H, label: "Product Image" },
19
+ { key: et, label: "Product Name" },
20
+ { key: rt, label: "Product Price" },
21
+ { key: ot, label: "Product Original Price" },
22
+ { key: st, label: "Omnibus Price" },
23
+ { key: it, 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_", E = "deleteAttr_";
26
+ class Ht extends tt {
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: _ },
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 + _, 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="${R}${u}" style="display: none;">
64
+ <${f.BUTTON}
65
65
  class="drag-handle-btn flat-inline flat-white"
66
- ${E.BUTTON.name}="${N}${d}"
66
+ ${v.BUTTON.name}="${R}${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: _ },
77
+ (l, u) => `
78
+ <div data-custom-delete-key="${E}${u}" style="display: none;">
79
+ <${f.BUTTON}
80
80
  class="custom-attr-delete flat-inline flat-white"
81
- ${E.BUTTON.name}="${R}${d}"
81
+ ${v.BUTTON.name}="${E}${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
+ ), c = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
93
93
  return `
94
94
  <div class="recommendation-controls-container" data-card-composition-control>
95
95
  <div class="container">
@@ -97,7 +97,7 @@ class Ut extends rt {
97
97
  ${n}
98
98
  ${c}
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">${a}</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: j.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 < _; 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,50 +161,56 @@ 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(x);
166
+ if (t)
167
+ return t.split(",").filter(Boolean);
168
+ const { composition: r } = $.getConfig(this.currentNode);
169
+ return r != null && r.length ? [...r] : [...P];
167
170
  }
168
171
  _readCustomAttributesFromNode() {
169
172
  if (!this.currentNode || !("getAttribute" in this.currentNode))
170
173
  return [];
171
174
  const t = this.currentNode.getAttribute(F);
172
- if (!t)
173
- return [];
174
- try {
175
- return JSON.parse(t);
176
- } catch {
177
- return [];
178
- }
175
+ if (t)
176
+ try {
177
+ return JSON.parse(t);
178
+ } catch {
179
+ return [];
180
+ }
181
+ return this._readCompositionFromNode().filter((r) => r.startsWith(d)).map((r) => r.substring(d.length));
179
182
  }
180
183
  _readVisibilityFromRows() {
181
184
  if (!this.currentNode)
182
185
  return this._getDefaultVisibilities();
183
- const t = Array.from(this.currentNode.querySelectorAll(T)), r = this._extractVisibilityFromRows(t);
184
- return this._mergeWithDefaults(r);
186
+ const t = Array.from(this.currentNode.querySelectorAll(A)), r = this._extractVisibilityFromRows(t);
187
+ if (Object.keys(r).length > 0)
188
+ return this._mergeWithDefaults(r);
189
+ const e = $.getConfig(this.currentNode).visibility;
190
+ return this._mergeWithDefaults({ ...e });
185
191
  }
186
192
  _getDefaultVisibilities() {
187
- return { ...M };
193
+ return { ...w };
188
194
  }
189
195
  _extractVisibilityFromRows(t) {
190
196
  const r = {};
191
197
  return t.forEach((e) => {
192
198
  if (!("getAttribute" in e))
193
199
  return;
194
- const i = e.getAttribute(y), o = e.getAttribute(O);
195
- i && o !== null && (r[i] = this._parseVisibilityValue(o));
200
+ const o = e.getAttribute(y), s = e.getAttribute(N);
201
+ o && s !== null && (r[o] = this._parseVisibilityValue(s));
196
202
  }), r;
197
203
  }
198
204
  _parseVisibilityValue(t) {
199
205
  return t === "1" || t === "true";
200
206
  }
201
207
  _mergeWithDefaults(t) {
202
- return Object.entries(M).forEach(([r, e]) => {
208
+ return Object.entries(w).forEach(([r, e]) => {
203
209
  r in t || (t[r] = e);
204
210
  }), t;
205
211
  }
206
212
  _buildVisibilityValues(t) {
207
- return m.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
213
+ return h.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
208
214
  }
209
215
  // ========================================================================
210
216
  // UI Rendering (Orderable List)
@@ -218,30 +224,24 @@ class Ut extends rt {
218
224
  const e = this._getControlContainer();
219
225
  if (!e)
220
226
  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))
227
+ const o = e.querySelector("[data-composition-list]");
228
+ if (!o || this._tryReorderInPlace(o, t))
226
229
  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++);
230
+ const s = new Set(r);
231
+ let i = 0, n = 0;
232
+ const c = t.map((a) => {
233
+ if (yt.has(a)) {
234
+ const l = h.find((u) => u.key === a);
235
+ return this._createBuiltInItemHtml(l, n++);
236
236
  }
237
- if (u.startsWith(p)) {
238
- const h = u.substring(p.length);
239
- if (n.has(h))
240
- return this._createCustomItemHtml(u, l++, a++);
237
+ if (a.startsWith(d)) {
238
+ const l = a.substring(d.length);
239
+ if (s.has(l))
240
+ return this._createCustomItemHtml(a, i++, n++);
241
241
  }
242
242
  return "";
243
243
  }).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;
244
+ 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;
245
245
  }
246
246
  /**
247
247
  * Attempts to reorder existing orderable-item elements to match the composition order.
@@ -253,27 +253,27 @@ class Ut extends rt {
253
253
  const e = Array.from(t.querySelectorAll(".orderable-item"));
254
254
  if (e.length !== r.length)
255
255
  return !1;
256
- const i = e.map((l) => l.dataset.key).filter(Boolean);
257
- if (i.length !== r.length)
256
+ const o = e.map((a) => a.dataset.key).filter(Boolean);
257
+ if (o.length !== r.length)
258
258
  return !1;
259
- const o = [...i].sort().join(","), s = [...r].sort().join(",");
260
- if (o !== s || r.some((l) => l.startsWith(p)))
259
+ const s = [...o].sort().join(","), i = [...r].sort().join(",");
260
+ if (s !== i || r.some((a) => a.startsWith(d)))
261
261
  return !1;
262
262
  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);
263
+ e.forEach((a) => {
264
+ const { key: l } = a.dataset;
265
+ if (l) {
266
+ const u = n.get(l) || [];
267
+ u.push(a), n.set(l, u);
268
268
  }
269
269
  });
270
270
  const c = /* @__PURE__ */ new Map();
271
- return r.forEach((l) => {
272
- const a = n.get(l);
273
- if (!a)
271
+ return r.forEach((a) => {
272
+ const l = n.get(a);
273
+ if (!l)
274
274
  return;
275
- const d = c.get(l) || 0;
276
- c.set(l, d + 1), a[d] && t.appendChild(a[d]);
275
+ const u = c.get(a) || 0;
276
+ c.set(a, u + 1), l[u] && t.appendChild(l[u]);
277
277
  }), !0;
278
278
  }
279
279
  _createBuiltInItemHtml(t, r) {
@@ -285,33 +285,6 @@ class Ut extends rt {
285
285
  </div>
286
286
  `;
287
287
  }
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
288
  _createCustomItemHtml(t, r, e) {
316
289
  return `
317
290
  <div class="orderable-item" draggable="true"
@@ -332,10 +305,10 @@ class Ut extends rt {
332
305
  _getSelectOptions(t, r = []) {
333
306
  const e = this._getAddableFilters();
334
307
  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
308
+ const s = new Set(r);
309
+ return s.delete(t), e.filter((i) => !s.has(i.attributeName)).map((i) => ({
310
+ text: i.displayName,
311
+ value: i.attributeName
339
312
  }));
340
313
  }
341
314
  return [{ text: this._getDisplayNameForAttribute(t), value: t }];
@@ -348,8 +321,8 @@ class Ut extends rt {
348
321
  _initializeCustomSelects(t) {
349
322
  t.length !== 0 && setTimeout(() => {
350
323
  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 });
324
+ const o = `${T}${e}`, s = this._getSelectOptions(r, t);
325
+ this.api.setUIEAttribute(o, v.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
353
326
  });
354
327
  }, 0);
355
328
  }
@@ -358,11 +331,11 @@ class Ut extends rt {
358
331
  * Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
359
332
  */
360
333
  _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);
334
+ h.forEach((r) => {
335
+ const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
336
+ if (e && o) {
337
+ const s = e.querySelector("ue-switcher");
338
+ s && o.appendChild(s);
366
339
  }
367
340
  });
368
341
  }
@@ -372,10 +345,10 @@ class Ut extends rt {
372
345
  */
373
346
  _moveSelectsIntoItems(t, r) {
374
347
  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);
348
+ const o = `${T}${e}`, s = t.querySelector(`[data-custom-select-key="${o}"]`), i = t.querySelector(`[data-custom-select-slot="${e}"]`);
349
+ if (s && i) {
350
+ const n = s.querySelector("ue-select");
351
+ n && i.appendChild(n);
379
352
  }
380
353
  }
381
354
  }
@@ -386,11 +359,11 @@ class Ut extends rt {
386
359
  * previously-moved toggles, making them permanently lost.
387
360
  */
388
361
  _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);
362
+ h.forEach((r) => {
363
+ const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
364
+ if (o) {
365
+ const s = o.querySelector("ue-switcher");
366
+ s && e && e.appendChild(s);
394
367
  }
395
368
  });
396
369
  }
@@ -399,11 +372,11 @@ class Ut extends rt {
399
372
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
400
373
  */
401
374
  _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);
375
+ for (let r = 0; r < _; r++) {
376
+ const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
377
+ if (s) {
378
+ const i = s.querySelector("ue-select");
379
+ i && o && o.appendChild(i);
407
380
  }
408
381
  }
409
382
  }
@@ -413,10 +386,10 @@ class Ut extends rt {
413
386
  */
414
387
  _moveDeleteButtonsIntoItems(t, r) {
415
388
  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);
389
+ const o = `${E}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
390
+ if (s && i) {
391
+ const n = s.querySelector("ue-button");
392
+ n && i.appendChild(n);
420
393
  }
421
394
  }
422
395
  }
@@ -425,11 +398,11 @@ class Ut extends rt {
425
398
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
426
399
  */
427
400
  _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);
401
+ for (let r = 0; r < _; r++) {
402
+ const e = `${E}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
403
+ if (s) {
404
+ const i = s.querySelector("ue-button");
405
+ i && o && o.appendChild(i);
433
406
  }
434
407
  }
435
408
  }
@@ -439,10 +412,10 @@ class Ut extends rt {
439
412
  */
440
413
  _moveReorderIconsIntoItems(t, r) {
441
414
  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);
415
+ const o = `${R}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
416
+ if (s && i) {
417
+ const n = s.querySelector("ue-button");
418
+ n && i.appendChild(n);
446
419
  }
447
420
  }
448
421
  }
@@ -451,12 +424,12 @@ class Ut extends rt {
451
424
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
452
425
  */
453
426
  _rescueReorderIconsToStore(t) {
454
- const r = m.length + f;
427
+ const r = h.length + _;
455
428
  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);
429
+ const o = `${R}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
430
+ if (i) {
431
+ const n = i.querySelector("ue-button");
432
+ n && s && s.appendChild(n);
460
433
  }
461
434
  }
462
435
  }
@@ -468,83 +441,41 @@ class Ut extends rt {
468
441
  const { signal: t } = this.eventController, r = this._getControlContainer();
469
442
  if (!r)
470
443
  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);
444
+ const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
445
+ e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
446
+ const s = new Set(this._readCustomAttributesFromNode()), i = this._getAddableFilters().find((n) => !s.has(n.attributeName));
447
+ i && this._onAddAttribute(i.attributeName, i.displayName);
475
448
  }, { signal: t });
476
449
  }
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
450
  _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) => {
515
- 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 ?? ""));
451
+ let e = null, o = null;
452
+ t.addEventListener("dragstart", (s) => {
453
+ var c;
454
+ const n = s.target.closest(".orderable-item");
455
+ n && (e = n, n.classList.add("dragging"), (c = s.dataTransfer) == null || c.setData("text/plain", n.dataset.key || ""));
521
456
  }, { 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)
525
- return;
526
- const c = s(n);
527
- if (!c)
457
+ e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
458
+ }, { signal: r }), t.addEventListener("dragover", (s) => {
459
+ s.preventDefault();
460
+ const n = s.target.closest(".orderable-item"), c = n && n !== e ? n : null;
461
+ c !== o && (o == null || o.classList.remove("drag-over"), o = c, o == null || o.classList.add("drag-over"));
462
+ }, { signal: r }), t.addEventListener("drop", (s) => {
463
+ s.preventDefault();
464
+ const n = s.target.closest(".orderable-item");
465
+ if (!n || !e || n === e)
528
466
  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));
467
+ const c = n.getBoundingClientRect(), a = c.top + c.height / 2;
468
+ 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");
469
+ const u = t.querySelectorAll(".orderable-item"), m = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
470
+ this._onReorder(m), e = null;
540
471
  }, { signal: r });
541
472
  }
542
473
  _setupDeleteHandler(t, r) {
543
474
  t.addEventListener("click", (e) => {
544
- const o = e.target.closest(".custom-attr-delete");
545
- if (!o)
475
+ const s = e.target.closest(".custom-attr-delete");
476
+ if (!s)
546
477
  return;
547
- const s = o.closest("[data-custom-index]"), n = s == null ? void 0 : s.dataset.customIndex;
478
+ const i = s.closest("[data-custom-index]"), n = i == null ? void 0 : i.dataset.customIndex;
548
479
  n !== void 0 && this._onDeleteCustomAttribute(Number(n));
549
480
  }, { signal: r });
550
481
  }
@@ -552,10 +483,10 @@ class Ut extends rt {
552
483
  // Actions (Add, Delete, Reorder)
553
484
  // ========================================================================
554
485
  _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();
486
+ const e = `${d}${t}`, o = this._readCompositionFromNode();
487
+ o.push(e);
488
+ const s = [...this._readCustomAttributesFromNode(), t];
489
+ this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
559
490
  }
560
491
  /**
561
492
  * Removes a single custom attribute by its index in the customAttrs array.
@@ -565,32 +496,27 @@ class Ut extends rt {
565
496
  const r = this._readCustomAttributesFromNode();
566
497
  if (r[t] === void 0)
567
498
  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();
499
+ const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((c, a) => a !== s), n = r.filter((c, a) => a !== t);
500
+ this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
570
501
  }
571
502
  /**
572
503
  * Handles changing a custom attribute's selection via its inline _GuSelect.
573
504
  * Uses the customIndex to target only the specific instance, supporting duplicates.
574
505
  */
575
506
  _onCustomAttributeChanged(t, r) {
576
- const e = this._readCustomAttributesFromNode(), i = e[t];
577
- if (i === void 0 || i === r)
507
+ const e = this._readCustomAttributesFromNode(), o = e[t];
508
+ if (o === void 0 || o === r)
578
509
  return;
579
- const o = `${p}${r}`, s = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(s, t);
580
- n !== -1 && (s[n] = o), e[t] = r;
510
+ const s = `${d}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
511
+ n !== -1 && (i[n] = s), e[t] = r;
581
512
  const c = this._getDisplayNameForAttribute(r);
582
- this._updateBothAttributes(s, e), this._injectCustomAttributeHtml(r, c, o, s), this._renderOrderableItems(s, e), this._initializeCustomSelects(e);
513
+ this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, c, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
583
514
  }
584
515
  _onReorder(t) {
585
- const r = t.filter((e) => e.startsWith(p)).map((e) => e.substring(p.length));
516
+ const r = t.filter((e) => e.startsWith(d)).map((e) => e.substring(d.length));
586
517
  this.reorderInProgress = !0;
587
518
  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
- });
519
+ this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
594
520
  } finally {
595
521
  this.reorderInProgress = !1;
596
522
  }
@@ -599,67 +525,67 @@ class Ut extends rt {
599
525
  // ========================================================================
600
526
  // HTML Injection / Removal (Product Card DOM)
601
527
  // ========================================================================
602
- _injectCustomAttributeHtml(t, r, e, i) {
528
+ _injectCustomAttributeHtml(t, r, e, o) {
603
529
  if (!this.currentNode)
604
530
  return;
605
- this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, i) : this._injectListAttributeRow(t, r, e, i);
531
+ this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
606
532
  }
607
- _injectGridAttributeRow(t, r, e, i) {
608
- const o = this.currentNode.querySelectorAll(H);
609
- if (!(o != null && o.length))
533
+ _injectGridAttributeRow(t, r, e, o) {
534
+ const s = this.currentNode.querySelectorAll(L);
535
+ if (!(s != null && s.length))
610
536
  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(
537
+ const i = $.getConfig(this.currentNode), c = `0 ${Math.floor(i.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
538
+ let u = 0;
539
+ s.forEach((m) => {
540
+ var k;
541
+ const b = m.querySelector(A), I = ((k = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : k.length) || 1, B = (100 / I).toFixed(2), { bgStyle: W, bgAttr: K } = this._extractSegmentBgFromCard(m), O = l > 0 ? Math.min(I, l - u) : I, z = o.map((q) => {
542
+ if (q === e) {
543
+ const G = Array.from(
544
+ { length: O },
545
+ (Ct, X) => {
546
+ const J = this._resolveAttributeContent(
621
547
  t,
622
548
  r,
623
- d + Q
549
+ u + X
624
550
  );
625
551
  return this._getGridCellHtml(
626
552
  t,
627
- Z,
628
- q,
629
- G,
630
- z,
553
+ J,
554
+ B,
555
+ W,
556
+ K,
631
557
  c
632
558
  );
633
559
  }
634
- ).join(""), J = ut(q, c).repeat(C - D);
635
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${O}="1">${X}${J}</tr>`;
560
+ ).join(""), Y = dt(B, c).repeat(I - O);
561
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${N}="1">${G}${Y}</tr>`;
636
562
  }
637
- const L = u.querySelector(
638
- `${T}[${y}="${B}"]`
563
+ const D = m.querySelector(
564
+ `${A}[${y}="${q}"]`
639
565
  );
640
- return L && "getOuterHTML" in L ? L.getOuterHTML() : "";
566
+ return D && "getOuterHTML" in D ? D.getOuterHTML() : "";
641
567
  }).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}`));
568
+ u += O, l > 0 && u >= l && (u = 0), a.modifyHtml(m).setInnerHtml(z);
569
+ }), a.apply(new C(`${this.api.translate("Add custom attribute")}: ${r}`));
644
570
  }
645
- _injectListAttributeRow(t, r, e, i) {
646
- const o = this.currentNode.querySelectorAll(j);
647
- if (!(o != null && o.length))
571
+ _injectListAttributeRow(t, r, e, o) {
572
+ const s = this.currentNode.querySelectorAll(V);
573
+ if (!(s != null && s.length))
648
574
  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);
575
+ const i = o.filter((c) => c !== H && c !== U), n = this.api.getDocumentModifier();
576
+ s.forEach((c, a) => {
577
+ const l = i.map((u) => {
578
+ if (u === e) {
579
+ const b = this._resolveAttributeContent(t, r, a);
580
+ return this._getListRowHtml(t, b, e);
655
581
  }
656
- const u = c.querySelector(
657
- `${T}[${y}="${d}"]`
582
+ const m = c.querySelector(
583
+ `${A}[${y}="${u}"]`
658
584
  );
659
- return u && "getOuterHTML" in u ? u.getOuterHTML() : "";
585
+ return m && "getOuterHTML" in m ? m.getOuterHTML() : "";
660
586
  }).join("");
661
- n.modifyHtml(c).setInnerHtml(a);
662
- }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
587
+ n.modifyHtml(c).setInnerHtml(l);
588
+ }), n.apply(new C(`${this.api.translate("Add custom attribute")}: ${r}`));
663
589
  }
664
590
  /**
665
591
  * Removes a custom attribute by rebuilding product card content without it.
@@ -670,19 +596,19 @@ class Ut extends rt {
670
596
  return;
671
597
  const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
672
598
  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);
599
+ const o = this.currentNode.querySelectorAll(L);
600
+ o == null || o.forEach((s) => {
601
+ const i = this._buildCompositionHtml(s, t);
602
+ e.modifyHtml(s).setInnerHtml(i);
677
603
  });
678
604
  } 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);
605
+ const o = t.filter((i) => i !== H && i !== U), s = this.currentNode.querySelectorAll(V);
606
+ s == null || s.forEach((i) => {
607
+ const n = this._buildCompositionHtml(i, o);
608
+ e.modifyHtml(i).setInnerHtml(n);
683
609
  });
684
610
  }
685
- e.apply(new A(this.api.translate("Remove custom attribute")));
611
+ e.apply(new C(this.api.translate("Remove custom attribute")));
686
612
  }
687
613
  // ========================================================================
688
614
  // DOM Mutation (Block Root Attributes, Reorder)
@@ -695,7 +621,13 @@ class Ut extends rt {
695
621
  * producing a flicker on the custom attribute dropdowns.
696
622
  */
697
623
  _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")));
624
+ if (!this.currentNode)
625
+ return;
626
+ const e = {
627
+ ...$.getConfig(this.currentNode),
628
+ composition: t
629
+ };
630
+ this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(x, t.join(",")).setAttribute(F, JSON.stringify(r)).setNodeConfig(e).apply(new C(this.api.translate("Update card composition")));
699
631
  }
700
632
  /**
701
633
  * Reorders attribute rows within each product card based on composition order.
@@ -704,23 +636,23 @@ class Ut extends rt {
704
636
  _reorderProductAttributes(t) {
705
637
  if (!this.currentNode)
706
638
  return;
707
- const r = this.currentNode.querySelectorAll(H);
639
+ const r = this.currentNode.querySelectorAll(L);
708
640
  if (!(r != null && r.length))
709
641
  return;
710
642
  const e = this.api.getDocumentModifier();
711
- r.forEach((i) => {
712
- const o = this._buildCompositionHtml(i, t);
713
- e.modifyHtml(i).setInnerHtml(o);
714
- }), e.apply(new A(this.api.translate("Reorder product attributes")));
643
+ r.forEach((o) => {
644
+ const s = this._buildCompositionHtml(o, t);
645
+ e.modifyHtml(o).setInnerHtml(s);
646
+ }), e.apply(new C(this.api.translate("Reorder product attributes")));
715
647
  }
716
648
  /**
717
649
  * Builds HTML string with attributes ordered according to composition.
718
650
  * Queries existing rows from the container by data-attribute-type.
719
651
  */
720
652
  _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;
653
+ return r.reduce((e, o) => {
654
+ const s = t.querySelector(`${A}[${y}="${o}"]`);
655
+ return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
724
656
  }, "");
725
657
  }
726
658
  // ========================================================================
@@ -729,14 +661,19 @@ class Ut extends rt {
729
661
  _applyVisibilityToBlock(t, r) {
730
662
  if (!this.currentNode)
731
663
  return;
732
- const e = this.currentNode.querySelectorAll(`${T}[${y}="${t}"]`);
664
+ const e = this.currentNode.querySelectorAll(`${A}[${y}="${t}"]`);
733
665
  if (!(e != null && e.length))
734
666
  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));
667
+ 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();
668
+ e.forEach((a) => {
669
+ const l = ft(a), u = r ? l : "none";
670
+ n.modifyHtml(a).setStyle("display", u).setAttribute(N, o);
671
+ });
672
+ const c = {
673
+ ...$.getConfig(this.currentNode),
674
+ visibility: { ...this._readVisibilityFromRows(), [t]: r }
675
+ };
676
+ n.modifyHtml(this.currentNode).setNodeConfig(c), n.apply(new C(i));
740
677
  }
741
678
  // ========================================================================
742
679
  // Utilities
@@ -748,16 +685,16 @@ class Ut extends rt {
748
685
  */
749
686
  _findNthCustomKeyIndex(t, r) {
750
687
  let e = 0;
751
- for (let i = 0; i < t.length; i++)
752
- if (t[i].startsWith(p)) {
688
+ for (let o = 0; o < t.length; o++)
689
+ if (t[o].startsWith(d)) {
753
690
  if (e === r)
754
- return i;
691
+ return o;
755
692
  e++;
756
693
  }
757
694
  return -1;
758
695
  }
759
696
  _getCurrentLayout() {
760
- return this.store.recommendationConfigs.orientation || yt(this.currentNode);
697
+ return this.store.recommendationConfigs.orientation || _t(this.currentNode);
761
698
  }
762
699
  /**
763
700
  * Extracts background color properties from existing card elements.
@@ -766,21 +703,21 @@ class Ut extends rt {
766
703
  * Used when injecting new attribute cells to match the card's current background.
767
704
  */
768
705
  _extractSegmentBgFromCard(t) {
769
- var i;
706
+ var o;
770
707
  const r = t.querySelector(".product-card-segment");
771
708
  if (r && "getAttribute" in r) {
772
- const s = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
773
- if (s) {
709
+ const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
710
+ if (i) {
774
711
  const n = r.getAttribute("bgcolor") || "";
775
- return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
712
+ return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
776
713
  }
777
714
  }
778
- const e = (i = this.currentNode) == null ? void 0 : i.querySelector(".product-card-wrapper");
715
+ const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
779
716
  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 };
717
+ const s = e.getStyle("background-color");
718
+ if (s && s !== "transparent") {
719
+ const i = "getAttribute" in e && e.getAttribute("bgcolor") || "";
720
+ return { bgStyle: `background-color: ${s};`, bgAttr: i };
784
721
  }
785
722
  }
786
723
  return { bgStyle: "", bgAttr: "" };
@@ -790,18 +727,17 @@ class Ut extends rt {
790
727
  return t ? t.querySelector("[data-card-composition-control]") : null;
791
728
  }
792
729
  /**
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.)
730
+ * Adds/removes orderable-disabled class based on layout orientation.
731
+ * List layout hides drag handles via CSS and disables draggable attribute
732
+ * to prevent native browser drag-and-drop from working without the handle.
797
733
  */
798
734
  _updateOrderableState() {
799
- const t = this._getControlContainer();
800
- if (!t)
735
+ const r = this._getCurrentLayout() === "list", e = this._getControlContainer();
736
+ if (!e)
801
737
  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");
738
+ const o = e.querySelector("[data-composition-list]");
739
+ o && (o.classList.toggle("orderable-disabled", r), o.querySelectorAll(".orderable-item").forEach((s) => {
740
+ s.setAttribute("draggable", r ? "false" : "true");
805
741
  }));
806
742
  }
807
743
  /**
@@ -809,11 +745,11 @@ class Ut extends rt {
809
745
  * or when all available filters have already been added (no unused attributes left).
810
746
  */
811
747
  _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));
748
+ const t = this._readCustomAttributesFromNode(), r = t.length >= _, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
813
749
  this.api.setUIEAttribute(
814
- K.ADD_ATTRIBUTE,
815
- E.BUTTON.disabled,
816
- r || o ? "true" : "false"
750
+ j.ADD_ATTRIBUTE,
751
+ v.BUTTON.disabled,
752
+ r || s ? "true" : "false"
817
753
  );
818
754
  }
819
755
  /**
@@ -826,8 +762,8 @@ class Ut extends rt {
826
762
  this.unsubscribeStore = this.store.$subscribe(() => {
827
763
  const e = this.store.recommendationConfigs.orientation;
828
764
  e !== t && (t = e, this._updateOrderableState());
829
- const i = Object.keys(this.store.filterList).sort().join(",");
830
- i !== r && (r = i, this._initializeComposition());
765
+ const o = Object.keys(this.store.filterList).sort().join(",");
766
+ o !== r && (r = o, this._initializeComposition());
831
767
  });
832
768
  }
833
769
  /**
@@ -843,7 +779,7 @@ class Ut extends rt {
843
779
  */
844
780
  _getDisplayNameForAttribute(t) {
845
781
  const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
846
- return r ? r.displayName : pt(t);
782
+ return r ? r.displayName : ht(t);
847
783
  }
848
784
  /**
849
785
  * Resolves the display content for a custom attribute cell.
@@ -851,29 +787,29 @@ class Ut extends rt {
851
787
  */
852
788
  _resolveAttributeContent(t, r, e) {
853
789
  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;
790
+ 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];
791
+ return gt(i) ?? r;
856
792
  }
857
- _getGridCellHtml(t, r, e, i = "", o = "", s = "") {
858
- const n = `${p}${t}`, c = V(ct, [n], this.store.filterList), l = {
793
+ _getGridCellHtml(t, r, e, o = "", s = "", i = "") {
794
+ const n = `${d}${t}`, c = M(ct, [n], this.store.filterList), a = {
859
795
  [t]: r,
860
796
  product_attributes: { [t]: r }
861
797
  };
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;
798
+ let l = c[n](a);
799
+ return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
800
+ `padding: ${ut}`,
801
+ `padding: ${i}`
802
+ )), 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
803
  }
868
804
  _getListRowHtml(t, r, e) {
869
- const i = V(mt, [e], this.store.filterList), o = {
805
+ const o = M(mt, [e], this.store.filterList), s = {
870
806
  [t]: r,
871
807
  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>`;
808
+ }, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
809
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${N}="1">${n}</tr>`;
874
810
  }
875
811
  }
876
812
  export {
877
- St as COMPOSITION_CONTROL_BLOCK_ID,
878
- Ut as RecommendationCardCompositionControl
813
+ bt as COMPOSITION_CONTROL_BLOCK_ID,
814
+ Ht as RecommendationCardCompositionControl
879
815
  };