@useinsider/guido 3.7.2-beta.1489585 → 3.7.2-beta.2220fb0

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 (62) hide show
  1. package/dist/@types/config/schemas.js +70 -66
  2. package/dist/composables/usePreviewMode.js +15 -14
  3. package/dist/composables/useRecommendationPreview.js +100 -0
  4. package/dist/config/compiler/recommendationCompilerRules.js +1 -1
  5. package/dist/config/compiler/utils/recommendationCompilerUtils.js +92 -78
  6. package/dist/config/migrator/recommendation/htmlBuilder.js +59 -58
  7. package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
  8. package/dist/extensions/Blocks/Recommendation/block.js +60 -41
  9. package/dist/extensions/Blocks/Recommendation/canvasPreview.css.js +16 -0
  10. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
  11. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +10 -11
  12. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +369 -288
  13. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +96 -82
  14. package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +39 -30
  15. package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
  16. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +34 -28
  17. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +338 -288
  18. package/dist/extensions/Blocks/Recommendation/extension.js +30 -30
  19. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
  20. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
  21. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +2 -3
  22. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +7 -5
  23. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +217 -155
  24. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +31 -56
  25. package/dist/extensions/Blocks/Recommendation/templates/index.js +10 -29
  26. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +135 -145
  27. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +22 -43
  28. package/dist/extensions/Blocks/Recommendation/templates/utils.js +96 -109
  29. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +19 -24
  30. package/dist/extensions/Blocks/Recommendation/utils/tagName.js +22 -30
  31. package/dist/extensions/Blocks/controlFactories.js +133 -159
  32. package/dist/src/@types/config/schemas.d.ts +16 -0
  33. package/dist/src/composables/useConfig.d.ts +4 -0
  34. package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
  35. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
  36. package/dist/src/extensions/Blocks/Items/controls/index.d.ts +1 -1
  37. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  38. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  39. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +0 -2
  40. package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +1 -1
  41. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +29 -3
  42. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
  43. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
  44. package/dist/src/extensions/Blocks/Recommendation/controls/main/layoutOrientation.d.ts +1 -2
  45. package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
  46. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +47 -20
  47. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
  48. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +16 -0
  49. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  50. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
  51. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +13 -0
  52. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  53. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +47 -163
  54. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
  55. package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -15
  56. package/dist/src/extensions/Blocks/Recommendation/utils/stylePreserver.d.ts +113 -0
  57. package/dist/src/extensions/Blocks/Recommendation/utils/tagName.d.ts +9 -29
  58. package/dist/src/extensions/Blocks/controlFactories.d.ts +1 -11
  59. package/dist/src/stores/config.d.ts +36 -0
  60. package/package.json +1 -1
  61. package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +0 -216
  62. package/dist/src/extensions/Blocks/Recommendation/utils/captureStyleTemplates.d.ts +0 -78
@@ -1,103 +1,103 @@
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";
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";
9
9
  import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
10
- import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as ut, buildFillerCell as dt } from "../../templates/grid/elementRenderer.js";
10
+ import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as dt, buildFillerCell as ut } from "../../templates/grid/elementRenderer.js";
11
11
  import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
