@useinsider/guido 3.8.1 → 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 (86) 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/useHtmlCompiler.js +13 -10
  11. package/dist/composables/useHtmlValidator.js +180 -133
  12. package/dist/composables/usePreviewInteractionGuard.js +17 -0
  13. package/dist/composables/usePreviewMode.js +15 -14
  14. package/dist/composables/useRecommendationPreview.js +111 -0
  15. package/dist/composables/useSave.js +14 -14
  16. package/dist/composables/validators/useUnsubscribeBlockValidator.js +26 -17
  17. package/dist/config/compiler/htmlCompilerRules.js +38 -10
  18. package/dist/config/compiler/recommendationCompilerRules.js +84 -109
  19. package/dist/config/compiler/utils/recommendationCompilerUtils.js +98 -89
  20. package/dist/config/compiler/utils/recommendationIgnoreUtils.js +15 -0
  21. package/dist/config/migrator/recommendation/extractors.js +44 -22
  22. package/dist/config/migrator/recommendation/htmlBuilder.js +170 -163
  23. package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
  24. package/dist/config/migrator/recommendationMigrator.js +30 -31
  25. package/dist/extensions/Blocks/Recommendation/block.js +60 -41
  26. package/dist/extensions/Blocks/Recommendation/canvasPreview.css.js +16 -0
  27. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
  28. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +26 -20
  29. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +359 -264
  30. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +96 -83
  31. package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +43 -31
  32. package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
  33. package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
  34. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +55 -45
  35. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +175 -166
  36. package/dist/extensions/Blocks/Recommendation/controls/syncInfoMessage.js +7 -6
  37. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  38. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
  39. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
  40. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +3 -2
  41. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +6 -3
  42. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +130 -96
  43. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +43 -53
  44. package/dist/extensions/Blocks/Recommendation/templates/index.js +20 -16
  45. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +86 -80
  46. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +31 -40
  47. package/dist/extensions/Blocks/Recommendation/templates/utils.js +155 -102
  48. package/dist/extensions/Blocks/Unsubscribe/block.js +40 -37
  49. package/dist/extensions/Blocks/Unsubscribe/control.js +19 -16
  50. package/dist/guido.css +1 -1
  51. package/dist/src/@types/config/schemas.d.ts +16 -0
  52. package/dist/src/composables/useConfig.d.ts +4 -0
  53. package/dist/src/composables/useHtmlValidator.d.ts +27 -0
  54. package/dist/src/composables/useHtmlValidator.test.d.ts +1 -0
  55. package/dist/src/composables/usePreviewInteractionGuard.d.ts +3 -0
  56. package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
  57. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +1 -0
  58. package/dist/src/config/compiler/utils/recommendationIgnoreUtils.d.ts +17 -0
  59. package/dist/src/config/compiler/utils/recommendationIgnoreUtils.test.d.ts +1 -0
  60. package/dist/src/config/migrator/recommendation/extractors.d.ts +15 -0
  61. package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +8 -0
  62. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
  63. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  64. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  65. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +21 -0
  66. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +36 -3
  67. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
  68. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
  69. package/dist/src/extensions/Blocks/Recommendation/controls/main/layoutOrientation.d.ts +5 -0
  70. package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
  71. package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +6 -0
  72. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -0
  73. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
  74. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +13 -1
  75. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  76. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
  77. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +10 -1
  78. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  79. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +51 -1
  80. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
  81. package/dist/src/stores/config.d.ts +36 -0
  82. package/dist/src/stores/unsubscribe.d.ts +11 -1
  83. package/dist/src/utils/ampErrorFilter.d.ts +1 -0
  84. package/dist/stores/unsubscribe.js +8 -7
  85. package/dist/utils/ampErrorFilter.js +6 -5
  86. 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 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 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 { 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 { 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: D, 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
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
+ ], Tt = new Set(m.map((g) => g.key)), $ = "customAttr_", O = "deleteAttr_";
26
+ class qt 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 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="${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, 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
  })}
