@useinsider/guido 3.8.1-beta.fc167ba → 3.8.2-beta.189e91c

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