@useinsider/guido 3.8.3-beta.96b5eeb → 3.9.0-beta.ba394b1

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 (67) hide show
  1. package/dist/@types/config/schemas.js +70 -66
  2. package/dist/composables/useCustomInterfaceAppearance.js +16 -18
  3. package/dist/composables/usePreviewMode.js +15 -14
  4. package/dist/composables/useRecommendationPreview.js +111 -0
  5. package/dist/composables/useStripo.js +39 -37
  6. package/dist/composables/useStripoNotifications.js +26 -0
  7. package/dist/config/compiler/recommendationCompilerRules.js +1 -1
  8. package/dist/config/compiler/utils/recommendationCompilerUtils.js +88 -80
  9. package/dist/config/migrator/recommendation/htmlBuilder.js +53 -52
  10. package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
  11. package/dist/enums/toaster.js +2 -2
  12. package/dist/extensions/Blocks/Items/block.js +48 -29
  13. package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +62 -45
  14. package/dist/extensions/Blocks/Recommendation/block.js +64 -42
  15. package/dist/extensions/Blocks/Recommendation/canvasPreview.css.js +16 -0
  16. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
  17. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +461 -363
  18. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +99 -87
  19. package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
  20. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +162 -160
  21. package/dist/extensions/Blocks/Recommendation/extension.js +30 -29
  22. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
  23. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
  24. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +3 -1
  25. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +130 -96
  26. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +43 -54
  27. package/dist/extensions/Blocks/Recommendation/templates/index.js +17 -14
  28. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +86 -80
  29. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +31 -40
  30. package/dist/extensions/Blocks/Recommendation/templates/utils.js +155 -102
  31. package/dist/extensions/Blocks/Recommendation/useRecommendationBlockWarning.js +7 -7
  32. package/dist/extensions/Blocks/controlFactories.js +76 -57
  33. package/dist/services/templateLibraryApi.js +9 -8
  34. package/dist/src/@types/config/schemas.d.ts +16 -0
  35. package/dist/src/composables/useConfig.d.ts +4 -0
  36. package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
  37. package/dist/src/composables/useStripoNotifications.d.ts +10 -0
  38. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
  39. package/dist/src/enums/toaster.d.ts +2 -2
  40. package/dist/src/extensions/Blocks/CouponBlock/controls/index.d.ts +1 -1
  41. package/dist/src/extensions/Blocks/Items/block.d.ts +8 -0
  42. package/dist/src/extensions/Blocks/Items/controls/index.d.ts +3 -3
  43. package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.d.ts +1 -1
  44. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  45. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +29 -3
  46. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
  47. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
  48. package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
  49. package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +1 -1
  50. package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +1 -1
  51. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +1 -1
  52. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +1 -1
  53. package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +1 -1
  54. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
  55. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +13 -1
  56. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  57. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
  58. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +10 -1
  59. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  60. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +51 -1
  61. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
  62. package/dist/src/extensions/Blocks/controlFactories.d.ts +10 -1
  63. package/dist/src/stores/config.d.ts +36 -0
  64. package/dist/src/stores/toaster.d.ts +2 -3
  65. package/dist/stores/toaster.js +10 -10
  66. package/package.json +2 -2
  67. package/dist/static/styles/components/notification.css.js +0 -74
@@ -1,36 +1,36 @@
1
1
  import { ModificationDescription as b } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { DefaultConfigValues as o, SETTINGS_ENUMS as n, ItemInCartOptions as g } from "../enums/settingsEnums.js";
2
+ import { DefaultConfigValues as i, SETTINGS_ENUMS as n, ItemInCartOptions as g } from "../enums/settingsEnums.js";
3
3
  function _() {
4
4
  return String(Date.now() + Math.floor(Math.random() * 1e3));
5
5
  }
6
6
  const E = (r) => r.replace(/\$/g, "$$$$");