@@ -128,10 +128,24 @@ class Ut extends Z {
128
128
  `;
129
129
  }
130
130
  onRender() {
131
- this._initializeComposition(), this._registerValueChangeListeners(), this._setupEventListeners(), this._updateOrderableState(), this._subscribeToStoreChanges();
131
+ this._initializeComposition(), this._registerValueChangeListeners(), this._setupEventListeners(), this._updateOrderableState(), this._subscribeToStoreChanges(), this._syncDisabledState();
132
+ }
133
+ /**
134
+ * Card composition restructures the block (toggles/reorders/adds attribute
135
+ * cells), which would corrupt a partner-managed (`ins-skip-compile`) block's
136
+ * preserved markup. There is no native tab-disable API, so the whole control
137
+ * container is rendered inert (greyed + non-interactive) instead.
138
+ */
139
+ _syncDisabledState() {
140
+ var e;
141
+ const t = (e = this.getContainer()) == null ? void 0 : e.querySelector("[data-card-composition-control]");
142
+ if (!t)
143
+ return;
144
+ const r = ft(this.currentNode);
145
+ t.style.pointerEvents = r ? "none" : "", t.style.opacity = r ? "0.5" : "";
132
146
  }
133
147
  onTemplateNodeUpdated(t) {
134
- super.onTemplateNodeUpdated(t), !this.reorderInProgress && (this._initializeComposition(), this._updateOrderableState());
148
+ super.onTemplateNodeUpdated(t), !this.reorderInProgress && (this._initializeComposition(), this._updateOrderableState(), this._syncDisabledState());
135
149
  }
136
150
  onDestroy() {
137
151
  super.onDestroy(), this.eventController && (this.eventController.abort(), this.eventController = null), this.unsubscribeStore && (this.unsubscribeStore(), this.unsubscribeStore = null);
@@ -140,17 +154,17 @@ class Ut extends Z {
140
154
  // Initialization
141
155
  // ========================================================================
142
156
  _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();
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();
145
159
  }
146
160
  _registerValueChangeListeners() {
147
- h.forEach((t) => {
161
+ m.forEach((t) => {
148
162
  this.api.onValueChanged(`visibility_${t.key}`, (r) => {
149
163
  this._applyVisibilityToBlock(t.key, r);
150
164
  });
151
165
  });
152
- for (let t = 0; t < g; t++) {
153
- const r = `${T}${t}`, e = t;
166
+ for (let t = 0; t < f; t++) {
167
+ const r = `${$}${t}`, e = t;
154
168
  this.api.onValueChanged(r, (o) => {
155
169
  this._onCustomAttributeChanged(e, o);
156
170
  });
@@ -161,14 +175,14 @@ class Ut extends Z {
161
175
  // ========================================================================
162
176
  _readCompositionFromNode() {
163
177
  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];
178
+ return [...x];
179
+ const t = this.currentNode.getAttribute(W);
180
+ return t ? t.split(",").filter(Boolean) : [...x];
167
181
  }
168
182
  _readCustomAttributesFromNode() {
169
183
  if (!this.currentNode || !("getAttribute" in this.currentNode))
170
184
  return [];
171
- const t = this.currentNode.getAttribute(q);
185
+ const t = this.currentNode.getAttribute(F);
172
186
  if (!t)
173
187
  return [];
174
188
  try {
@@ -180,31 +194,31 @@ class Ut extends Z {
180
194
  _readVisibilityFromRows() {
181
195
  if (!this.currentNode)
182
196
  return this._getDefaultVisibilities();
183
- const t = Array.from(this.currentNode.querySelectorAll(C)), r = this._extractVisibilityFromRows(t);
197
+ const t = Array.from(this.currentNode.querySelectorAll(T)), r = this._extractVisibilityFromRows(t);
184
198
  return this._mergeWithDefaults(r);
185
199
  }
186
200
  _getDefaultVisibilities() {
187
- return { ...F };
201
+ return { ...M };
188
202
  }
189
203
  _extractVisibilityFromRows(t) {
190
204
  const r = {};
191
205
  return t.forEach((e) => {
192
206
  if (!("getAttribute" in e))
193
207
  return;
194
- const o = e.getAttribute(y), s = e.getAttribute(v);
195
- 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));
196
210
  }), r;
197
211
  }
198
212
  _parseVisibilityValue(t) {
199
213
  return t === "1" || t === "true";
200
214
  }
201
215
  _mergeWithDefaults(t) {
202
- return Object.entries(F).forEach(([r, e]) => {
216
+ return Object.entries(M).forEach(([r, e]) => {
203
217
  r in t || (t[r] = e);
204
218
  }), t;
205
219
  }
206
220
  _buildVisibilityValues(t) {
207
- 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), {});
208
222
  }
209
223
  // ========================================================================
210
224
  // UI Rendering (Orderable List)
@@ -219,23 +233,29 @@ class Ut extends Z {
219
233
  if (!e)
220
234
  return !1;
221
235
  const o = e.querySelector("[data-composition-list]");
222
- if (!o || this._tryReorderInPlace(o, t))
236
+ if (!o)
237
+ return !1;
238
+ const i = !P.getConfig(this.currentNode).priceMovedToNextLine;
239
+ if (!(o.dataset.inlinePrices !== String(i)) && this._tryReorderInPlace(o, t))
223
240
  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++);
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++);
230
250
  }
231
- if (c.startsWith(m)) {
232
- const l = c.substring(m.length);
233
- if (s.has(l))
234
- 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++);
235
255
  }
236
256
  return "";
237
257
  }).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;
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;
239
259
  }
240
260
  /**
241
261
  * Attempts to reorder existing orderable-item elements to match the composition order.
@@ -247,27 +267,27 @@ class Ut extends Z {
247
267
  const e = Array.from(t.querySelectorAll(".orderable-item"));
248
268
  if (e.length !== r.length)
249
269
  return !1;
250
- const o = e.map((c) => c.dataset.key).filter(Boolean);
270
+ const o = e.map((l) => l.dataset.key).filter(Boolean);
251
271
  if (o.length !== r.length)
252
272
  return !1;
253
- const s = [...o].sort().join(","), i = [...r].sort().join(",");
254
- 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)))
255
275
  return !1;
256
276
  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);
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);
262
282
  }
263
283
  });
264
- const a = /* @__PURE__ */ new Map();
265
- return r.forEach((c) => {
266
- const l = n.get(c);
267
- if (!l)
284
+ const c = /* @__PURE__ */ new Map();
285
+ return r.forEach((l) => {
286
+ const a = n.get(l);
287
+ if (!a)
268
288
  return;
269
- const u = a.get(c) || 0;
270
- 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]);
271
291
  }), !0;
272
292
  }
273
293
  _createBuiltInItemHtml(t, r) {
@@ -279,6 +299,33 @@ class Ut extends Z {
279
299
  </div>
280
300
  `;
281
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
+ }
282
329
  _createCustomItemHtml(t, r, e) {
283
330
  return `
284
331
  <div class="orderable-item" draggable="true"
@@ -299,10 +346,10 @@ class Ut extends Z {
299
346
  _getSelectOptions(t, r = []) {
300
347
  const e = this._getAddableFilters();
301
348
  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
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
306
353
  }));
307
354
  }
308
355
  return [{ text: this._getDisplayNameForAttribute(t), value: t }];
@@ -315,8 +362,8 @@ class Ut extends Z {
315
362
  _initializeCustomSelects(t) {
316
363
  t.length !== 0 && setTimeout(() => {
317
364
  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 });
365
+ const o = `${$}${e}`, i = this._getSelectOptions(r, t);
366
+ this.api.setUIEAttribute(o, E.SELECTPICKER.items, i), this.api.updateValues({ [o]: r });
320
367
  });
321
368
  }, 0);
322
369
  }
@@ -325,11 +372,11 @@ class Ut extends Z {
325
372
  * Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
326
373
  */
327
374
  _moveTogglesIntoItems(t) {
328
- h.forEach((r) => {
375
+ m.forEach((r) => {
329
376
  const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
330
377
  if (e && o) {
331
- const s = e.querySelector("ue-switcher");
332
- s && o.appendChild(s);
378
+ const i = e.querySelector("ue-switcher");
379
+ i && o.appendChild(i);
333
380
  }
334
381
  });
335
382
  }
@@ -339,10 +386,10 @@ class Ut extends Z {
339
386
  */
340
387
  _moveSelectsIntoItems(t, r) {
341
388
  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);
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);
346
393
  }
347
394
  }
348
395
  }
@@ -353,11 +400,11 @@ class Ut extends Z {
353
400
  * previously-moved toggles, making them permanently lost.
354
401
  */
355
402
  _rescueTogglesToStore(t) {
356
- h.forEach((r) => {
403
+ m.forEach((r) => {
357
404
  const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
358
405
  if (o) {
359
- const s = o.querySelector("ue-switcher");
360
- s && e && e.appendChild(s);
406
+ const i = o.querySelector("ue-switcher");
407
+ i && e && e.appendChild(i);
361
408
  }
362
409
  });
363
410
  }
@@ -366,11 +413,11 @@ class Ut extends Z {
366
413
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
367
414
  */
368
415
  _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);
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);
374
421
  }
375
422
  }
376
423
  }
@@ -380,10 +427,10 @@ class Ut extends Z {
380
427
  */
381
428
  _moveDeleteButtonsIntoItems(t, r) {
382
429
  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);
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);
387
434
  }
388
435
  }
389
436
  }
@@ -392,11 +439,11 @@ class Ut extends Z {
392
439
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
393
440
  */
394
441
  _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);
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);
400
447
  }
401
448
  }
402
449
  }
@@ -406,10 +453,10 @@ class Ut extends Z {
406
453
  */
407
454
  _moveReorderIconsIntoItems(t, r) {
408
455
  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);
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);
413
460
  }
414
461
  }
415
462
  }
@@ -418,12 +465,12 @@ class Ut extends Z {
418
465
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
419
466
  */
420
467
  _rescueReorderIconsToStore(t) {
421
- const r = h.length + g;
468
+ const r = m.length + f;
422
469
  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);
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);
427
474
  }
428
475
  }
429
476
  }
@@ -437,39 +484,81 @@ class Ut extends Z {
437
484
  return;
438
485
  const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
439
486
  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);
487
+ const i = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !i.has(n.attributeName));
488
+ s && this._onAddAttribute(s.attributeName, s.displayName);
442
489
  }, { signal: t });
443
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
+ }
444
506
  _setupDragAndDrop(t, r) {
445
- let e = null, o = null;
446
- 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) => {
447
529
  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 || ""));
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 ?? ""));
450
535
  }, { 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)
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)
539
+ return;
540
+ const c = s(n);
541
+ if (!c)
460
542
  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;
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));
465
554
  }, { signal: r });
466
555
  }
467
556
  _setupDeleteHandler(t, r) {
468
557
  t.addEventListener("click", (e) => {
469
- const s = e.target.closest(".custom-attr-delete");
470
- if (!s)
558
+ const i = e.target.closest(".custom-attr-delete");
559
+ if (!i)
471
560
  return;
472
- 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;
473
562
  n !== void 0 && this._onDeleteCustomAttribute(Number(n));
474
563
  }, { signal: r });
475
564
  }
@@ -477,10 +566,10 @@ class Ut extends Z {
477
566
  // Actions (Add, Delete, Reorder)
478
567
  // ========================================================================
479
568
  _onAddAttribute(t, r) {
480
- const e = `${m}${t}`, o = this._readCompositionFromNode();
569
+ const e = `${p}${t}`, o = this._readCompositionFromNode();
481
570
  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();
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();
484
573
  }
485
574
  /**
486
575
  * Removes a single custom attribute by its index in the customAttrs array.
@@ -490,8 +579,8 @@ class Ut extends Z {
490
579
  const r = this._readCustomAttributesFromNode();
491
580
  if (r[t] === void 0)
492
581
  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();
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();
495
584
  }
496
585
  /**
497
586
  * Handles changing a custom attribute's selection via its inline _GuSelect.
@@ -501,16 +590,21 @@ class Ut extends Z {
501
590
  const e = this._readCustomAttributesFromNode(), o = e[t];
502
591
  if (o === void 0 || o === r)
503
592
  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);
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);
508
597
  }
509
598
  _onReorder(t) {
510
- 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));
511
600
  this.reorderInProgress = !0;
512
601
  try {
513
- 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
+ });
514
608
  } finally {
515
609
  this.reorderInProgress = !1;
516
610
  }
@@ -525,60 +619,60 @@ class Ut extends Z {
525
619
  this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
526
620
  }
527
621
  _injectGridAttributeRow(t, r, e, o) {
528
- const s = this.currentNode.querySelectorAll(L);
529
- if (!(s != null && s.length))
622
+ const i = this.currentNode.querySelectorAll(H);
623
+ if (!(i != null && i.length))
530
624
  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(
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(
541
635
  t,
542
636
  r,
543
- u + Y
637
+ d + Q
544
638
  );
545
639
  return this._getGridCellHtml(
546
640
  t,
547
- X,
548
- B,
549
- j,
550
- W,
551
- a
641
+ Z,
642
+ q,
643
+ G,
644
+ z,
645
+ c
552
646
  );
553
647
  }
554
- ).join(""), G = dt(B, a).repeat($ - O);
555
- 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>`;
556
650
  }
