@useinsider/guido 2.1.0-beta.f8696fd → 2.1.0-beta.f9ab899

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 (74) hide show
  1. package/dist/components/organisms/base/Toaster.vue.js +4 -4
  2. package/dist/components/organisms/base/Toaster.vue2.js +12 -9
  3. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +5 -5
  4. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +2 -2
  5. package/dist/components/organisms/header/EditorActions.vue.js +10 -12
  6. package/dist/components/organisms/header/EditorActions.vue2.js +31 -41
  7. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
  8. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
  9. package/dist/composables/useRecommendation.js +9 -9
  10. package/dist/config/i18n/en/labels.json.js +3 -8
  11. package/dist/config/migrator/itemsBlockMigrator.js +134 -136
  12. package/dist/config/migrator/recommendationMigrator.js +40 -42
  13. package/dist/extensions/Blocks/Items/block.js +25 -45
  14. package/dist/extensions/Blocks/Items/iconsRegistry.js +5 -40
  15. package/dist/extensions/Blocks/Items/items.css.js +0 -48
  16. package/dist/extensions/Blocks/Recommendation/block.js +29 -49
  17. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +36 -33
  18. package/dist/extensions/Blocks/Recommendation/constants/layout.js +16 -14
  19. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +13 -12
  20. package/dist/extensions/Blocks/Recommendation/controls/button/index.js +9 -9
  21. package/dist/extensions/Blocks/Recommendation/controls/image/index.js +1 -1
  22. package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +37 -27
  23. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +16 -16
  24. package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +30 -32
  25. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +173 -102
  26. package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +9 -9
  27. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +46 -38
  28. package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +16 -16
  29. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +269 -215
  30. package/dist/extensions/Blocks/Recommendation/controls/name/index.js +10 -10
  31. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +5 -5
  32. package/dist/extensions/Blocks/Recommendation/controls/oldPrice/index.js +14 -14
  33. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.js +9 -9
  34. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +3 -3
  35. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +1 -1
  36. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/index.js +9 -9
  37. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +3 -3
  38. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +3 -3
  39. package/dist/extensions/Blocks/Recommendation/controls/price/index.js +3 -3
  40. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +225 -102
  41. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +2 -37
  42. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +0 -48
  43. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +94 -53
  44. package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
  45. package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
  46. package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
  47. package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
  48. package/dist/extensions/Blocks/common-control.js +4 -12
  49. package/dist/guido.css +1 -1
  50. package/dist/src/components/Guido.vue.d.ts +1 -1
  51. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  52. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  53. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  54. package/dist/src/components/wrappers/WpModal.vue.d.ts +2 -2
  55. package/dist/src/extensions/Blocks/Items/block.d.ts +0 -1
  56. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -1
  57. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +6 -0
  58. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +3 -3
  59. package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -2
  60. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +6 -1
  61. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +33 -10
  62. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +24 -14
  63. package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +49 -17
  64. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -0
  65. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +8 -0
  66. package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
  67. package/dist/src/extensions/Blocks/common-control.d.ts +0 -5
  68. package/dist/stores/unsubscribe.js +37 -34
  69. package/package.json +1 -1
  70. package/dist/components/organisms/header/MigrationConfirmModal.vue.js +0 -21
  71. package/dist/components/organisms/header/MigrationConfirmModal.vue2.js +0 -38
  72. package/dist/src/components/organisms/header/MigrationConfirmModal.vue.d.ts +0 -5
  73. package/dist/src/stores/template.d.ts +0 -3
  74. package/dist/stores/template.js +0 -9
@@ -1,222 +1,345 @@
1
1
  var G = Object.defineProperty;