7
- function S() {
7
+ function y() {
8
8
  return {
9
9
  initialized: !0,
10
10
  blockInstanceId: _(),
11
11
  source: n.ITEMS_TYPE.CART_ITEMS,
12
12
  type: n.ITEMS_TYPE.CART_ITEMS,
13
- itemsSelectValue: o.cartItemsSelectControlValue,
13
+ itemsSelectValue: i.cartItemsSelectControlValue,
14
14
  orientation: n.ORIENTATION.VERTICAL,
15
- nameTrimming: o.productNameTrimmingControlValue === "1",
16
- priceHideDiscount: o.productPriceHideDiscountControlValue === "1",
17
- priceFormatted: o.productPriceFormattedControlValue === "1",
15
+ nameTrimming: i.productNameTrimmingControlValue === "1",
16
+ priceHideDiscount: i.productPriceHideDiscountControlValue === "1",
17
+ priceFormatted: i.productPriceFormattedControlValue === "1",
18
18
  priceSinglePrice: !1,
19
- priceCurrencySymbol: o.productPriceCurrencySymbolControlValue,
20
- priceCurrencyLocation: o.productPriceCurrencyLocationControlValue,
19
+ priceCurrencySymbol: i.productPriceCurrencySymbolControlValue,
20
+ priceCurrencyLocation: i.productPriceCurrencyLocationControlValue,
21
21
  priceOrientation: "horizontal",
22
- quantityControlEnabled: o.productQuantityControlEnabled === "1",
23
- buttonLink: o.productButtonLinkControlValue,
24
- imageLink: o.productImageLinkControlValue,
22
+ quantityControlEnabled: i.productQuantityControlEnabled === "1",
23
+ buttonLink: i.productButtonLinkControlValue,
24
+ imageLink: i.productImageLinkControlValue,
25
25
  buttonLabel: "Buy",
26
26
  buttonFullWidth: !0,
27
27
  // Default to full width (es-fw class)
28
- imageVisible: o.productImageVisible === "1",
29
- nameVisible: o.productNameVisible === "1",
30
- quantityVisible: o.productQuantityVisible === "1",
31
- priceVisible: o.productPriceVisible === "1",
32
- originalPriceVisible: o.productOriginalPriceVisible === "1",
33
- buttonVisible: o.productButtonVisible === "1"
28
+ imageVisible: i.productImageVisible === "1",
29
+ nameVisible: i.productNameVisible === "1",
30
+ quantityVisible: i.productQuantityVisible === "1",
31
+ priceVisible: i.productPriceVisible === "1",
32
+ originalPriceVisible: i.productOriginalPriceVisible === "1",
33
+ buttonVisible: i.productButtonVisible === "1"
34
34
  };
35
35
  }
36
36
  function p(r) {
@@ -50,26 +50,26 @@ function m(r) {
50
50
  PURCHASED_ITEMS: n.ITEMS_TYPE.PURCHASED_ITEMS
51
51
  }[r] || n.ITEMS_TYPE.CART_ITEMS : n.ITEMS_TYPE.CART_ITEMS;
52
52
  }
53
- function I(r, t) {
53
+ function f(r, t) {
54
54
  if (!r)
55
- return o.cartItemsSelectControlValue;
55
+ return i.cartItemsSelectControlValue;
56
56
  if (r.includes("{{"))
57
57
  return r;
58
58
  if (/^\d+$/.test(r)) {
59
- const e = parseInt(r) - 1, i = g[t];
60
- if (i && i[e])
61
- return i[e].value;
59
+ const e = parseInt(r) - 1, o = g[t];
60
+ if (o && o[e])
61
+ return o[e].value;
62
62
  }
63
- return o.cartItemsSelectControlValue;
63
+ return i.cartItemsSelectControlValue;
64
64
  }
65
65
  function C(r) {
66
66
  const t = r.querySelector("esd-config-block");
67
67
  if (!t)
68
68
  return null;
69
- const e = (c, s) => c == null ? s : c === "1" || c === "true", i = (c, s) => c || s, u = t.getAttribute("data-type"), a = m(u), d = t.getAttribute("data-cart_items_select_control_value"), l = I(d, a);
69
+ const e = (u, s) => u == null ? s : u === "1" || u === "true", o = (u, s) => u || s, c = t.getAttribute("data-type"), a = m(c), d = t.getAttribute("data-cart_items_select_control_value"), l = f(d, a);
70
70
  return {
71
71
  initialized: e(t.getAttribute("data-initialized"), !1),
72
- blockInstanceId: i(
72
+ blockInstanceId: o(
73
73
  t.getAttribute("data-block-instance-id"),
74
74
  _()
75
75
  ),
@@ -93,28 +93,28 @@ function C(r) {
93
93
  t.getAttribute("data-product_price_control_single_price"),
94
94
  !1
95
95
  ),
96
- priceCurrencySymbol: i(
96
+ priceCurrencySymbol: o(
97
97
  t.getAttribute("data-product_price_control_currency_symbol"),
98
- o.productPriceCurrencySymbolControlValue
98
+ i.productPriceCurrencySymbolControlValue
99
99
  ),
100
- priceCurrencyLocation: i(
100
+ priceCurrencyLocation: o(
101
101
  t.getAttribute("data-product_price_currency_location"),
102
- o.productPriceCurrencyLocationControlValue
102
+ i.productPriceCurrencyLocationControlValue
103
103
  ),
104
104
  priceOrientation: t.getAttribute("data-product_original_price_control_orientation") || "horizontal",
105
105
  quantityControlEnabled: e(
106
106
  t.getAttribute("data-product_quantity_control_enabled"),
107
107
  !0
108
108
  ),
109
- buttonLink: i(
109
+ buttonLink: o(
110
110
  t.getAttribute("data-product_button_link"),
111
- o.productButtonLinkControlValue
111
+ i.productButtonLinkControlValue
112
112
  ),
113
- imageLink: i(
113
+ imageLink: o(
114
114
  t.getAttribute("data-product_image_link"),
115
- o.productImageLinkControlValue
115
+ i.productImageLinkControlValue
116
116
  ),
117
- buttonLabel: i(
117
+ buttonLabel: o(
118
118
  t.getAttribute("data-product_button_control_label"),
119
119
  "Buy"
120
120
  ),
@@ -149,28 +149,45 @@ function C(r) {
149
149
  )
150
150
  };
151
151
  }
152
- function y(r) {
152
+ function I(r) {
153
+ if (typeof r.getAttribute != "function")
154
+ return null;
155
+ const t = r.getAttribute("esd-ext-config");
156
+ if (!t)
157
+ return null;
158
+ try {
159
+ const e = JSON.parse(t);
160
+ if (e && e.initialized)
161
+ return e;
162
+ } catch {
163
+ }
164
+ return null;
165
+ }
166
+ function A(r) {
153
167
  const t = p(r);
154
168
  if (!t)
155
169
  return null;
156
170
  const e = t.getNodeConfig();
157
171
  if (e && e.initialized)
158
172
  return e;
159
- const i = C(t);
160
- return i || null;
173
+ const o = I(t);
174
+ if (o)
175
+ return o;
176
+ const c = C(t);
177
+ return c || null;
161
178
  }
162
- function A(r, t, e, i) {
163
- const u = p(r);
164
- if (!u)
179
+ function V(r, t, e, o) {
180
+ const c = p(r);
181
+ if (!c)
165
182
  return;
166
- const d = { ...u.getNodeConfig() || {}, ...e }, l = i ?? t.getDocumentModifier();
167
- l.modifyHtml(u).setNodeConfig(d), i || l.apply(new b("Update Items block configuration"));
183
+ const d = { ...c.getNodeConfig() || {}, ...e }, l = o ?? t.getDocumentModifier();
184
+ l.modifyHtml(c).setNodeConfig(d), o || l.apply(new b("Update Items block configuration"));
168
185
  }
169
186
  export {
170
187
  E as escapeReplacement,
171
188
  _ as generateBlockInstanceId,
172
- S as getDefaultItemsBlockConfig,
173
- y as getItemsBlockConfig,
189
+ y as getDefaultItemsBlockConfig,
190
+ A as getItemsBlockConfig,
174
191
  p as getItemsBlockContainer,
175
- A as setItemsBlockConfig
192
+ V as setItemsBlockConfig
176
193
  };
@@ -1,34 +1,34 @@
1
- var k = Object.defineProperty;
2
- var B = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
- var d = (a, r, t) => B(a, typeof r != "symbol" ? r + "" : r, t);
1
+ var B = Object.defineProperty;
2
+ var D = (a, c, t) => c in a ? B(a, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[c] = t;
3
+ var h = (a, c, t) => D(a, typeof c != "symbol" ? c + "" : c, t);
4
4
  import { BlockId as R } from "../../../enums/block.js";
5
5
  import { getMigrationBannerHtml as y } from "../../../utils/migrationBannerHtml.js";
6
- import { Block as D, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
- import { regenerateMobileProductRows as b } from "./controls/main/utils.js";
8
- import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as A } from "./controls/mobileLayout/cssRules.js";
9
- import { RecommendationConfigService as c } from "./services/configService.js";
10
- import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
11
- import { getDefaultTemplate as E } from "./templates/grid/template.js";
6
+ import { Block as b, BlockCompositionType as A, ModificationDescription as g } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
+ import { regenerateMobileProductRows as C } from "./controls/main/utils.js";
8
+ import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as E } from "./controls/mobileLayout/cssRules.js";
9
+ import { RecommendationConfigService as s } from "./services/configService.js";
10
+ import { useRecommendationExtensionStore as d } from "./store/recommendation.js";
11
+ import { getDefaultTemplate as S } from "./templates/grid/template.js";
12
12
  import { useRecommendationBlockWarning as M } from "./useRecommendationBlockWarning.js";
13
- const I = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
14
- let _ = !1;
15
- class H extends D {
13
+ const _ = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id", I = "hide-price";
14
+ let k = !1;
15
+ class P extends b {
16
16
  constructor() {
17
17
  super();
18
18
  /**
19
19
  * Stores the ID generated in getTemplate() so onCreated() can reuse it.
20
20
  * This avoids generating a new (different) ID in onCreated().
21
21
  */
22
- d(this, "_pendingBlockId", null);
22
+ h(this, "_pendingBlockId", null);
23
23
  }
24
24
  getId() {
25
- return I;
25
+ return _;
26
26
  }
27
27
  getIcon() {
28
28
  return "recommendation-icon";
29
29
  }
30
30
  getBlockCompositionType() {
31
- return C.CONTAINER;
31
+ return A.CONTAINER;
32
32
  }
33
33
  getName() {
34
34
  return this.api.translate("Recommendation Block");
@@ -40,7 +40,7 @@ class H extends D {
40
40
  }
41
41
  getSettingsPanelTitleHtml() {
42
42
  return y(
43
- I,
43
+ _,
44
44
  this.api.translate("Recommendation Block"),
45
45
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
46
46
  );
@@ -48,8 +48,11 @@ class H extends D {
48
48
  allowInnerBlocksDND() {
49
49
  return !1;
50
50
  }
51
+ // A saved module carries its config in the esd-config blob, restored on
52
+ // re-drop by migrateFromDataAttributes; per-element styles ride the
53
+ // preserved inner HTML. (onCreated early-returns for re-drops, never clobbers.)
51
54
  canBeSavedAsModule() {
52
- return !1;
55
+ return !0;
53
56
  }
54
57
  /**
55
58
  * Returns the template HTML for a new recommendation block.
@@ -60,7 +63,7 @@ class H extends D {
60
63
  */
61
64
  getTemplate() {
62
65
  const t = this._generateNextId();
63
- return this._pendingBlockId = t, E(t);
66
+ return this._pendingBlockId = t, S(t);
64
67
  }
65
68
  /**
66
69
  * Called when a new block is dropped into the template
@@ -83,20 +86,20 @@ class H extends D {
83
86
  }
84
87
  const i = this._pendingBlockId ?? this._generateNextId();
85
88
  this._pendingBlockId = null, this._assignRecommendationId(t, i);
86
- const { config: n, wasFreshDrop: o } = c.initializeConfig(
89
+ const { config: n, wasFreshDrop: o } = s.initializeConfig(
87
90
  this.api,
88
91
  t,
89
92
  { recommendationId: i }
90
- ), s = g();
91
- if (s.setCurrentBlock(i), o) {
93
+ ), r = d();
94
+ if (r.setCurrentBlock(i), this._stampHidePrice(t, n.priceHideIfSameAsDiscounted), o) {
92
95
  p(this.api);
93
96
  const l = this._getBlockElement(t);
94
- l && (f(this.api, l, !0), b({
97
+ l && (f(this.api, l, !0), C({
95
98
  currentNode: t,
96
99
  documentModifier: this.api.getDocumentModifier()
97
100
  }));
98
101
  }
99
- s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
102
+ r.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
100
103
  }
101
104
  /**
102
105
  * Called when the document changes or template is loaded
@@ -109,20 +112,20 @@ class H extends D {
109
112
  if (!(!t || !("getNodeConfig" in t))) {
110
113
  if (!this._getRecommendationId(t)) {
111
114
  const e = this._generateNextId();
112
- this._assignRecommendationId(t, e), c.hasConfig(t) && c.updateConfig(
115
+ this._assignRecommendationId(t, e), s.hasConfig(t) && s.updateConfig(
113
116
  this.api,
114
117
  t,
115
118
  { recommendationId: e },
116
119
  "Assign recommendation ID to legacy block"
117
120
  );
118
121
  }
119
- this._healLingeringDuplicate(t), c.needsMigration(t) && this._migrateFromLegacy(t);
122
+ this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
120
123
  try {
121
- _ || (p(this.api), _ = !0);
122
- const e = c.getConfig(t), i = this._getBlockElement(t);
124
+ k || (p(this.api), k = !0);
125
+ const e = s.getConfig(t), i = this._getBlockElement(t);
123
126
  if (i) {
124
127
  const n = !e.mobileLayoutEnabled;
125
- A(i) !== n && f(this.api, i, n);
128
+ E(i) !== n && f(this.api, i, n);
126
129
  }
127
130
  } catch {
128
131
  }
@@ -136,7 +139,7 @@ class H extends D {
136
139
  */
137
140
  onDelete(t) {
138
141
  const e = this._getRecommendationId(t);
139
- e && g().removeBlockState(e);
142
+ e && d().removeBlockState(e);
140
143
  }
141
144
  /**
142
145
  * Warns (dark advisory toaster) when the design holds more than one live
@@ -166,8 +169,8 @@ class H extends D {
166
169
  const e = this.api.getDocumentRoot();
167
170
  e && "querySelectorAll" in e && e.querySelectorAll(`.${m}`).forEach((n) => {
168
171
  if ("getAttribute" in n) {
169
- const o = n.getAttribute(u), s = o ? parseInt(o) : 0;
170
- s > t && (t = s);
172
+ const o = n.getAttribute(u), r = o ? parseInt(o) : 0;
173
+ r > t && (t = r);
171
174
  }
172
175
  });
173
176
  } catch {
@@ -201,13 +204,13 @@ class H extends D {
201
204
  const o = this._getBlockElement(t);
202
205
  if (!o)
203
206
  return;
204
- let s = -1;
207
+ let r = -1;
205
208
  for (let l = 0; l < n.length; l++)
206
209
  if (n[l] === o) {
207
- s = l;
210
+ r = l;
208
211
  break;
209
212
  }
210
- if (s <= 0)
213
+ if (r <= 0)
211
214
  return;
212
215
  this._reassignDuplicateId(t, e);
213
216
  } catch {
@@ -227,7 +230,7 @@ class H extends D {
227
230
  }
228
231
  /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
229
232
  _handleDuplicate(t, e) {
230
- const i = this._reassignDuplicateId(t, e), n = g();
233
+ const i = this._reassignDuplicateId(t, e), n = d();
231
234
  n.cloneBlockState(e, i), n.setCurrentBlock(i), this._warnIfMultipleBlocks();
232
235
  }
233
236
  /**
@@ -243,7 +246,7 @@ class H extends D {
243
246
  */
244
247
  _reassignDuplicateId(t, e) {
245
248
  const i = this._generateNextId(), n = this._getBlockElement(t);
246
- return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), c.hasConfig(t) && c.updateConfig(
249
+ return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), s.hasConfig(t) && s.updateConfig(
247
250
  this.api,
248
251
  t,
249
252
  { recommendationId: i },
@@ -260,8 +263,8 @@ class H extends D {
260
263
  _reassignInstanceClass(t, e, i) {
261
264
  if (!("getAttribute" in t))
262
265
  return;
263
- const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, s = this.api.getDocumentModifier();
264
- s.modifyHtml(t).removeClass(n).setClass(o), s.apply(new h(
266
+ const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, r = this.api.getDocumentModifier();
267
+ r.modifyHtml(t).removeClass(n).setClass(o), r.apply(new g(
265
268
  `Reassign recommendation instance class ${n} -> ${o}`
266
269
  ));
267
270
  }
@@ -276,7 +279,26 @@ class H extends D {
276
279
  if (!i)
277
280
  return;
278
281
  const n = this.api.getDocumentModifier();
279
- n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new h(`Assign recommendation ID ${e}`));
282
+ n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new g(`Assign recommendation ID ${e}`));
283
+ }
284
+ /**
285
+ * Stamps the `hide-price` attribute (read by email-service at send time) on
286
+ * the block element from the config flag.
287
+ */
288
+ _stampHidePrice(t, e) {
289
+ const i = this._getBlockElement(t);
290
+ i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(I, String(e)).apply(new g("Stamp hide-price"));
291
+ }
292
+ /**
293
+ * Stamps `hide-price` from config only when the block lacks the attribute —
294
+ * heals templates saved before this feature without dirtying current ones.
295
+ */
296
+ _healHidePriceAttr(t) {
297
+ const e = this._getBlockElement(t);
298
+ if (!e || !("getAttribute" in e) || e.getAttribute(I) !== null)
299
+ return;
300
+ const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
301
+ this._stampHidePrice(t, i);
280
302
  }
281
303
  /**
282
304
  * Gets the recommendation-id from a block node
@@ -306,10 +328,10 @@ class H extends D {
306
328
  * Migrate configuration from legacy format
307
329
  */
308
330
  _migrateFromLegacy(t) {
309
- c.migrateFromDataAttributes(this.api, t);
331
+ s.migrateFromDataAttributes(this.api, t);
310
332
  }
311
333
  }
312
334
  export {
313
- I as BLOCK_ID,
314
- H as RecommendationBlock
335
+ _ as BLOCK_ID,
336
+ P as RecommendationBlock
315
337
  };
@@ -0,0 +1,16 @@
1
+ const e = `/*
2
+ * Editor-canvas-only styles (ExtensionBuilder.withPreviewStyles).
3
+ * Never reaches the exported email HTML — send-time behavior stays in email-service.
4
+ */
5
+
6
+ /* Hide-if-same: mirror the email-service rule in the canvas. The block-level
7
+ \`hide-price\` attr is the toggle; \`data-same-price\` is stamped per old-price
8
+ cell by the renderers / in-place price updates. Hiding the <p> (not the td)
9
+ keeps inline price columns from collapsing, matching the preview look. */
10
+ .recommendation-block-v2[hide-price="true"] .product-old-price[data-same-price="true"] p {
11
+ display: none;
12
+ }
13
+ `;
14
+ export {
15
+ e as default
16
+ };
@@ -1,34 +1,34 @@
1
- import { DEFAULT_COLUMN_SPACING as R, DEFAULT_ROW_SPACING as U, DEFAULT_MOBILE_ROW_SPACING as i, DEFAULT_MOBILE_COLUMN_SPACING as s, DEFAULT_MOBILE_CARDS_IN_ROW as o, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
2
- import { ATTR_PRODUCT_IMAGE as _, ATTR_PRODUCT_NAME as e, ATTR_PRODUCT_OLD_PRICE as t, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as I, ATTR_PRODUCT_BUTTON as n } from "./selectors.js";
3
- const O = {
1
+ import { DEFAULT_COLUMN_SPACING as n, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as R, DEFAULT_MOBILE_COLUMN_SPACING as U, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
2
+ import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as t, ATTR_PRODUCT_OLD_PRICE as _, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as i, ATTR_PRODUCT_BUTTON as I } from "./selectors.js";
3
+ const D = {
4
4
  code: "USD",
5
5
  symbol: "USD",
6
6
  alignment: "after",
7
7
  decimalCount: 2,
8
8
  decimalSeparator: ".",
9
9
  thousandSeparator: ","
10
- }, D = {
10
+ }, O = {
11
11
  textBefore: "",
12
12
  textAfter: ""
13
- }, A = {
13
+ }, a = {
14
14
  textBefore: "",
15
15
  textAfter: ""
16
- }, a = [
17
- _,
18
- e,
16
+ }, A = [
17
+ o,
19
18
  t,
19
+ _,
20
20
  T,
21
21
  r,
22
- I,
23
- n
24
- ], E = {
25
- [_]: !0,
26
- [e]: !0,
27
- [T]: !0,
22
+ i,
23
+ I
24
+ ], c = {
25
+ [o]: !0,
28
26
  [t]: !0,
27
+ [T]: !0,
28
+ [_]: !0,
29
29
  [r]: !1,
30
- [I]: !1,
31
- [n]: !0
30
+ [i]: !1,
31
+ [I]: !0
32
32
  }, l = {
33
33
  // Settings
34
34
  strategy: "mostPopular",
@@ -36,36 +36,45 @@ const O = {
36
36
  size: "6",
37
37
  shuffleProducts: !1,
38
38
  language: "en_US",
39
- currency: O,
39
+ currency: D,
40
40
  filters: [],
41
41
  // Layout
42
42
  layout: "grid",
43
43
  cardsInRow: C,
44
- mobileCardsInRow: o,
44
+ mobileCardsInRow: e,
45
45
  mobileLayoutEnabled: !1,
46
- previousMobileCardsInRow: o,
47
- columnSpacing: R,
48
- rowSpacing: U,
49
- mobileColumnSpacing: s,
50
- mobileRowSpacing: i,
46
+ previousMobileCardsInRow: e,
47
+ columnSpacing: n,
48
+ rowSpacing: s,
49
+ mobileColumnSpacing: U,
50
+ mobileRowSpacing: R,
51
51
  // Composition
52
- composition: a,
53
- visibility: E,
52
+ composition: A,
53
+ visibility: c,
54
54
  // Element settings
55
- omnibusPrice: D,
56
- omnibusDiscount: A,
55
+ omnibusPrice: O,
56
+ omnibusDiscount: a,
57
57
  textTrimming: !1,
58
+ // Price placement (block-level, affects all cards)
59
+ // Default ON = current stacked look, so existing templates are unaffected.
60
+ priceMovedToNextLine: !0,
61
+ // Default OFF: the original price always shows; the user opts in to hide it
62
+ // when it equals the sale price. Mirrors email-service's `hide-price` default
63
+ // of "false" (the actual hiding happens server-side at send).
64
+ priceHideIfSameAsDiscounted: !1,
58
65
  // Meta
66
+ // Version NOT bumped: mergeWithDefaults() backfills the two new fields from
67
+ // defaults, so no data transform (and no needsMigration trigger) is required.
59
68
  configVersion: 1,
60
69
  recommendationId: 0
61
70
  }, N = [11, 12], m = 1;
62
71
  export {
63
72
  m as CURRENT_CONFIG_VERSION,
64
- a as DEFAULT_COMPOSITION,
65
- O as DEFAULT_CURRENCY,
73
+ A as DEFAULT_COMPOSITION,
74
+ D as DEFAULT_CURRENCY,
66
75
  l as DEFAULT_NODE_CONFIG,
67
- A as DEFAULT_OMNIBUS_DISCOUNT,
68
- D as DEFAULT_OMNIBUS_PRICE,
69
- E as DEFAULT_VISIBILITY,
76
+ a as DEFAULT_OMNIBUS_DISCOUNT,
77
+ O as DEFAULT_OMNIBUS_PRICE,
78
+ c as DEFAULT_VISIBILITY,
70
79
  N as EXCLUDED_ALGORITHM_IDS
71
80
  };