557
- const N = d.querySelector(
558
- `${C}[${y}="${k}"]`
651
+ const L = u.querySelector(
652
+ `${T}[${y}="${w}"]`
559
653
  );
560
- return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
654
+ return L && "getOuterHTML" in L ? L.getOuterHTML() : "";
561
655
  }).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}`));
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}`));
564
658
  }
565
659
  _injectListAttributeRow(t, r, e, o) {
566
- const s = this.currentNode.querySelectorAll(M);
567
- if (!(s != null && s.length))
660
+ const i = this.currentNode.querySelectorAll(j);
661
+ if (!(i != null && i.length))
568
662
  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);
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);
575
669
  }
576
- const d = a.querySelector(
577
- `${C}[${y}="${u}"]`
670
+ const u = c.querySelector(
671
+ `${T}[${y}="${d}"]`
578
672
  );
579
- return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
673
+ return u && "getOuterHTML" in u ? u.getOuterHTML() : "";
580
674
  }).join("");
581
- n.modifyHtml(a).setInnerHtml(l);
675
+ n.modifyHtml(c).setInnerHtml(a);
582
676
  }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
583
677
  }
584
678
  /**
@@ -590,16 +684,16 @@ class Ut extends Z {
590
684
  return;
591
685
  const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
592
686
  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);
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);
597
691
  });
598
692
  } 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);
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);
603
697
  });
604
698
  }
605
699
  e.apply(new A(this.api.translate("Remove custom attribute")));
@@ -615,7 +709,7 @@ class Ut extends Z {
615
709
  * producing a flicker on the custom attribute dropdowns.
616
710
  */