2
- var I = (o, n, t) => n in o ? G(o, n, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[n] = t;
3
- var l = (o, n, t) => I(o, typeof n != "symbol" ? n + "" : n, t);
4
- import { ModificationDescription as g } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as L } from "../../../common-control.js";
6
- import { SPACING_STEP as b, MAX_SPACING as y, MIN_SPACING as A, DEFAULT_COLUMN_SPACING as a, DEFAULT_ROW_SPACING as m } from "../../constants/layout.js";
7
- import { RecommendationConfigService as d } from "../../services/configService.js";
8
- import { useRecommendationExtensionStore as w } from "../../store/recommendation.js";
9
- import { safeGetStyle as S, safeGetParent as V } from "../../utils/tagName.js";
10
- import { getCurrentLayout as C } from "../main/utils.js";
11
- import { useDebounceFn as O } from "../../../../../node_modules/@vueuse/shared/index.js";
12
- const R = "recommendation-spacing-control", s = {
2
+ var R = (u, c, t) => c in u ? G(u, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[c] = t;
3
+ var h = (u, c, t) => R(u, typeof c != "symbol" ? c + "" : c, t);
4
+ import { EditorStatePropertyType as y, PreviewDeviceMode as w, ModificationDescription as g } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as V } from "../../../common-control.js";
6
+ import { DESKTOP_CONTAINER_SELECTOR as m, MOBILE_CONTAINER_SELECTOR as E } from "../../constants/selectors.js";
7
+ import { SPACING_STEP as S, MAX_SPACING as _, MIN_SPACING as N, DEFAULT_COLUMN_SPACING as C, DEFAULT_ROW_SPACING as P } from "../../constants/layout.js";
8
+ import { RecommendationConfigService as p } from "../../services/configService.js";
9
+ import { useRecommendationExtensionStore as B } from "../../store/recommendation.js";
10
+ import { safeGetStyle as A, safeGetParent as U } from "../../utils/tagName.js";
11
+ import { getCurrentLayout as b, getBlockElement as x } from "../main/utils.js";
12
+ import { useDebounceFn as f } from "../../../../../node_modules/@vueuse/shared/index.js";
13
+ const W = "recommendation-spacing-control", i = {
13
14
  COLUMN_SPACING: "columnSpacing",
14
15
  COLUMN_SPACING_LABEL: "columnSpacingLabel",
15
- ROW_SPACING: "rowSpacing"
16
- }, P = {
16
+ ROW_SPACING: "rowSpacing",
17
+ ROW_SPACING_LABEL: "rowSpacingLabel",
18
+ MOBILE_COLUMN_SPACING: "mobileColumnSpacing",
19
+ MOBILE_COLUMN_SPACING_LABEL: "mobileColumnSpacingLabel",
20
+ MOBILE_ROW_SPACING: "mobileRowSpacing",
21
+ MOBILE_ROW_SPACING_LABEL: "mobileRowSpacingLabel"
22
+ }, O = {
17
23
  COLUMN_SPACING: "data-column-spacing",
18
- ROW_SPACING: "data-row-spacing"
24
+ ROW_SPACING: "data-row-spacing",
25
+ MOBILE_COLUMN_SPACING: "data-mobile-column-spacing",
26
+ MOBILE_ROW_SPACING: "data-mobile-row-spacing"
19
27
  };
20
- function N(o, n) {
21
- if (!o)
22
- return n;
23
- const t = parseFloat(o);
24
- return Number.isNaN(t) ? n : t;
28
+ function L(u, c) {
29
+ if (!u)
30
+ return c;
31
+ const t = parseFloat(u);
32
+ return Number.isNaN(t) ? c : t;
25
33
  }
26
- class $ extends L {
34
+ class X extends V {
27
35
  constructor() {
28
36
  super(...arguments);
29
- l(this, "store", w());
30
- l(this, "unsubscribeOrientation", null);
37
+ h(this, "store", B());
38
+ h(this, "unsubscribeOrientation", null);
31
39
  /**
32
40
  * Debounced version of _onColumnSpacingChange
33
41
  * Prevents excessive DOM updates when user rapidly adjusts the counter
34
42
  */
35
- l(this, "_debouncedOnColumnSpacingChange", O((t) => {
43
+ h(this, "_debouncedOnColumnSpacingChange", f((t) => {
36
44
  this._onColumnSpacingChange(t);
37
45
  }, 300));
38
46
  /**
39
47
  * Debounced version of _onRowSpacingChange
40
- * Prevents excessive DOM updates when user rapidly adjusts the counter
41
48
  */
42
- l(this, "_debouncedOnRowSpacingChange", O((t) => {
49
+ h(this, "_debouncedOnRowSpacingChange", f((t) => {
43
50
  this._onRowSpacingChange(t);
44
51
  }, 300));
52
+ /**
53
+ * Debounced version of _onMobileColumnSpacingChange
54
+ */
55
+ h(this, "_debouncedOnMobileColumnSpacingChange", f((t) => {
56
+ this._onMobileColumnSpacingChange(t);
57
+ }, 300));
58
+ /**
59
+ * Debounced version of _onMobileRowSpacingChange
60
+ */
61
+ h(this, "_debouncedOnMobileRowSpacingChange", f((t) => {
62
+ this._onMobileRowSpacingChange(t);
63
+ }, 300));
45
64
  }
46
65
  getId() {
47
- return R;
66
+ return W;
48
67
  }
49
68
  getTemplate() {
50
69
  return `
51
70
  <div class="spacing-control-container">
52
71
  ${this._GuTwoColumns([
53
- this._GuLabel({ text: "Column Spacing (px)", name: s.COLUMN_SPACING_LABEL }),
72
+ this._GuLabel({ text: "Column Spacing on Desktop (px)", name: i.COLUMN_SPACING_LABEL }),
54
73
  this._GuCounter({
55
- name: s.COLUMN_SPACING,
56
- minValue: A,
57
- maxValue: y,
58
- step: b
74
+ name: i.COLUMN_SPACING,
75
+ minValue: N,
76
+ maxValue: _,
77
+ step: S
59
78
  }),
60
- this._GuLabel({ text: "Row Spacing (px)" }),
79
+ this._GuLabel({ text: "Row Spacing on Desktop (px)", name: i.ROW_SPACING_LABEL }),
61
80
  this._GuCounter({
62
- name: s.ROW_SPACING,
63
- minValue: A,
64
- maxValue: y,
65
- step: b
81
+ name: i.ROW_SPACING,
82
+ minValue: N,
83
+ maxValue: _,
84
+ step: S
85
+ }),
86
+ this._GuLabel({
87
+ text: "Column Spacing on Mobile (px)",
88
+ name: i.MOBILE_COLUMN_SPACING_LABEL
89
+ }),
90
+ this._GuCounter({
91
+ name: i.MOBILE_COLUMN_SPACING,
92
+ minValue: N,
93
+ maxValue: _,
94
+ step: S
95
+ }),
96
+ this._GuLabel({ text: "Row Spacing on Mobile (px)", name: i.MOBILE_ROW_SPACING_LABEL }),
97
+ this._GuCounter({
98
+ name: i.MOBILE_ROW_SPACING,
99
+ minValue: N,
100
+ maxValue: _,
101
+ step: S
66
102
  })
67
103
  ])}
68
104
  </div>
69
105
  `;
70
106
  }
71
107
  onRender() {
72
- this._setFormValues(), this._updateColumnSpacingVisibility(), this._listenToFormUpdates(), this._subscribeToOrientationChanges();
108
+ this._setFormValues(), this._updateSpacingVisibility(), this._listenToFormUpdates(), this._subscribeToOrientationChanges(), this._subscribeToEditorModeChanges();
73
109
  }
74
110
  onTemplateNodeUpdated(t) {
75
- super.onTemplateNodeUpdated(t), this._setFormValues(), this._updateColumnSpacingVisibility();
111
+ super.onTemplateNodeUpdated(t), this._setFormValues(), this._updateSpacingVisibility();
76
112
  }
77
113
  onDestroy() {
78
114
  this.unsubscribeOrientation && (this.unsubscribeOrientation(), this.unsubscribeOrientation = null);
79
115
  }
80
116
  /**
81
- * Updates column spacing visibility based on layout orientation
82
- * Column spacing is hidden for list layout (products are stacked vertically)
83
- * Reads from node config first, falls back to store then DOM
117
+ * Checks if the editor is currently in mobile preview mode
118
+ * using Stripo's EditorStatePropertyType API.
119
+ */
120
+ _isMobileMode() {
121
+ return this.api.getEditorState()[y.previewDeviceMode] === w.MOBILE;
122
+ }
123
+ /**
124
+ * Updates spacing control visibility based on layout orientation, editor mode,
125
+ * and products-per-row count.
126
+ * - List layout: hide column spacing (products are full-width)
127
+ * - Desktop mode: show desktop spacing, hide mobile spacing
128
+ * - Mobile mode: show mobile spacing, hide desktop spacing
129
+ * - 1 product per row: hide column spacing (no gap between single column)
84
130
  */
85
- _updateColumnSpacingVisibility() {
131
+ _updateSpacingVisibility() {
86
132
  if (!this.api)
87
133
  return;
88
- const t = d.getConfig(this.currentNode), e = this.store.recommendationConfigs.orientation, i = (t.layout || e || C(this.currentNode)) === "grid";
89
- this.api.setVisibility(s.COLUMN_SPACING, i), this.api.setVisibility(s.COLUMN_SPACING_LABEL, i);
134
+ const t = p.getConfig(this.currentNode), e = this.store.recommendationConfigs.orientation, o = (t.layout || e || b(this.currentNode)) === "grid", r = this._isMobileMode(), a = t.cardsInRow > 1, l = t.mobileCardsInRow > 1;
135
+ this.api.setVisibility(i.COLUMN_SPACING, o && !r && a), this.api.setVisibility(i.COLUMN_SPACING_LABEL, o && !r && a), this.api.setVisibility(i.ROW_SPACING, !r), this.api.setVisibility(i.ROW_SPACING_LABEL, !r), this.api.setVisibility(i.MOBILE_COLUMN_SPACING, o && r && l), this.api.setVisibility(i.MOBILE_COLUMN_SPACING_LABEL, o && r && l), this.api.setVisibility(i.MOBILE_ROW_SPACING, r), this.api.setVisibility(i.MOBILE_ROW_SPACING_LABEL, r);
90
136
  }
91
137
  /**
92
- * Reads spacing values from node config first, falls back to DOM styles
138
+ * Reads spacing values from node config first, falls back to DOM styles.
139
+ * DOM fallback is only used for legacy templates that lack node config.
93
140
  */
94
141
  _setFormValues() {
95
142
  if (!this.api)
96
143
  return;
97
- const t = d.getConfig(this.currentNode), e = t.columnSpacing !== a ? t.columnSpacing : this._getStoredColumnSpacing(), r = t.rowSpacing !== m ? t.rowSpacing : this._getStoredRowSpacing();
144
+ const t = p.hasConfig(this.currentNode), e = p.getConfig(this.currentNode), n = t ? e.columnSpacing : this._getStoredColumnSpacing(), o = t ? e.rowSpacing : this._getStoredRowSpacing();
98
145
  this.api.updateValues({
99
- [s.COLUMN_SPACING]: e,
100
- [s.ROW_SPACING]: r
146
+ [i.COLUMN_SPACING]: n,
147
+ [i.ROW_SPACING]: o,
148
+ [i.MOBILE_COLUMN_SPACING]: e.mobileColumnSpacing,
149
+ [i.MOBILE_ROW_SPACING]: e.mobileRowSpacing
101
150
  });
102
151
  }
103
152
  /**
104
153
  * Gets stored column spacing from the first attribute row cell's padding.
154
+ * Scoped to the desktop container for accurate readings.
105
155
  * For grid layout: cells inside .recommendation-attribute-row have padding applied.
106
156
  * For list layout: the parent of .product-card-wrapper has the padding.
107
157
  * The padding is applied as "0 {halfSpacing}px", so we extract and multiply by 2.
108
158
  */
109
159
  _getStoredColumnSpacing() {
110
160
  if (!this.currentNode)
111
- return a;
112
- if (C(this.currentNode) === "grid") {
113
- const p = this.currentNode.querySelector(".recommendation-attribute-row"), c = p == null ? void 0 : p.querySelector("td"), f = S(c, "padding");
114
- if (!f)
115
- return a;
116
- const _ = f.trim().split(/\s+/);
117
- return _.length < 2 ? a : N(_[1], a / 2) * 2;
161
+ return C;
162
+ const t = this.currentNode.querySelector(m) ?? this.currentNode;
163
+ if (b(this.currentNode) === "grid") {
164
+ const d = t.querySelector(".recommendation-attribute-row"), s = d == null ? void 0 : d.querySelector("td"), I = A(s, "padding");
165
+ if (!I)
166
+ return C;
167
+ const M = I.trim().split(/\s+/);
168
+ return M.length < 2 ? C : L(M[1], C / 2) * 2;
118
169
  }
119
- const e = this.currentNode.querySelector(".product-card-wrapper"), r = V(e), i = S(r, "padding");
120
- if (!i)
121
- return a;
122
- const u = i.trim().split(/\s+/);
123
- return u.length < 2 ? a : N(u[1], a / 2) * 2;
170
+ const n = t.querySelector(".product-card-wrapper"), o = U(n), r = A(o, "padding");
171
+ if (!r)
172
+ return C;
173
+ const a = r.trim().split(/\s+/);
174
+ return a.length < 2 ? C : L(a[1], C / 2) * 2;
124
175
  }
125
176
  /**
126
177
  * Gets stored row spacing from the first spacer element's height style
178
+ * Scoped to the desktop container for accurate readings.
127
179
  */
128
180
  _getStoredRowSpacing() {
129
181
  if (!this.currentNode)
130
- return m;
131
- const t = this.currentNode.querySelector(".spacer"), e = S(t, "height");
132
- return N(e, m);
182
+ return P;
183
+ const e = (this.currentNode.querySelector(m) ?? this.currentNode).querySelector(".spacer"), n = A(e, "height");
184
+ return L(n, P);
133
185
  }
186
+ // ========================================================================
187
+ // Desktop Spacing Handlers
188
+ // ========================================================================
134
189
  /**
135
- * Handles column spacing changes.
136
- * For grid layout: applies horizontal padding to all cells inside attribute rows.
137
- * For list layout: applies padding to parent of product card wrappers.
190
+ * Handles column spacing changes for desktop.
191
+ * Applies horizontal padding only to the desktop container elements.
138
192
  */
139
193
  _onColumnSpacingChange(t) {
140
194
  if (!this.currentNode)
141
195
  return;
142
- d.updateConfig(
196
+ p.updateConfig(
143
197
  this.api,
144
198
  this.currentNode,
145
199
  { columnSpacing: t },
146
200
  `Changed column spacing to ${t}px`
147
- ), this._storeColumnSpacing(t);
148
- const r = d.getConfig(this.currentNode).layout || C(this.currentNode), i = this.api.getDocumentModifier(), h = `0 ${t / 2}px`;
149
- r === "grid" ? Array.from(
150
- this.currentNode.querySelectorAll(".attribute-cell")
151
- ).forEach((c) => {
152
- i.modifyHtml(c).setStyle("padding", h);
201
+ ), this._storeDataAttribute(O.COLUMN_SPACING, t);
202
+ const n = p.getConfig(this.currentNode).layout || b(this.currentNode), o = this.api.getDocumentModifier(), a = `0 ${t / 2}px`, l = this.currentNode.querySelector(m);
203
+ l && (n === "grid" ? Array.from(
204
+ l.querySelectorAll(".attribute-cell")
205
+ ).forEach((s) => {
206
+ o.modifyHtml(s).setStyle("padding", a);
153
207
  }) : Array.from(
154
- this.currentNode.querySelectorAll(".product-card-wrapper")
155
- ).forEach((c) => {
156
- "parent" in c && c.parent() && i.modifyHtml(c.parent()).setStyle("padding", h);
157
- }), i.apply(new g(`Update column spacing to ${t}px`));
208
+ l.querySelectorAll(".product-card-wrapper")
209
+ ).forEach((s) => {
210
+ "parent" in s && s.parent() && o.modifyHtml(s.parent()).setStyle("padding", a);
211
+ }), o.apply(new g(`Update column spacing to ${t}px`)));
158
212
  }
159
213
  /**
160
- * Handles row spacing changes
161
- * Applies height to all spacer elements between product rows
214
+ * Handles row spacing changes for desktop.
215
+ * Applies height only to spacer elements in the desktop container.
162
216
  */
163
217
  _onRowSpacingChange(t) {
164
218
  if (!this.currentNode)
165
219
  return;
166
- d.updateConfig(
220
+ p.updateConfig(
167
221
  this.api,
168
222
  this.currentNode,
169
223
  { rowSpacing: t },
170
224
  `Changed row spacing to ${t}px`
171
- ), this._storeRowSpacing(t);
172
- const e = Array.from(
173
- this.currentNode.querySelectorAll(".spacer")
225
+ ), this._storeDataAttribute(O.ROW_SPACING, t);
226
+ const e = this.currentNode.querySelector(m);
227
+ if (!e)
228
+ return;
229
+ const n = Array.from(
230
+ e.querySelectorAll(".spacer")
174
231
  );
175
- if (!e.length)
232
+ if (!n.length)
176
233
  return;
177
- const r = this.api.getDocumentModifier(), i = `${t}px`;
178
- e.forEach((u) => {
179
- r.modifyHtml(u).setStyle("height", i);
180
- }), r.apply(new g(`Update row spacing to ${t}px`));
234
+ const o = this.api.getDocumentModifier(), r = `${t}px`;
235
+ n.forEach((a) => {
236
+ o.modifyHtml(a).setStyle("height", r);
237
+ }), o.apply(new g(`Update row spacing to ${t}px`));
181
238
  }
239
+ // ========================================================================
240
+ // Mobile Spacing Handlers
241
+ // ========================================================================
182
242
  /**
183
- * Stores column spacing value in block data attribute
243
+ * Handles column spacing changes for mobile.
244
+ * Applies horizontal padding only to the mobile container elements.
184
245
  */
185
- _storeColumnSpacing(t) {
246
+ _onMobileColumnSpacingChange(t) {
186
247
  if (!this.currentNode)
187
248
  return;
188
- const e = this.currentNode.querySelector(".ins-recommendation-v3-block-v2");
189
- e && this.api.getDocumentModifier().modifyHtml(e).setAttribute(P.COLUMN_SPACING, t.toString()).apply(new g("Store column spacing"));
249
+ p.updateConfig(
250
+ this.api,
251
+ this.currentNode,
252
+ { mobileColumnSpacing: t },
253
+ `Changed mobile column spacing to ${t}px`
254
+ ), this._storeDataAttribute(O.MOBILE_COLUMN_SPACING, t);
255
+ const n = p.getConfig(this.currentNode).layout || b(this.currentNode), o = this.api.getDocumentModifier(), a = `0 ${t / 2}px`, l = this.currentNode.querySelector(E);
256
+ l && (n === "grid" ? Array.from(
257
+ l.querySelectorAll(".attribute-cell")
258
+ ).forEach((s) => {
259
+ o.modifyHtml(s).setStyle("padding", a);
260
+ }) : Array.from(
261
+ l.querySelectorAll(".product-card-wrapper")
262
+ ).forEach((s) => {
263
+ "parent" in s && s.parent() && o.modifyHtml(s.parent()).setStyle("padding", a);
264
+ }), o.apply(new g(`Update mobile column spacing to ${t}px`)));
190
265
  }
191
266
  /**
192
- * Stores row spacing value in block data attribute
267
+ * Handles row spacing changes for mobile.
268
+ * Applies height only to spacer elements in the mobile container.
193
269
  */
194
- _storeRowSpacing(t) {
270
+ _onMobileRowSpacingChange(t) {
195
271
  if (!this.currentNode)
196
272
  return;
197
- const e = this.currentNode.querySelector(".ins-recommendation-v3-block-v2");
198
- e && this.api.getDocumentModifier().modifyHtml(e).setAttribute(P.ROW_SPACING, t.toString()).apply(new g("Store row spacing"));
273
+ p.updateConfig(
274
+ this.api,
275
+ this.currentNode,
276
+ { mobileRowSpacing: t },
277
+ `Changed mobile row spacing to ${t}px`
278
+ ), this._storeDataAttribute(O.MOBILE_ROW_SPACING, t);
279
+ const e = this.currentNode.querySelector(E);
280
+ if (!e)
281
+ return;
282
+ const n = Array.from(
283
+ e.querySelectorAll(".spacer")
284
+ );
285
+ if (!n.length)
286
+ return;
287
+ const o = this.api.getDocumentModifier(), r = `${t}px`;
288
+ n.forEach((a) => {
289
+ o.modifyHtml(a).setStyle("height", r);
290
+ }), o.apply(new g(`Update mobile row spacing to ${t}px`));
291
+ }
292
+ // ========================================================================
293
+ // Data Attribute Storage
294
+ // ========================================================================
295
+ /**
296
+ * Stores a spacing value as a data attribute on the block root element
297
+ */
298
+ _storeDataAttribute(t, e) {
299
+ const n = x(this.currentNode);
300
+ n && this.api.getDocumentModifier().modifyHtml(n).setAttribute(t, e.toString()).apply(new g(`Store ${t}`));
199
301
  }
302
+ // ========================================================================
303
+ // Event Listeners
304
+ // ========================================================================
200
305
  _listenToFormUpdates() {
201
- this.api.onValueChanged(s.COLUMN_SPACING, (t) => {
306
+ this.api.onValueChanged(i.COLUMN_SPACING, (t) => {
202
307
  const e = parseInt(t);
203
308
  Number.isNaN(e) || this._debouncedOnColumnSpacingChange(e);
204
- }), this.api.onValueChanged(s.ROW_SPACING, (t) => {
309
+ }), this.api.onValueChanged(i.ROW_SPACING, (t) => {
205
310
  const e = parseInt(t);
206
311
  Number.isNaN(e) || this._debouncedOnRowSpacingChange(e);
312
+ }), this.api.onValueChanged(i.MOBILE_COLUMN_SPACING, (t) => {
313
+ const e = parseInt(t);
314
+ Number.isNaN(e) || this._debouncedOnMobileColumnSpacingChange(e);
315
+ }), this.api.onValueChanged(i.MOBILE_ROW_SPACING, (t) => {
316
+ const e = parseInt(t);
317
+ Number.isNaN(e) || this._debouncedOnMobileRowSpacingChange(e);
207
318
  });
208
319
  }
209
320
  /**
210
321
  * Subscribe to store orientation changes
211
- * Updates column spacing visibility when layout changes via the layout control
322
+ * Updates spacing visibility when layout changes via the layout control
212
323
  */
213
324
  _subscribeToOrientationChanges() {
214
325
  this.unsubscribeOrientation && this.unsubscribeOrientation(), this.unsubscribeOrientation = this.store.$subscribe((t) => {
215
- t.type === "patch object" && this._updateColumnSpacingVisibility();
326
+ t.type === "patch object" && (this._updateSpacingVisibility(), this._setFormValues());
216
327
  });
217
328
  }
329
+ /**
330
+ * Subscribes to editor preview mode changes via Stripo API.
331
+ * Toggles which spacing controls (desktop/mobile) are visible.
332
+ */
333
+ _subscribeToEditorModeChanges() {
334
+ this.api.onEditorStatePropUpdated(
335
+ y.previewDeviceMode,
336
+ () => {
337
+ this._updateSpacingVisibility();
338
+ }
339
+ );
340
+ }
218
341
  }
219
342
  export {
220
- R as SPACING_CONTROL_ID,
221
- $ as SpacingControl
343
+ W as SPACING_CONTROL_ID,
344
+ X as SpacingControl
222
345
  };
@@ -1,5 +1,5 @@
1
- import { IconsRegistry as t } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- class o extends t {
1
+ import { IconsRegistry as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ class o extends r {
3
3
  registerIconsSvg(C) {
4
4
  C["recommendation-icon"] = `
5
5
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
@@ -59,41 +59,6 @@ class o extends t {
59
59
  <circle cx="3" cy="16" r="1" stroke="currentColor" stroke-width="1"/>
60
60
  <rect x="7" y="15" width="11" height="2" rx="1"/>
61
61
  </svg>
62
- `, C["migration-info-icon"] = `
63
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
64
- <g transform="translate(3, 2.5)">
65
- <path d="M6.87812 0.141942C10.7873 -0.580665 14.6797 1.51065 16.201 5.16436C17.7344
66
- 8.84685 16.432 13.0909 13.0906 15.3015C9.77511 17.4946 5.36819 17.08 2.52785
67
- 14.3193L2.46105 14.2536C0.882709 12.6854 -0.00259777 10.5591 5.72603e-06
68
- 8.34301L0.000643642 8.24974C0.0491816 4.30543 2.87651 0.926565 6.78576
69
- 0.159555L6.87812 0.141942ZM14.5911 5.82406C13.3749 2.90345 10.2486 1.24158 7.12372
70
- 1.85468C3.99888 2.46779 1.74568 5.18516 1.74194 8.34505C1.73988 10.1027 2.44203
71
- 11.789 3.69379 13.0328C5.94435 15.269 9.4739 15.617 12.1241 13.8638C14.7742 12.1106
72
- 15.8071 8.74458 14.5911 5.82406Z" fill="#258DDE"/>
73
- <path d="M12.5195 13.5806C12.8537 13.2479 13.3933 13.2417 13.7351 13.5628L13.7512
74
- 13.5783L17.7437 17.5239C18.0845 17.8607 18.0856 18.4077 17.7461 18.7458C17.4066
75
- 19.0838 16.8551 19.0849 16.5143 18.7481L12.5218 14.8025L12.5061 14.7866C12.1811
76
- 14.4487 12.1853 13.9134 12.5195 13.5806Z" fill="#258DDE"/>
77
- <path d="M6.71262 5.42913C6.37248 5.09172 5.82105 5.09172 5.48092 5.42913C5.14079
78
- 5.76655 5.14079 6.3136 5.48092 6.65104L6.71262 5.42913ZM7.80353 8.95504C8.14367
79
- 9.29246 8.69506 9.29246 9.0352 8.95504C9.37534 8.61762 9.37534 8.07053 9.0352
80
- 7.73311L7.80353 8.95504ZM9.0352 7.73311C8.69506 7.39569 8.14367 7.39569 7.80353
81
- 7.73311C7.46339 8.07053 7.46339 8.61762 7.80353 8.95504L9.0352 7.73311ZM10.1261
82
- 11.259C10.4663 11.5965 11.0176 11.5965 11.3578 11.259C11.6979 10.9216 11.6979
83
- 10.3745 11.3578 10.0371L10.1261 11.259ZM9.0352 8.95504C9.37534 8.61762 9.37534
84
- 8.07053 9.0352 7.73311C8.69506 7.39569 8.14367 7.39569 7.80353 7.73311L9.0352
85
- 8.95504ZM5.48092 10.0371C5.14079 10.3745 5.14079 10.9216 5.48092 11.259C5.82105
86
- 11.5965 6.37248 11.5965 6.71262 11.259L5.48092 10.0371ZM7.80353 7.73311C7.46339
87
- 8.07053 7.46339 8.61762 7.80353 8.95504C8.14367 9.29246 8.69506 9.29246 9.0352
88
- 8.95504L7.80353 7.73311ZM11.3578 6.65104C11.6979 6.3136 11.6979 5.76655 11.3578
89
- 5.42913C11.0176 5.09172 10.4663 5.09172 10.1261 5.42913L11.3578 6.65104ZM5.48092
90
- 6.65104L7.80353 8.95504L9.0352 7.73311L6.71262 5.42913L5.48092 6.65104ZM7.80353
91
- 8.95504L10.1261 11.259L11.3578 10.0371L9.0352 7.73311L7.80353 8.95504ZM7.80353
92
- 7.73311L5.48092 10.0371L6.71262 11.259L9.0352 8.95504L7.80353 7.73311ZM9.0352
93
- 8.95504L11.3578 6.65104L10.1261 5.42913L7.80353 7.73311L9.0352 8.95504Z"
94
- fill="#258DDE"/>
95
- </g>
96
- </svg>
97
62
  `;
98
63
  }
99
64
  }
@@ -22,54 +22,6 @@ const n = `/* Utils */
22
22
  ue-orderable.orderable-disabled .droppable-icon {
23
23
  display: none;
24
24
  }
25
-
26
- /* ─── Migration Info Box ─────────────────────────────────────────────── */
27
- /* Shown in the settings panel title when a block was migrated from legacy */
28
-
29
- /* Layout variables for positioning the absolutely-placed info box */
30
- :host {
31
- --rec-migration-padding: 16px;
32
- --rec-migration-title-height: 61px;
33
- --rec-migration-box-height: 98px;
34
- }
35
-
36
- /* Push tabs down when info box is present inside the control panel header */
37
- .control-panel-header:has(.recommendation-migration-info) {
38
- position: relative;
39
- margin-bottom: calc(2 * var(--rec-migration-padding) + var(--rec-migration-box-height));
40
- }
41
-
42
- /* Info box container */
43
- .recommendation-migration-info {
44
- display: flex;
45
- align-items: flex-start;
46
- gap: 8px;
47
- padding: 12px;
48
- background: var(--guido-color-background-onpage-message-info);
49
- border: 1px solid var(--guido-color-border-onpage-message-info);
50
- border-radius: 4px;
51
- box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
52
- position: absolute;
53
- left: var(--rec-migration-padding);
54
- right: var(--rec-migration-padding);
55
- top: calc(var(--rec-migration-padding) + var(--rec-migration-title-height));
56
- }
57
-
58
- /* Icon — 18x19 icon inside a 24x24 bounding box (matches Figma) */
59
- .recommendation-migration-info__icon {
60
- flex-shrink: 0;
61
- width: 24px;
62
- height: 24px;
63
- }
64
-
65
- /* Text content */
66
- .recommendation-migration-info__text {
67
- margin: 4px 0;
68
- white-space: normal;
69
- font-size: 13px;
70
- font-weight: 400;
71
- line-height: 16px;
72
- }
73
25
  `;
74
26
  export {
75
27
  n as default