12
- import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as _t, buildElementRenderer as w } from "../../templates/utils.js";
13
- import { getTableDisplayValue as ft } from "../../utils/tagName.js";
14
- import { getCurrentLayout as gt } from "../main/utils.js";
15
- const bt = "ui-elements-recommendation-card-composition", C = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", M = ".product-info-cell > table > tbody", V = "data-card-composition", y = "data-attribute-type", v = "data-visibility", x = {
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 = {
16
16
  ADD_ATTRIBUTE: "addAttribute"
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" },
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
23
  { key: st, label: "Omnibus Discount" },
24
24
  { key: U, label: "Product Button" }
25
- ], yt = new Set(h.map((p) => p.key)), T = "customAttr_", R = "deleteAttr_";
26
- class Ut extends Z {
25
+ ], At = new Set(m.map((g) => g.key)), $ = "customAttr_", R = "deleteAttr_";
26
+ class Ut extends rt {
27
27
  constructor() {
28
28
  super(...arguments);
29
- S(this, "store", lt());
30
- S(this, "unsubscribeStore", null);
31
- S(this, "eventController", null);
29
+ I(this, "store", lt());
30
+ I(this, "unsubscribeStore", null);
31
+ I(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
- S(this, "reorderInProgress", !1);
36
+ I(this, "reorderInProgress", !1);
37
37
  }
38
38
  getId() {
39
- return bt;
39
+ return St;
40
40
  }
41
41
  // ========================================================================
42
42
  // Lifecycle
43
43
  // ========================================================================
44
44
  getTemplate() {
45
- const t = h.map((l) => `
46
- <div data-toggle-key="${l.key}" style="display: none;">
47
- ${this._GuToggle(`visibility_${l.key}`)}
45
+ const t = m.map((a) => `
46
+ <div data-toggle-key="${a.key}" style="display: none;">
47
+ ${this._GuToggle(`visibility_${a.key}`)}
48
48
  </div>
49
49
  `).join(""), r = Array.from(
50
- { length: g },
51
- (l, u) => `
52
- <div data-custom-select-key="${T}${u}" style="display: none;">
50
+ { length: f },
51
+ (a, d) => `
52
+ <div data-custom-select-key="${$}${d}" style="display: none;">
53
53
  ${this._GuSelect({
54
- name: `${T}${u}`,
54
+ name: `${$}${d}`,
55
55
  placeholder: this.api.translate("Select Attribute"),
56
56
  options: []
57
57
  })}
58
58
  </div>
59
59
  `
60
- ).join(""), e = h.length + g, o = Array.from(
60
+ ).join(""), e = m.length + f, i = Array.from(
61
61
  { length: e },
62
- (l, u) => `
63
- <div data-reorder-icon-key="${E}${u}" style="display: none;">
64
- <${f.BUTTON}
62
+ (a, d) => `
63
+ <div data-reorder-icon-key="${N}${d}" style="display: none;">
64
+ <${_.BUTTON}
65
65
  class="drag-handle-btn flat-inline flat-white"
66
- ${I.BUTTON.name}="${E}${u}"
66
+ ${E.BUTTON.name}="${N}${d}"
67
67
  >
68
- <${f.ICON}
68
+ <${_.ICON}
69
69
  src="reorder"
70
70
  class="icon-button"
71
- ></${f.ICON}>
72
- </${f.BUTTON}>
71
+ ></${_.ICON}>
72
+ </${_.BUTTON}>
73
73
  </div>
74
74
  `
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}
75
+ ).join(""), o = Array.from(
76
+ { length: f },
77
+ (a, d) => `
78
+ <div data-custom-delete-key="${R}${d}" style="display: none;">
79
+ <${_.BUTTON}
80
80
  class="custom-attr-delete flat-inline flat-white"
81
- ${I.BUTTON.name}="${R}${u}"
81
+ ${E.BUTTON.name}="${R}${d}"
82
82
  >
83
- <${f.ICON}
83
+ <${_.ICON}
84
84
  src="delete"
85
85
  class="icon-button"
86
- ></${f.ICON}>
87
- </${f.BUTTON}>
86
+ ></${_.ICON}>
87
+ </${_.BUTTON}>
88
88
  </div>
89
89
  `
90
- ).join(""), i = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
90
+ ).join(""), s = "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
- ), a = this.api.translate("For more information, you can"), c = this.api.translate("visit Academy");
92
+ ), c = this.api.translate("For more information, you can"), l = 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
- ${a}
98
+ ${c}
99
99
  <!-- cspell:disable-next-line -->
100
- <a href="${i}" target="_blank" rel="noopener noreferrer">${c}</a>.
100
+ <a href="${s}" target="_blank" rel="noopener noreferrer">${l}</a>.
101
101
  </p>
102
102
  </div>
103
103
 
@@ -110,17 +110,17 @@ class Ut extends Z {
110
110
  </div>
111
111
 
112
112
  <div class="custom-delete-store" style="display: none;">
113
- ${s}
113
+ ${o}
114
114
  </div>
115
115
 
116
116
  <div class="reorder-icon-store" style="display: none;">
117
- ${o}
117
+ ${i}
118
118
  </div>
119
119
 
120
120
  <div class="orderable-list" data-composition-list></div>
121
121
 
122
122
  ${this._GuButton({
123
- name: x.ADD_ATTRIBUTE,
123
+ name: K.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 Z {
140
140
  // Initialization
141
141
  // ========================================================================
142
142
  _initializeComposition() {
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();
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();
145
145
  }
146
146
  _registerValueChangeListeners() {
147
- h.forEach((t) => {
147
+ m.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 < g; t++) {
153
- const r = `${T}${t}`, e = t;
154
- this.api.onValueChanged(r, (o) => {
155
- this._onCustomAttributeChanged(e, o);
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);
156
156
  });
157
157
  }
158
158
  }
@@ -161,14 +161,14 @@ class Ut extends Z {
161
161
  // ========================================================================
162
162
  _readCompositionFromNode() {
163
163
  if (!this.currentNode || !("getAttribute" in this.currentNode))
164
- return [...P];
165
- const t = this.currentNode.getAttribute(V);
166
- return t ? t.split(",").filter(Boolean) : [...P];
164
+ return [...x];
165
+ const t = this.currentNode.getAttribute(W);
166
+ return t ? t.split(",").filter(Boolean) : [...x];
167
167
  }
168
168
  _readCustomAttributesFromNode() {
169
169
  if (!this.currentNode || !("getAttribute" in this.currentNode))
170
170
  return [];
171
- const t = this.currentNode.getAttribute(q);
171
+ const t = this.currentNode.getAttribute(F);
172
172
  if (!t)
173
173
  return [];
174
174
  try {
@@ -180,31 +180,31 @@ class Ut extends Z {
180
180
  _readVisibilityFromRows() {
181
181
  if (!this.currentNode)
182
182
  return this._getDefaultVisibilities();
183
- const t = Array.from(this.currentNode.querySelectorAll(C)), r = this._extractVisibilityFromRows(t);
183
+ const t = Array.from(this.currentNode.querySelectorAll(T)), r = this._extractVisibilityFromRows(t);
184
184
  return this._mergeWithDefaults(r);
185
185
  }
186
186
  _getDefaultVisibilities() {
187
- return { ...F };
187
+ return { ...M };
188
188
  }
189
189
  _extractVisibilityFromRows(t) {
190
190
  const r = {};
191
191
  return t.forEach((e) => {
192
192
  if (!("getAttribute" in e))
193
193
  return;
194
- const o = e.getAttribute(y), s = e.getAttribute(v);
195
- o && s !== null && (r[o] = this._parseVisibilityValue(s));
194
+ const i = e.getAttribute(y), o = e.getAttribute(O);
195
+ i && o !== null && (r[i] = this._parseVisibilityValue(o));
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(F).forEach(([r, e]) => {
202
+ return Object.entries(M).forEach(([r, e]) => {
203
203
  r in t || (t[r] = e);
204
204
  }), t;
205
205
  }
206
206
  _buildVisibilityValues(t) {
207
- return h.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
207
+ return m.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
208
208
  }
209
209
  // ========================================================================
210
210
  // UI Rendering (Orderable List)
@@ -218,24 +218,30 @@ class Ut extends Z {
218
218
  const e = this._getControlContainer();
219
219
  if (!e)
220
220
  return !1;
221
- const o = e.querySelector("[data-composition-list]");
222
- if (!o || this._tryReorderInPlace(o, t))
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))
223
226
  return !1;
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++);
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
236
  }
231
- if (c.startsWith(m)) {
232
- const l = c.substring(m.length);
233
- if (s.has(l))
234
- return this._createCustomItemHtml(c, i++, n++);
237
+ if (u.startsWith(p)) {
238
+ const h = u.substring(p.length);
239
+ if (n.has(h))
240
+ return this._createCustomItemHtml(u, l++, a++);
235
241
  }
236
242
  return "";
237
243
  }).join("");
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;
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;
239
245
  }
240
246
  /**
241
247
  * Attempts to reorder existing orderable-item elements to match the composition order.
@@ -247,27 +253,27 @@ class Ut extends Z {
247
253
  const e = Array.from(t.querySelectorAll(".orderable-item"));
248
254
  if (e.length !== r.length)
249
255
  return !1;
250
- const o = e.map((c) => c.dataset.key).filter(Boolean);
251
- if (o.length !== r.length)
256
+ const i = e.map((l) => l.dataset.key).filter(Boolean);
257
+ if (i.length !== r.length)
252
258
  return !1;
253
- const s = [...o].sort().join(","), i = [...r].sort().join(",");
254
- if (s !== i || r.some((c) => c.startsWith(m)))
259
+ const o = [...i].sort().join(","), s = [...r].sort().join(",");
260
+ if (o !== s || r.some((l) => l.startsWith(p)))
255
261
  return !1;
256
262
  const n = /* @__PURE__ */ new Map();
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);
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);
262
268
  }
263
269
  });
264
- const a = /* @__PURE__ */ new Map();
265
- return r.forEach((c) => {
266
- const l = n.get(c);
267
- if (!l)
270
+ const c = /* @__PURE__ */ new Map();
271
+ return r.forEach((l) => {
272
+ const a = n.get(l);
273
+ if (!a)
268
274
  return;
269
- const u = a.get(c) || 0;
270
- a.set(c, u + 1), l[u] && t.appendChild(l[u]);
275
+ const d = c.get(l) || 0;
276
+ c.set(l, d + 1), a[d] && t.appendChild(a[d]);
271
277
  }), !0;
272
278
  }
273
279
  _createBuiltInItemHtml(t, r) {
@@ -279,6 +285,33 @@ class Ut extends Z {
279
285
  </div>
280
286
  `;
281
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
+ }
282
315
  _createCustomItemHtml(t, r, e) {
283
316
  return `
284
317
  <div class="orderable-item" draggable="true"
@@ -299,10 +332,10 @@ class Ut extends Z {
299
332
  _getSelectOptions(t, r = []) {
300
333
  const e = this._getAddableFilters();
301
334
  if (e.length > 0) {
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
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
306
339
  }));
307
340
  }
308
341
  return [{ text: this._getDisplayNameForAttribute(t), value: t }];
@@ -315,8 +348,8 @@ class Ut extends Z {
315
348
  _initializeCustomSelects(t) {
316
349
  t.length !== 0 && setTimeout(() => {
317
350
  t.forEach((r, e) => {
318
- const o = `${T}${e}`, s = this._getSelectOptions(r, t);
319
- this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
351
+ const i = `${$}${e}`, o = this._getSelectOptions(r, t);
352
+ this.api.setUIEAttribute(i, E.SELECTPICKER.items, o), this.api.updateValues({ [i]: r });
320
353
  });
321
354
  }, 0);
322
355
  }
@@ -325,11 +358,11 @@ class Ut extends Z {
325
358
  * Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
326
359
  */
327
360
  _moveTogglesIntoItems(t) {
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);
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);
333
366
  }
334
367
  });
335
368
  }
@@ -339,10 +372,10 @@ class Ut extends Z {
339
372
  */
340
373
  _moveSelectsIntoItems(t, r) {
341
374
  for (let e = 0; e < r; e++) {
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);
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);
346
379
  }
347
380
  }
348
381
  }
@@ -353,11 +386,11 @@ class Ut extends Z {
353
386
  * previously-moved toggles, making them permanently lost.
354
387
  */
355
388
  _rescueTogglesToStore(t) {
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);
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);
361
394
  }
362
395
  });
363
396
  }
@@ -366,11 +399,11 @@ class Ut extends Z {
366
399
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
367
400
  */
368
401
  _rescueSelectsToStore(t) {
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);
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);
374
407
  }
375
408
  }
376
409
  }
@@ -380,10 +413,10 @@ class Ut extends Z {
380
413
  */
381
414
  _moveDeleteButtonsIntoItems(t, r) {
382
415
  for (let e = 0; e < r; e++) {
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);
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);
387
420
  }
388
421
  }
389
422
  }
@@ -392,11 +425,11 @@ class Ut extends Z {
392
425
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
393
426
  */
394
427
  _rescueDeleteButtonsToStore(t) {
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);
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);
400
433
  }
401
434
  }
402
435
  }
@@ -406,10 +439,10 @@ class Ut extends Z {
406
439
  */
407
440
  _moveReorderIconsIntoItems(t, r) {
408
441
  for (let e = 0; e < r; e++) {
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);
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);
413
446
  }
414
447
  }
415
448
  }
@@ -418,12 +451,12 @@ class Ut extends Z {
418
451
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
419
452
  */
420
453
  _rescueReorderIconsToStore(t) {
421
- const r = h.length + g;
454
+ const r = m.length + f;
422
455
  for (let e = 0; e < r; e++) {
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);
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);
427
460
  }
428
461
  }
429
462
  }
@@ -435,41 +468,83 @@ class Ut extends Z {
435
468
  const { signal: t } = this.eventController, r = this._getControlContainer();
436
469
  if (!r)
437
470
  return;
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);
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);
442
475
  }, { signal: t });
443
476
  }
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
+ }
444
492
  _setupDragAndDrop(t, r) {
445
- let e = null, o = null;
446
- t.addEventListener("dragstart", (s) => {
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) => {
447
515
  var a;
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 || ""));
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 ?? ""));
450
521
  }, { signal: r }), t.addEventListener("dragend", () => {
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)
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)
460
525
  return;
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;
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));
465
540
  }, { signal: r });
466
541
  }
467
542
  _setupDeleteHandler(t, r) {
468
543
  t.addEventListener("click", (e) => {
469
- const s = e.target.closest(".custom-attr-delete");
470
- if (!s)
544
+ const o = e.target.closest(".custom-attr-delete");
545
+ if (!o)
471
546
  return;
472
- const i = s.closest("[data-custom-index]"), n = i == null ? void 0 : i.dataset.customIndex;
547
+ const s = o.closest("[data-custom-index]"), n = s == null ? void 0 : s.dataset.customIndex;
473
548
  n !== void 0 && this._onDeleteCustomAttribute(Number(n));
474
549
  }, { signal: r });
475
550
  }
@@ -477,10 +552,10 @@ class Ut extends Z {
477
552
  // Actions (Add, Delete, Reorder)
478
553
  // ========================================================================
479
554
  _onAddAttribute(t, r) {
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();
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();
484
559
  }
485
560
  /**
486
561
  * Removes a single custom attribute by its index in the customAttrs array.
@@ -490,27 +565,32 @@ class Ut extends Z {
490
565
  const r = this._readCustomAttributesFromNode();
491
566
  if (r[t] === void 0)
492
567
  return;
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();
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();
495
570
  }
496
571
  /**
497
572
  * Handles changing a custom attribute's selection via its inline _GuSelect.
498
573
  * Uses the customIndex to target only the specific instance, supporting duplicates.
499
574
  */
500
575
  _onCustomAttributeChanged(t, r) {
501
- const e = this._readCustomAttributesFromNode(), o = e[t];
502
- if (o === void 0 || o === r)
576
+ const e = this._readCustomAttributesFromNode(), i = e[t];
577
+ if (i === void 0 || i === r)
503
578
  return;
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);
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);
508
583
  }
509
584
  _onReorder(t) {
510
- const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
585
+ const r = t.filter((e) => e.startsWith(p)).map((e) => e.substring(p.length));
511
586
  this.reorderInProgress = !0;
512
587
  try {
513
- this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
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
+ });
514
594
  } finally {
515
595
  this.reorderInProgress = !1;
516
596
  }
@@ -519,66 +599,66 @@ class Ut extends Z {
519
599
  // ========================================================================
520
600
  // HTML Injection / Removal (Product Card DOM)
521
601
  // ========================================================================
522
- _injectCustomAttributeHtml(t, r, e, o) {
602
+ _injectCustomAttributeHtml(t, r, e, i) {
523
603
  if (!this.currentNode)
524
604
  return;
525
- this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
605
+ this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, i) : this._injectListAttributeRow(t, r, e, i);
526
606
  }
527
- _injectGridAttributeRow(t, r, e, o) {
528
- const s = this.currentNode.querySelectorAll(L);
529
- if (!(s != null && s.length))
607
+ _injectGridAttributeRow(t, r, e, i) {
608
+ const o = this.currentNode.querySelectorAll(H);
609
+ if (!(o != null && o.length))
530
610
  return;
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(
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(
541
621
  t,
542
622
  r,
543
- u + Y
623
+ d + Q
544
624
  );
545
625
  return this._getGridCellHtml(
546
626
  t,
547
- X,
548
- B,
549
- j,
550
- W,
551
- a
627
+ Z,
628
+ q,
629
+ G,
630
+ z,
631
+ c
552
632
  );
553
633
  }
554
- ).join(""), G = dt(B, a).repeat($ - O);
555
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${z}${G}</tr>`;
634
+ ).join(""), J = ut(q, c).repeat(C - D);
635
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${O}="1">${X}${J}</tr>`;
556
636
  }
557
- const N = d.querySelector(
558
- `${C}[${y}="${k}"]`
637
+ const L = u.querySelector(
638
+ `${T}[${y}="${B}"]`
559
639
  );
560
- return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
640
+ return L && "getOuterHTML" in L ? L.getOuterHTML() : "";
561
641
  }).join("");
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}`));
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}`));
564
644
  }
565
- _injectListAttributeRow(t, r, e, o) {
566
- const s = this.currentNode.querySelectorAll(M);
567
- if (!(s != null && s.length))
645
+ _injectListAttributeRow(t, r, e, i) {
646
+ const o = this.currentNode.querySelectorAll(j);
647
+ if (!(o != null && o.length))
568
648
  return;
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);
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
655
  }
576
- const d = a.querySelector(
577
- `${C}[${y}="${u}"]`
656
+ const u = c.querySelector(
657
+ `${T}[${y}="${d}"]`
578
658
  );
579
- return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
659
+ return u && "getOuterHTML" in u ? u.getOuterHTML() : "";
580
660
  }).join("");
581
- n.modifyHtml(a).setInnerHtml(l);
661
+ n.modifyHtml(c).setInnerHtml(a);
582
662
  }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
583
663
  }
584
664
  /**
@@ -590,16 +670,16 @@ class Ut extends Z {
590
670
  return;
591
671
  const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
592
672
  if (r === "grid") {
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);
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);
597
677
  });
598
678
  } else {
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);
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);
603
683
  });
604
684
  }
605
685
  e.apply(new A(this.api.translate("Remove custom attribute")));
@@ -615,7 +695,7 @@ class Ut extends Z {
615
695
  * producing a flicker on the custom attribute dropdowns.
616
696
  */
617
697
  _updateBothAttributes(t, r) {
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")));
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")));
619
699
  }
620
700
  /**
621
701
  * Reorders attribute rows within each product card based on composition order.
@@ -624,13 +704,13 @@ class Ut extends Z {
624
704
  _reorderProductAttributes(t) {
625
705
  if (!this.currentNode)
626
706
  return;
627
- const r = this.currentNode.querySelectorAll(L);
707
+ const r = this.currentNode.querySelectorAll(H);
628
708
  if (!(r != null && r.length))
629
709
  return;
630
710
  const e = this.api.getDocumentModifier();
631
- r.forEach((o) => {
632
- const s = this._buildCompositionHtml(o, t);
633
- e.modifyHtml(o).setInnerHtml(s);
711
+ r.forEach((i) => {
712
+ const o = this._buildCompositionHtml(i, t);
713
+ e.modifyHtml(i).setInnerHtml(o);
634
714
  }), e.apply(new A(this.api.translate("Reorder product attributes")));
635
715
  }
636
716
  /**
@@ -638,9 +718,9 @@ class Ut extends Z {
638
718
  * Queries existing rows from the container by data-attribute-type.
639
719
  */
640
720
  _buildCompositionHtml(t, r) {
641
- return r.reduce((e, o) => {
642
- const s = t.querySelector(`${C}[${y}="${o}"]`);
643
- return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
721
+ return r.reduce((e, i) => {
722
+ const o = t.querySelector(`${T}[${y}="${i}"]`);
723
+ return o && "getOuterHTML" in o ? e + o.getOuterHTML() : e;
644
724
  }, "");
645
725
  }
646
726
  // ========================================================================
@@ -649,14 +729,14 @@ class Ut extends Z {
649
729
  _applyVisibilityToBlock(t, r) {
650
730
  if (!this.currentNode)
651
731
  return;
652
- const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
732
+ const e = this.currentNode.querySelectorAll(`${T}[${y}="${t}"]`);
653
733
  if (!(e != null && e.length))
654
734
  return;
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));
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));
660
740
  }
661
741
  // ========================================================================
662
742
  // Utilities
@@ -668,16 +748,16 @@ class Ut extends Z {
668
748
  */
669
749
  _findNthCustomKeyIndex(t, r) {
670
750
  let e = 0;
671
- for (let o = 0; o < t.length; o++)
672
- if (t[o].startsWith(m)) {
751
+ for (let i = 0; i < t.length; i++)
752
+ if (t[i].startsWith(p)) {
673
753
  if (e === r)
674
- return o;
754
+ return i;
675
755
  e++;
676
756
  }
677
757
  return -1;
678
758
  }
679
759
  _getCurrentLayout() {
680
- return this.store.recommendationConfigs.orientation || gt(this.currentNode);
760
+ return this.store.recommendationConfigs.orientation || yt(this.currentNode);
681
761
  }
682
762
  /**
683
763
  * Extracts background color properties from existing card elements.
@@ -686,21 +766,21 @@ class Ut extends Z {
686
766
  * Used when injecting new attribute cells to match the card's current background.
687
767
  */
688
768
  _extractSegmentBgFromCard(t) {
689
- var o;
769
+ var i;
690
770
  const r = t.querySelector(".product-card-segment");
691
771
  if (r && "getAttribute" in r) {
692
- const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
693
- if (i) {
772
+ const s = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
773
+ if (s) {
694
774
  const n = r.getAttribute("bgcolor") || "";
695
- return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
775
+ return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
696
776
  }
697
777
  }
698
- const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
778
+ const e = (i = this.currentNode) == null ? void 0 : i.querySelector(".product-card-wrapper");
699
779
  if (e && "getStyle" in e) {
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 };
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 };
704
784
  }
705
785
  }
706
786
  return { bgStyle: "", bgAttr: "" };
@@ -710,17 +790,18 @@ class Ut extends Z {
710
790
  return t ? t.querySelector("[data-card-composition-control]") : null;
711
791
  }
712
792
  /**
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.
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.)
716
797
  */
717
798
  _updateOrderableState() {
718
- const r = this._getCurrentLayout() === "list", e = this._getControlContainer();
719
- if (!e)
799
+ const t = this._getControlContainer();
800
+ if (!t)
720
801
  return;
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");
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");
724
805
  }));
725
806
  }
726
807
  /**
@@ -728,11 +809,11 @@ class Ut extends Z {
728
809
  * or when all available filters have already been added (no unused attributes left).
729
810
  */
730
811
  _updateAddButtonState() {
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));
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));
732
813
  this.api.setUIEAttribute(
733
- x.ADD_ATTRIBUTE,
734
- I.BUTTON.disabled,
735
- r || s ? "true" : "false"
814
+ K.ADD_ATTRIBUTE,
815
+ E.BUTTON.disabled,
816
+ r || o ? "true" : "false"
736
817
  );
737
818
  }
738
819
  /**
@@ -745,8 +826,8 @@ class Ut extends Z {
745
826
  this.unsubscribeStore = this.store.$subscribe(() => {
746
827
  const e = this.store.recommendationConfigs.orientation;
747
828
  e !== t && (t = e, this._updateOrderableState());
748
- const o = Object.keys(this.store.filterList).sort().join(",");
749
- o !== r && (r = o, this._initializeComposition());
829
+ const i = Object.keys(this.store.filterList).sort().join(",");
830
+ i !== r && (r = i, this._initializeComposition());
750
831
  });
751
832
  }
752
833
  /**
@@ -754,7 +835,7 @@ class Ut extends Z {
754
835
  * excluding default attributes already covered by built-in toggle items.
755
836
  */
756
837
  _getAddableFilters() {
757
- return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && it.has(t.attributeName)));
838
+ return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && nt.has(t.attributeName)));
758
839
  }
759
840
  /**
760
841
  * Looks up the display name for an attribute from the store's filterList.
@@ -762,7 +843,7 @@ class Ut extends Z {
762
843
  */
763
844
  _getDisplayNameForAttribute(t) {
764
845
  const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
765
- return r ? r.displayName : ht(t);
846
+ return r ? r.displayName : pt(t);
766
847
  }
767
848
  /**
768
849
  * Resolves the display content for a custom attribute cell.
@@ -770,29 +851,29 @@ class Ut extends Z {
770
851
  */
771
852
  _resolveAttributeContent(t, r, e) {
772
853
  var n;
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;
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;
775
856
  }
776
- _getGridCellHtml(t, r, e, o = "", s = "", i = "") {
777
- const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
857
+ _getGridCellHtml(t, r, e, i = "", o = "", s = "") {
858
+ const n = `${p}${t}`, c = V(ct, [n], this.store.filterList), l = {
778
859
  [t]: r,
779
860
  product_attributes: { [t]: r }
780
861
  };
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;
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;
786
867
  }
787
868
  _getListRowHtml(t, r, e) {
788
- const o = w(mt, [e], this.store.filterList), s = {
869
+ const i = V(mt, [e], this.store.filterList), o = {
789
870
  [t]: r,
790
871
  product_attributes: { [t]: r }
791
- }, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
792
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
872
+ }, n = i[e](o).replace(/<tr>/, "").replace(/<\/tr>/, "");
873
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${O}="1">${n}</tr>`;
793
874
  }
794
875
  }
795
876
  export {
796
- bt as COMPOSITION_CONTROL_BLOCK_ID,
877
+ St as COMPOSITION_CONTROL_BLOCK_ID,
797
878
  Ut as RecommendationCardCompositionControl
798
879
  };