617
711
  _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")));
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")));
619
713
  }
620
714
  /**
621
715
  * Reorders attribute rows within each product card based on composition order.
@@ -624,13 +718,13 @@ class Ut extends Z {
624
718
  _reorderProductAttributes(t) {
625
719
  if (!this.currentNode)
626
720
  return;
627
- const r = this.currentNode.querySelectorAll(L);
721
+ const r = this.currentNode.querySelectorAll(H);
628
722
  if (!(r != null && r.length))
629
723
  return;
630
724
  const e = this.api.getDocumentModifier();
631
725
  r.forEach((o) => {
632
- const s = this._buildCompositionHtml(o, t);
633
- e.modifyHtml(o).setInnerHtml(s);
726
+ const i = this._buildCompositionHtml(o, t);
727
+ e.modifyHtml(o).setInnerHtml(i);
634
728
  }), e.apply(new A(this.api.translate("Reorder product attributes")));
635
729
  }
636
730
  /**
@@ -639,8 +733,8 @@ class Ut extends Z {
639
733
  */
640
734
  _buildCompositionHtml(t, r) {
641
735
  return r.reduce((e, o) => {
642
- const s = t.querySelector(`${C}[${y}="${o}"]`);
643
- 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;
644
738
  }, "");
645
739
  }
646
740
  // ========================================================================
@@ -649,14 +743,14 @@ class Ut extends Z {
649
743
  _applyVisibilityToBlock(t, r) {
650
744
  if (!this.currentNode)
651
745
  return;
652
- const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
746
+ const e = this.currentNode.querySelectorAll(`${T}[${y}="${t}"]`);
653
747
  if (!(e != null && e.length))
654
748
  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));
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));
660
754
  }
661
755
  // ========================================================================
662
756
  // Utilities
@@ -669,7 +763,7 @@ class Ut extends Z {
669
763
  _findNthCustomKeyIndex(t, r) {
670
764
  let e = 0;
671
765
  for (let o = 0; o < t.length; o++)
672
- if (t[o].startsWith(m)) {
766
+ if (t[o].startsWith(p)) {
673
767
  if (e === r)
674
768
  return o;
675
769
  e++;
@@ -677,7 +771,7 @@ class Ut extends Z {
677
771
  return -1;
678
772
  }
679
773
  _getCurrentLayout() {
680
- return this.store.recommendationConfigs.orientation || gt(this.currentNode);
774
+ return this.store.recommendationConfigs.orientation || St(this.currentNode);
681
775
  }
682
776
  /**
683
777
  * Extracts background color properties from existing card elements.
@@ -689,18 +783,18 @@ class Ut extends Z {
689
783
  var o;
690
784
  const r = t.querySelector(".product-card-segment");
691
785
  if (r && "getAttribute" in r) {
692
- const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
693
- if (i) {
786
+ const s = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
787
+ if (s) {
694
788
  const n = r.getAttribute("bgcolor") || "";
695
- return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
789
+ return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
696
790
  }
697
791
  }
698
792
  const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
699
793
  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 };
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 };
704
798
  }
705
799
  }
706
800
  return { bgStyle: "", bgAttr: "" };
@@ -710,17 +804,18 @@ class Ut extends Z {
710
804
  return t ? t.querySelector("[data-card-composition-control]") : null;
711
805
  }
712
806
  /**
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.
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.)
716
811
  */
717
812
  _updateOrderableState() {
718
- const r = this._getCurrentLayout() === "list", e = this._getControlContainer();
719
- if (!e)
813
+ const t = this._getControlContainer();
814
+ if (!t)
720
815
  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");
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");
724
819
  }));
725
820
  }
726
821
  /**
@@ -728,11 +823,11 @@ class Ut extends Z {
728
823
  * or when all available filters have already been added (no unused attributes left).
729
824
  */
730
825
  _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));
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));
732
827
  this.api.setUIEAttribute(
733
- x.ADD_ATTRIBUTE,
734
- I.BUTTON.disabled,
735
- r || s ? "true" : "false"
828
+ K.ADD_ATTRIBUTE,
829
+ E.BUTTON.disabled,
830
+ r || i ? "true" : "false"
736
831
  );
737
832
  }
738
833
  /**
@@ -754,7 +849,7 @@ class Ut extends Z {
754
849
  * excluding default attributes already covered by built-in toggle items.
755
850
  */
756
851
  _getAddableFilters() {
757
- 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)));
758
853
  }
759
854
  /**
760
855
  * Looks up the display name for an attribute from the store's filterList.
@@ -762,7 +857,7 @@ class Ut extends Z {
762
857
  */
763
858
  _getDisplayNameForAttribute(t) {
764
859
  const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
765
- return r ? r.displayName : ht(t);
860
+ return r ? r.displayName : pt(t);
766
861
  }
767
862
  /**
768
863
  * Resolves the display content for a custom attribute cell.
@@ -770,29 +865,29 @@ class Ut extends Z {
770
865
  */
771
866
  _resolveAttributeContent(t, r, e) {
772
867
  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;
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;
775
870
  }
776
- _getGridCellHtml(t, r, e, o = "", s = "", i = "") {
777
- 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 = {
778
873
  [t]: r,
779
874
  product_attributes: { [t]: r }
780
875
  };
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;
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;
786
881
  }
787
882
  _getListRowHtml(t, r, e) {
788
- const o = w(mt, [e], this.store.filterList), s = {
883
+ const o = V(mt, [e], this.store.filterList), i = {
789
884
  [t]: r,
790
885
  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>`;
886
+ }, n = o[e](i).replace(/<tr>/, "").replace(/<\/tr>/, "");
887
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${D}="1">${n}</tr>`;
793
888
  }
794
889
  }
795
890
  export {
796
- bt as COMPOSITION_CONTROL_BLOCK_ID,
797
- Ut as RecommendationCardCompositionControl
891
+ Ct as COMPOSITION_CONTROL_BLOCK_ID,
892
+ qt as RecommendationCardCompositionControl
798
893
  };