@useinsider/guido 3.2.0-beta.4aabac5 → 3.2.0-beta.51b7991

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 (83) hide show
  1. package/README.md +1 -0
  2. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  3. package/dist/components/organisms/header/EditorActions.vue2.js +51 -36
  4. package/dist/components/organisms/header/RightSlot.vue.js +10 -10
  5. package/dist/components/organisms/header/RightSlot.vue2.js +16 -13
  6. package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
  7. package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
  8. package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
  9. package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
  10. package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
  11. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
  12. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
  13. package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
  14. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +18 -17
  15. package/dist/composables/useActionsApi.js +4 -4
  16. package/dist/composables/useFullStoryBridge.js +14 -0
  17. package/dist/composables/useHtmlCompiler.js +18 -16
  18. package/dist/composables/useRibbonOffset.js +21 -0
  19. package/dist/composables/useSave.js +26 -17
  20. package/dist/composables/useStripo.js +48 -45
  21. package/dist/composables/validators/useCouponBlockValidator.js +24 -0
  22. package/dist/composables/validators/useLiquidValidator.js +42 -0
  23. package/dist/config/compiler/liquidCompilerRules.js +15 -0
  24. package/dist/config/compiler/recommendationCompilerRules.js +77 -72
  25. package/dist/config/compiler/unsubscribeCompilerRules.js +40 -37
  26. package/dist/config/compiler/utils/recommendationCompilerUtils.js +33 -30
  27. package/dist/config/migrator/radioButtonMigrator.js +64 -44
  28. package/dist/config/migrator/recommendationMigrator.js +1 -1
  29. package/dist/enums/onboarding.js +7 -2
  30. package/dist/enums/unsubscribe.js +34 -27
  31. package/dist/extensions/Blocks/CouponBlock/template.js +24 -13
  32. package/dist/extensions/Blocks/Items/controls/price/singlePrice.js +38 -38
  33. package/dist/extensions/Blocks/Items/enums/productEnums.js +19 -7
  34. package/dist/extensions/Blocks/RadioButton/template.js +1 -1
  35. package/dist/extensions/Blocks/Recommendation/block.js +35 -28
  36. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  37. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +21 -18
  38. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +99 -0
  39. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +6 -6
  40. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +3 -1
  41. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +27 -57
  42. package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +14 -0
  43. package/dist/extensions/Blocks/Recommendation/services/configService.js +11 -4
  44. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +18 -17
  45. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +29 -25
  46. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +11 -11
  47. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +17 -14
  48. package/dist/extensions/Blocks/Unsubscribe/block.js +11 -11
  49. package/dist/extensions/DynamicContent/dynamic-content.js +17 -12
  50. package/dist/guido.css +1 -1
  51. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +393 -264
  52. package/dist/package.json.js +1 -1
  53. package/dist/services/stripoApi.js +9 -9
  54. package/dist/services/templateLibraryApi.js +49 -46
  55. package/dist/src/@types/save-as-template.d.ts +1 -0
  56. package/dist/src/composables/useActionsApi.d.ts +1 -1
  57. package/dist/src/composables/useFullStoryBridge.d.ts +11 -0
  58. package/dist/src/composables/useRibbonOffset.d.ts +4 -0
  59. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  60. package/dist/src/composables/validators/useLiquidValidator.d.ts +3 -0
  61. package/dist/src/config/compiler/liquidCompilerRules.d.ts +2 -0
  62. package/dist/src/enums/onboarding.d.ts +6 -0
  63. package/dist/src/enums/unsubscribe.d.ts +5 -0
  64. package/dist/src/extensions/Blocks/CouponBlock/template.d.ts +2 -0
  65. package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
  66. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  67. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +3 -0
  68. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +35 -0
  69. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +3 -20
  70. package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +29 -0
  71. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +11 -3
  72. package/dist/src/services/templateLibraryApi.d.ts +1 -1
  73. package/dist/src/stores/onboarding.d.ts +4 -0
  74. package/dist/src/utils/genericUtil.d.ts +1 -1
  75. package/dist/static/styles/components/button.css.js +16 -9
  76. package/dist/static/styles/components/loader.css.js +4 -0
  77. package/dist/static/styles/components/narrow-panel.css.js +52 -0
  78. package/dist/stores/onboarding.js +4 -0
  79. package/dist/utils/genericUtil.js +42 -20
  80. package/dist/utils/pairProductVariables.js +89 -88
  81. package/package.json +3 -3
  82. package/dist/enums/displayConditions.js +0 -80
  83. package/dist/src/enums/displayConditions.d.ts +0 -2
@@ -8,8 +8,8 @@ import { regenerateMobileProductRows as C } from "./controls/main/utils.js";
8
8
  import { ensureMobileCssRulesExist as g, setMobileLayoutOptOut as d, hasMobileLayoutOptOut as A } from "./controls/mobileLayout/cssRules.js";
9
9
  import { RecommendationConfigService as c } from "./services/configService.js";
10
10
  import { useRecommendationExtensionStore as p } from "./store/recommendation.js";
11
- import { getDefaultTemplate as E } from "./templates/grid/template.js";
12
- const f = B.Recommendation, a = "recommendation-block-v2", l = "recommendation-id";
11
+ import { getDefaultTemplate as D } from "./templates/grid/template.js";
12
+ const f = B.Recommendation, l = "recommendation-block-v2", m = "recommendation-id";
13
13
  let h = !1;
14
14
  class q extends b {
15
15
  constructor() {
@@ -56,7 +56,7 @@ class q extends b {
56
56
  */
57
57
  getTemplate() {
58
58
  const t = this._generateNextId();
59
- return this._pendingBlockId = t, E(t);
59
+ return this._pendingBlockId = t, D(t);
60
60
  }
61
61
  /**
62
62
  * Called when a new block is dropped into the template
@@ -68,13 +68,20 @@ class q extends b {
68
68
  onCreated(t) {
69
69
  const e = this._pendingBlockId ?? this._generateNextId();
70
70
  this._pendingBlockId = null, this._assignRecommendationId(t, e);
71
- const o = c.initializeConfig(this.api, t, { recommendationId: e }), i = p();
72
- i.setCurrentBlock(e), g(this.api);
73
- const s = this._getBlockElement(t);
74
- s && (d(this.api, s, !0), C({
75
- currentNode: t,
76
- documentModifier: this.api.getDocumentModifier()
77
- })), i.patchCurrentBlockConfig({ language: o.language }, { triggerRefetch: !1 });
71
+ const { config: i, wasFreshDrop: o } = c.initializeConfig(
72
+ this.api,
73
+ t,
74
+ { recommendationId: e }
75
+ ), s = p();
76
+ if (s.setCurrentBlock(e), o) {
77
+ g(this.api);
78
+ const a = this._getBlockElement(t);
79
+ a && (d(this.api, a, !0), C({
80
+ currentNode: t,
81
+ documentModifier: this.api.getDocumentModifier()
82
+ }));
83
+ }
84
+ s.patchCurrentBlockConfig({ language: i.language }, { triggerRefetch: !1 });
78
85
  }
79
86
  /**
80
87
  * Called when the document changes or template is loaded
@@ -97,10 +104,10 @@ class q extends b {
97
104
  c.needsMigration(t) && this._migrateFromLegacy(t);
98
105
  try {
99
106
  h || (g(this.api), h = !0);
100
- const e = c.getConfig(t), o = this._getBlockElement(t);
101
- if (o) {
102
- const i = !e.mobileLayoutEnabled;
103
- A(o) !== i && d(this.api, o, i);
107
+ const e = c.getConfig(t), i = this._getBlockElement(t);
108
+ if (i) {
109
+ const o = !e.mobileLayoutEnabled;
110
+ A(i) !== o && d(this.api, i, o);
104
111
  }
105
112
  } catch {
106
113
  }
@@ -124,10 +131,10 @@ class q extends b {
124
131
  let t = 0;
125
132
  try {
126
133
  const e = this.api.getDocumentRoot();
127
- e && "querySelectorAll" in e && e.querySelectorAll(`.${a}`).forEach((i) => {
128
- if ("getAttribute" in i) {
129
- const s = i.getAttribute(l), m = s ? parseInt(s) : 0;
130
- m > t && (t = m);
134
+ e && "querySelectorAll" in e && e.querySelectorAll(`.${l}`).forEach((o) => {
135
+ if ("getAttribute" in o) {
136
+ const s = o.getAttribute(m), a = s ? parseInt(s) : 0;
137
+ a > t && (t = a);
131
138
  }
132
139
  });
133
140
  } catch {
@@ -141,11 +148,11 @@ class q extends b {
141
148
  * added classes via setAttribute.
142
149
  */
143
150
  _assignRecommendationId(t, e) {
144
- const o = this._getBlockElement(t);
145
- if (!o)
151
+ const i = this._getBlockElement(t);
152
+ if (!i)
146
153
  return;
147
- const i = this.api.getDocumentModifier();
148
- i.modifyHtml(o).setAttribute(l, e.toString()), i.apply(new y(`Assign recommendation ID ${e}`));
154
+ const o = this.api.getDocumentModifier();
155
+ o.modifyHtml(i).setAttribute(m, e.toString()), o.apply(new y(`Assign recommendation ID ${e}`));
149
156
  }
150
157
  /**
151
158
  * Gets the recommendation-id from a block node
@@ -154,11 +161,11 @@ class q extends b {
154
161
  const e = this._getBlockElement(t);
155
162
  if (!e || !("getAttribute" in e))
156
163
  return null;
157
- const o = e.getAttribute(l);
158
- if (!o)
164
+ const i = e.getAttribute(m);
165
+ if (!i)
159
166
  return null;
160
- const i = parseInt(o);
161
- return Number.isNaN(i) ? null : i;
167
+ const o = parseInt(i);
168
+ return Number.isNaN(o) ? null : o;
162
169
  }
163
170
  /**
164
171
  * Gets the block element (the element with BLOCK_CLASS)
@@ -166,10 +173,10 @@ class q extends b {
166
173
  _getBlockElement(t) {
167
174
  if ("getAttribute" in t) {
168
175
  const e = t.getAttribute("class");
169
- if (e && e.includes(a))
176
+ if (e && e.includes(l))
170
177
  return t;
171
178
  }
172
- return "querySelector" in t ? t.querySelector(`.${a}`) ?? null : null;
179
+ return "querySelector" in t ? t.querySelector(`.${l}`) ?? null : null;
173
180
  }
174
181
  /**
175
182
  * Migrate configuration from legacy format
@@ -1,4 +1,4 @@
1
- var o = /* @__PURE__ */ ((c) => (c.BUTTON_ALIGN = "recommendation-block-button-align-control", c.BUTTON_BORDER = "recommendation-block-button-border-control", c.BUTTON_BORDER_RADIUS = "recommendation-block-button-border-radius-control", c.BUTTON_COLOR = "recommendation-block-button-color-control", c.BUTTON_FIT_TO_CONTENT = "recommendation-block-button-fit-to-content-control", c.BUTTON_FONT_FAMILY = "recommendation-block-button-font-family-control", c.BUTTON_MARGINS = "recommendation-block-button-margins-control", c.BUTTON_PADDINGS = "recommendation-block-button-paddings-control", c.BUTTON_TEXT = "recommendation-block-button-text-control", c.BUTTON_TEXT_SIZE = "recommendation-block-button-text-size-control", c.BUTTON_TEXT_STYLE_AND_FONT_COLOR = "recommendation-block-button-text-style-and-font-color-control", c.NAME_ALIGN = "recommendation-block-name-align-control", c.NAME_BACKGROUND = "recommendation-block-name-background-control", c.NAME_COLOR = "recommendation-block-name-color-control", c.NAME_FONT_FAMILY = "recommendation-block-name-font-family-control", c.NAME_PADDINGS = "recommendation-block-name-paddings-control", c.NAME_SIZE = "recommendation-block-name-size-control", c.NAME_STYLE = "recommendation-block-name-style-control", c.NAME_TEXT_TRIM = "recommendation-block-name-text-trim-control", c.PRICE_ALIGN = "recommendation-block-price-align-control", c.PRICE_BACKGROUND = "recommendation-block-price-background-control", c.PRICE_COLOR = "recommendation-block-price-color-control", c.PRICE_FONT_FAMILY = "recommendation-block-price-font-family-control", c.PRICE_PADDINGS = "recommendation-block-price-paddings-control", c.PRICE_SIZE = "recommendation-block-price-size-control", c.PRICE_STYLE = "recommendation-block-price-style-control", c.OLD_PRICE_ALIGN = "recommendation-block-old-price-align-control", c.OLD_PRICE_BACKGROUND = "recommendation-block-old-price-background-control", c.OLD_PRICE_COLOR = "recommendation-block-old-price-color-control", c.OLD_PRICE_FONT_FAMILY = "recommendation-block-old-price-font-family-control", c.OLD_PRICE_PADDINGS = "recommendation-block-old-price-paddings-control", c.OLD_PRICE_SIZE = "recommendation-block-old-price-size-control", c.OLD_PRICE_STYLE = "recommendation-block-old-price-style-control", c.OMNIBUS_PRICE_ALIGN = "recommendation-block-omnibus-price-align-control", c.OMNIBUS_PRICE_BACKGROUND = "recommendation-block-omnibus-price-background-control", c.OMNIBUS_PRICE_COLOR = "recommendation-block-omnibus-price-color-control", c.OMNIBUS_PRICE_FONT_FAMILY = "recommendation-block-omnibus-price-font-family-control", c.OMNIBUS_PRICE_PADDINGS = "recommendation-block-omnibus-price-paddings-control", c.OMNIBUS_PRICE_SIZE = "recommendation-block-omnibus-price-size-control", c.OMNIBUS_PRICE_STYLE = "recommendation-block-omnibus-price-style-control", c.OMNIBUS_PRICE_TEXT_BEFORE = "recommendation-block-omnibus-price-text-before-control", c.OMNIBUS_PRICE_TEXT_AFTER = "recommendation-block-omnibus-price-text-after-control", c.OMNIBUS_DISCOUNT_ALIGN = "recommendation-block-omnibus-discount-align-control", c.OMNIBUS_DISCOUNT_BACKGROUND = "recommendation-block-omnibus-discount-background-control", c.OMNIBUS_DISCOUNT_COLOR = "recommendation-block-omnibus-discount-color-control", c.OMNIBUS_DISCOUNT_FONT_FAMILY = "recommendation-block-omnibus-discount-font-family-control", c.OMNIBUS_DISCOUNT_PADDINGS = "recommendation-block-omnibus-discount-paddings-control", c.OMNIBUS_DISCOUNT_SIZE = "recommendation-block-omnibus-discount-size-control", c.OMNIBUS_DISCOUNT_STYLE = "recommendation-block-omnibus-discount-style-control", c.OMNIBUS_DISCOUNT_TEXT_BEFORE = "recommendation-block-omnibus-discount-text-before-control", c.OMNIBUS_DISCOUNT_TEXT_AFTER = "recommendation-block-omnibus-discount-text-after-control", c.IMAGE_SIZE = "recommendation-block-image-size-control", c.IMAGE_MARGINS = "recommendation-block-image-margins-control", c.CUSTOM_ATTR_ALIGN = "recommendation-block-custom-attr-align-control", c.CUSTOM_ATTR_BACKGROUND = "recommendation-block-custom-attr-background-control", c.CUSTOM_ATTR_COLOR = "recommendation-block-custom-attr-color-control", c.CUSTOM_ATTR_FONT_FAMILY = "recommendation-block-custom-attr-font-family-control", c.CUSTOM_ATTR_PADDINGS = "recommendation-block-custom-attr-paddings-control", c.CUSTOM_ATTR_SIZE = "recommendation-block-custom-attr-size-control", c.CUSTOM_ATTR_STYLE = "recommendation-block-custom-attr-style-control", c.SYNC_INFO_MESSAGE = "recommendation-block-sync-info-message", c))(o || {});
1
+ var o = /* @__PURE__ */ ((c) => (c.BUTTON_ALIGN = "recommendation-block-button-align-control", c.BUTTON_BORDER = "recommendation-block-button-border-control", c.BUTTON_BORDER_RADIUS = "recommendation-block-button-border-radius-control", c.BUTTON_COLOR = "recommendation-block-button-color-control", c.BUTTON_FIT_TO_CONTENT = "recommendation-block-button-fit-to-content-control", c.BUTTON_FONT_FAMILY = "recommendation-block-button-font-family-control", c.BUTTON_MARGINS = "recommendation-block-button-margins-control", c.BUTTON_PADDINGS = "recommendation-block-button-paddings-control", c.BUTTON_TEXT = "recommendation-block-button-text-control", c.BUTTON_TEXT_SIZE = "recommendation-block-button-text-size-control", c.BUTTON_TEXT_STYLE_AND_FONT_COLOR = "recommendation-block-button-text-style-and-font-color-control", c.NAME_ALIGN = "recommendation-block-name-align-control", c.NAME_BACKGROUND = "recommendation-block-name-background-control", c.NAME_COLOR = "recommendation-block-name-color-control", c.NAME_FONT_FAMILY = "recommendation-block-name-font-family-control", c.NAME_PADDINGS = "recommendation-block-name-paddings-control", c.NAME_SIZE = "recommendation-block-name-size-control", c.NAME_STYLE = "recommendation-block-name-style-control", c.NAME_TEXT_TRIM = "recommendation-block-name-text-trim-control", c.PRICE_ALIGN = "recommendation-block-price-align-control", c.PRICE_BACKGROUND = "recommendation-block-price-background-control", c.PRICE_COLOR = "recommendation-block-price-color-control", c.PRICE_FONT_FAMILY = "recommendation-block-price-font-family-control", c.PRICE_PADDINGS = "recommendation-block-price-paddings-control", c.PRICE_SIZE = "recommendation-block-price-size-control", c.PRICE_STYLE = "recommendation-block-price-style-control", c.OLD_PRICE_ALIGN = "recommendation-block-old-price-align-control", c.OLD_PRICE_BACKGROUND = "recommendation-block-old-price-background-control", c.OLD_PRICE_COLOR = "recommendation-block-old-price-color-control", c.OLD_PRICE_FONT_FAMILY = "recommendation-block-old-price-font-family-control", c.OLD_PRICE_PADDINGS = "recommendation-block-old-price-paddings-control", c.OLD_PRICE_SIZE = "recommendation-block-old-price-size-control", c.OLD_PRICE_STYLE = "recommendation-block-old-price-style-control", c.OMNIBUS_PRICE_ALIGN = "recommendation-block-omnibus-price-align-control", c.OMNIBUS_PRICE_BACKGROUND = "recommendation-block-omnibus-price-background-control", c.OMNIBUS_PRICE_COLOR = "recommendation-block-omnibus-price-color-control", c.OMNIBUS_PRICE_FONT_FAMILY = "recommendation-block-omnibus-price-font-family-control", c.OMNIBUS_PRICE_PADDINGS = "recommendation-block-omnibus-price-paddings-control", c.OMNIBUS_PRICE_SIZE = "recommendation-block-omnibus-price-size-control", c.OMNIBUS_PRICE_STYLE = "recommendation-block-omnibus-price-style-control", c.OMNIBUS_PRICE_TEXT_BEFORE = "recommendation-block-omnibus-price-text-before-control", c.OMNIBUS_PRICE_TEXT_AFTER = "recommendation-block-omnibus-price-text-after-control", c.OMNIBUS_DISCOUNT_ALIGN = "recommendation-block-omnibus-discount-align-control", c.OMNIBUS_DISCOUNT_BACKGROUND = "recommendation-block-omnibus-discount-background-control", c.OMNIBUS_DISCOUNT_COLOR = "recommendation-block-omnibus-discount-color-control", c.OMNIBUS_DISCOUNT_FONT_FAMILY = "recommendation-block-omnibus-discount-font-family-control", c.OMNIBUS_DISCOUNT_PADDINGS = "recommendation-block-omnibus-discount-paddings-control", c.OMNIBUS_DISCOUNT_SIZE = "recommendation-block-omnibus-discount-size-control", c.OMNIBUS_DISCOUNT_STYLE = "recommendation-block-omnibus-discount-style-control", c.OMNIBUS_DISCOUNT_TEXT_BEFORE = "recommendation-block-omnibus-discount-text-before-control", c.OMNIBUS_DISCOUNT_TEXT_AFTER = "recommendation-block-omnibus-discount-text-after-control", c.IMAGE_SIZE = "recommendation-block-image-size-control", c.IMAGE_MARGINS = "recommendation-block-image-margins-control", c.CUSTOM_ATTR_ALIGN = "recommendation-block-custom-attr-align-control", c.CUSTOM_ATTR_BACKGROUND = "recommendation-block-custom-attr-background-control", c.CUSTOM_ATTR_COLOR = "recommendation-block-custom-attr-color-control", c.CUSTOM_ATTR_FONT_FAMILY = "recommendation-block-custom-attr-font-family-control", c.CUSTOM_ATTR_PADDINGS = "recommendation-block-custom-attr-paddings-control", c.CUSTOM_ATTR_SIZE = "recommendation-block-custom-attr-size-control", c.CUSTOM_ATTR_STYLE = "recommendation-block-custom-attr-style-control", c.CUSTOM_ATTR_TEXT_TRIM = "recommendation-block-custom-attr-text-trim-control", c.SYNC_INFO_MESSAGE = "recommendation-block-sync-info-message", c))(o || {});
2
2
  export {
3
3
  o as RecommendationControlId
4
4
  };
@@ -1,21 +1,22 @@
1
- import { TextPaddingsBuiltInControl as d, ButtonBackgroundColorBuiltInControl as c, TextFontFamilyBuiltInControl as u, TextStyleBuiltInControl as i, TextSizeBuiltInControl as C, TextColorBuiltInControl as g, TextAlignBuiltInControl as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
1
+ import { TextPaddingsBuiltInControl as d, ButtonBackgroundColorBuiltInControl as i, TextFontFamilyBuiltInControl as u, TextStyleBuiltInControl as c, TextSizeBuiltInControl as C, TextColorBuiltInControl as g, TextAlignBuiltInControl as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { RecommendationBlockId as l } from "../../constants/blockIds.js";
3
3
  import { RecommendationControlId as e } from "../../constants/controlIds.js";
4
- import { BLOCK_ROOT_SELECTOR as I, ATTR_PRODUCT_ATTR as s } from "../../constants/selectors.js";
4
+ import { BLOCK_ROOT_SELECTOR as A, ATTR_PRODUCT_ATTR as s } from "../../constants/selectors.js";
5
+ import { CustomAttributeTextTrimControl as I } from "./textTrim.js";
5
6
  function o(t) {
6
- const n = t.closest(I);
7
- if (!n)
7
+ const r = t.closest(A);
8
+ if (!r)
8
9
  return [];
9
- const r = t.asElement().getAttribute(s);
10
- if (r) {
11
- const T = `[esd-extension-block-id="${l.CUSTOM_ATTRIBUTE}"][${s}="${r}"]`;
12
- return n.querySelectorAll(T);
10
+ const n = t.asElement().getAttribute(s);
11
+ if (n) {
12
+ const T = `[esd-extension-block-id="${l.CUSTOM_ATTRIBUTE}"][${s}="${n}"]`;
13
+ return r.querySelectorAll(T);
13
14
  }
14
- return n.querySelectorAll(
15
+ return r.querySelectorAll(
15
16
  `[esd-extension-block-id="${l.CUSTOM_ATTRIBUTE}"]`
16
17
  );
17
18
  }
18
- const A = class extends a {
19
+ const m = class extends a {
19
20
  getId() {
20
21
  return e.CUSTOM_ATTR_ALIGN;
21
22
  }
@@ -36,7 +37,7 @@ const A = class extends a {
36
37
  getTargetNodes(t) {
37
38
  return o(t);
38
39
  }
39
- }, m = class extends i {
40
+ }, x = class extends c {
40
41
  getId() {
41
42
  return e.CUSTOM_ATTR_STYLE;
42
43
  }
@@ -50,29 +51,31 @@ const A = class extends a {
50
51
  getTargetNodes(t) {
51
52
  return o(t);
52
53
  }
53
- }, R = class extends c {
54
+ }, R = class extends i {
54
55
  getId() {
55
56
  return e.CUSTOM_ATTR_BACKGROUND;
56
57
  }
57
58
  getTargetNodes(t) {
58
59
  return o(t);
59
60
  }
60
- }, x = class extends d {
61
+ }, B = class extends d {
61
62
  getId() {
62
63
  return e.CUSTOM_ATTR_PADDINGS;
63
64
  }
64
65
  getTargetNodes(t) {
65
66
  return o(t);
66
67
  }
67
- }, k = {
68
- align: A,
68
+ }, p = {
69
+ align: m,
69
70
  color: _,
70
71
  size: S,
71
- style: m,
72
+ style: x,
72
73
  fontFamily: O,
73
74
  background: R,
74
- paddings: x
75
+ paddings: B,
76
+ textTrim: I
75
77
  };
76
78
  export {
77
- k as CustomAttributeControls
79
+ p as CustomAttributeControls,
80
+ I as CustomAttributeTextTrimControl
78
81
  };
@@ -0,0 +1,99 @@
1
+ import { ModificationDescription as T } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { CommonControl as m } from "../../../common-control.js";
3
+ import { RecommendationBlockId as n } from "../../constants/blockIds.js";
4
+ import { RecommendationControlId as l } from "../../constants/controlIds.js";
5
+ import { BLOCK_ROOT_SELECTOR as u, ATTR_PRODUCT_ATTR as a } from "../../constants/selectors.js";
6
+ import { CSS_CLASS_TEXT_TRIM as o, ensureTextTrimCssRulesExist as c } from "../shared/textTrimCssRules.js";
7
+ const i = {
8
+ TEXT_TRIM_ENABLED: "customAttrTextTrimEnabled"
9
+ };
10
+ class g extends m {
11
+ getId() {
12
+ return l.CUSTOM_ATTR_TEXT_TRIM;
13
+ }
14
+ getTemplate() {
15
+ return `
16
+ <hr style="margin: 0; border: none; border-top: 1px solid #e0e0e0;" />
17
+ <div class="custom-attr-text-trim-control-container">
18
+ ${this._GuTwoColumns([
19
+ this._GuLabel({ text: this.api.translate("Trim Long Text") }),
20
+ this._GuToggle(i.TEXT_TRIM_ENABLED)
21
+ ])}
22
+ </div>
23
+ `;
24
+ }
25
+ onRender() {
26
+ this._setFormValues(), this._listenToFormUpdates();
27
+ }
28
+ onTemplateNodeUpdated(t) {
29
+ super.onTemplateNodeUpdated(t), this._setFormValues();
30
+ }
31
+ // ========================================================================
32
+ // State Reading
33
+ // ========================================================================
34
+ _setFormValues() {
35
+ this.api.updateValues({
36
+ [i.TEXT_TRIM_ENABLED]: this._getCurrentTrimState()
37
+ });
38
+ }
39
+ _getCurrentTrimState() {
40
+ if (!this.currentNode || !("hasClass" in this.currentNode))
41
+ return !1;
42
+ if (this.currentNode.hasClass(o))
43
+ return !0;
44
+ const t = this._getTargetElements();
45
+ return t.length > 0 && "hasClass" in t[0] ? t[0].hasClass(o) : !1;
46
+ }
47
+ // ========================================================================
48
+ // Target Element Discovery (per-attribute scoping)
49
+ // ========================================================================
50
+ /**
51
+ * Finds all custom attribute elements of the same type as the current node.
52
+ *
53
+ * Similar to getCustomAttrTargetNodes in customAttribute/index.ts, but adapted
54
+ * for CommonControl lifecycle where currentNode is a class property (not a
55
+ * parameter from Stripo's getTargetNodes override).
56
+ */
57
+ _getTargetElements() {
58
+ if (!this.currentNode || !("closest" in this.currentNode))
59
+ return [];
60
+ const t = this.currentNode.closest(u);
61
+ if (!t)
62
+ return [];
63
+ const e = "asElement" in this.currentNode ? this.currentNode.asElement().getAttribute(a) : null;
64
+ if (e) {
65
+ const s = `[esd-extension-block-id="${n.CUSTOM_ATTRIBUTE}"][${a}="${e}"]`;
66
+ return Array.from(t.querySelectorAll(s));
67
+ }
68
+ return Array.from(
69
+ t.querySelectorAll(
70
+ `[esd-extension-block-id="${n.CUSTOM_ATTRIBUTE}"]`
71
+ )
72
+ );
73
+ }
74
+ // ========================================================================
75
+ // Toggle Handler
76
+ // ========================================================================
77
+ _onTextTrimChange(t) {
78
+ const e = this._getTargetElements();
79
+ if (!e.length)
80
+ return;
81
+ t && c(this.api);
82
+ const r = this.api.getDocumentModifier();
83
+ e.forEach((s) => {
84
+ t ? r.modifyHtml(s).setClass(o) : r.modifyHtml(s).removeClass(o);
85
+ }), r.apply(
86
+ new T(
87
+ t ? "Enable custom attribute text trimming" : "Disable custom attribute text trimming"
88
+ )
89
+ );
90
+ }
91
+ _listenToFormUpdates() {
92
+ this.api.onValueChanged(i.TEXT_TRIM_ENABLED, (t) => {
93
+ this._onTextTrimChange(t);
94
+ });
95
+ }
96
+ }
97
+ export {
98
+ g as CustomAttributeTextTrimControl
99
+ };
@@ -1,7 +1,7 @@
1
- var c = Object.defineProperty;
2
- var h = (s, i, t) => i in s ? c(s, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[i] = t;
3
- var a = (s, i, t) => h(s, typeof i != "symbol" ? i + "" : i, t);
4
- import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
1
+ var l = Object.defineProperty;
2
+ var c = (s, i, t) => i in s ? l(s, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[i] = t;
3
+ var a = (s, i, t) => c(s, typeof i != "symbol" ? i + "" : i, t);
4
+ import { UEAttr as h } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
5
  import { CommonControl as d } from "../../../common-control.js";
6
6
  import { RecommendationConfigService as n } from "../../services/configService.js";
7
7
  import { useRecommendationExtensionStore as m } from "../../store/recommendation.js";
@@ -42,7 +42,7 @@ class T extends d {
42
42
  this._initializeSelectItems(), this._setFormValues(), this._listenToFormUpdates();
43
43
  }
44
44
  onTemplateNodeUpdated(t) {
45
- super.onTemplateNodeUpdated(t), this._setFormValues();
45
+ super.onTemplateNodeUpdated(t), this._initializeSelectItems(), this._setFormValues();
46
46
  }
47
47
  _setFormValues() {
48
48
  const t = n.getConfig(this.currentNode);
@@ -58,7 +58,7 @@ class T extends d {
58
58
  try {
59
59
  this.api.setUIEAttribute(
60
60
  e.ALGORITHM,
61
- l.SELECTPICKER.items,
61
+ h.SELECTPICKER.items,
62
62
  t
63
63
  );
64
64
  } catch (r) {
@@ -114,7 +114,9 @@ class H extends g {
114
114
  var r;
115
115
  super.onTemplateNodeUpdated(t);
116
116
  const e = this._getRecommendationIdFromNode(t);
117
- e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((r = this.store.blockStates[e]) != null && r.isInitialized) && this._fetchBlockData(e), [
117
+ e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && this._syncNodeConfigToStore(), e !== null && !((r = this.store.blockStates[e]) != null && r.isInitialized) && this._fetchBlockData(e).then(() => {
118
+ this._initializeSubControls();
119
+ }), [
118
120
  this.layoutOrientationControl,
119
121
  this.productCountControl,
120
122
  this.algorithmControl,
@@ -1,14 +1,15 @@
1
- import { ModificationDescription as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { CommonControl as d } from "../../../common-control.js";
3
- import { RecommendationBlockId as l } from "../../constants/blockIds.js";
4
- import { RecommendationControlId as m } from "../../constants/controlIds.js";
5
- import { BLOCK_ROOT_SELECTOR as u } from "../../constants/selectors.js";
6
- const i = {
1
+ import { ModificationDescription as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { CommonControl as u } from "../../../common-control.js";
3
+ import { RecommendationBlockId as a } from "../../constants/blockIds.js";
4
+ import { RecommendationControlId as d } from "../../constants/controlIds.js";
5
+ import { BLOCK_ROOT_SELECTOR as m } from "../../constants/selectors.js";
6
+ import { CSS_CLASS_TEXT_TRIM as r, ensureTextTrimCssRulesExist as T } from "../shared/textTrimCssRules.js";
7
+ const s = {
7
8
  TEXT_TRIM_ENABLED: "textTrimEnabled"
8
- }, o = "text-trim-enabled", c = `.${o}`, T = `.${o} p`, p = `.${o} { max-width: 0; }`, _ = `.${o} p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0; display: block; }`;
9
- class N extends d {
9
+ };
10
+ class N extends u {
10
11
  getId() {
11
- return m.NAME_TEXT_TRIM;
12
+ return d.NAME_TEXT_TRIM;
12
13
  }
13
14
  getTemplate() {
14
15
  return `
@@ -16,7 +17,7 @@ class N extends d {
16
17
  <div class="name-text-trim-control-container">
17
18
  ${this._GuTwoColumns([
18
19
  this._GuLabel({ text: this.api.translate("Trim Long Text") }),
19
- this._GuToggle(i.TEXT_TRIM_ENABLED)
20
+ this._GuToggle(s.TEXT_TRIM_ENABLED)
20
21
  ])}
21
22
  </div>
22
23
  `;
@@ -30,76 +31,45 @@ class N extends d {
30
31
  _setFormValues() {
31
32
  const e = this._getCurrentTrimState();
32
33
  this.api.updateValues({
33
- [i.TEXT_TRIM_ENABLED]: e
34
+ [s.TEXT_TRIM_ENABLED]: e
34
35
  });
35
36
  }
36
37
  _getCurrentTrimState() {
37
38
  if (!this.currentNode || !("hasClass" in this.currentNode))
38
39
  return !1;
39
- if (this.currentNode.hasClass(o))
40
+ if (this.currentNode.hasClass(r))
40
41
  return !0;
41
- const e = this.currentNode.closest(u);
42
+ const e = this.currentNode.closest(m);
42
43
  if (!e)
43
44
  return !1;
44
45
  const t = e.querySelector(
45
- `[esd-extension-block-id="${l.NAME}"]`
46
+ `[esd-extension-block-id="${a.NAME}"]`
46
47
  );
47
- return t && "hasClass" in t ? t.hasClass(o) : !1;
48
- }
49
- /**
50
- * Finds an existing CSS rule in the document stylesheet by exact query
51
- * @param query - The CSS query to search for (uses Stripo's CSS query syntax)
52
- * @returns The CSS rule node if found, undefined otherwise
53
- */
54
- _findCssRule(e) {
55
- const t = this.api.getDocumentRootCssNode();
56
- if (t)
57
- return t.querySelector(e);
58
- }
59
- /**
60
- * Finds the .text-trim-enabled p rule by searching all text-trim rules and comparing selectors
61
- * This is needed because Stripo's CSS query syntax interprets spaces as path separators
62
- * @returns true if the rule exists
63
- */
64
- _hasParagraphRule() {
65
- const e = this.api.getDocumentRootCssNode();
66
- return e ? e.querySelectorAll(`*${o}`).some((s) => "getSelector" in s && typeof s.getSelector == "function" ? s.getSelector() === T : !1) : !1;
67
- }
68
- /**
69
- * Ensures the text-trim CSS rules exist in the document stylesheet
70
- * Only adds rules if they don't already exist (prevents duplicates across multiple blocks)
71
- */
72
- _ensureCssRulesExist() {
73
- const e = this.api.getDocumentRootCssNode();
74
- if (!e)
75
- return;
76
- const t = this.api.getDocumentModifier();
77
- let s = !1;
78
- this._findCssRule(c) || (t.modifyCss(e).appendRule(p), s = !0), this._hasParagraphRule() || (t.modifyCss(e).appendRule(_), s = !0), s && t.apply(new a("Add text trim CSS rules"));
48
+ return t && "hasClass" in t ? t.hasClass(r) : !1;
79
49
  }
80
50
  _onTextTrimChange(e) {
81
51
  if (!this.currentNode || !("closest" in this.currentNode))
82
52
  return;
83
- const t = this.currentNode.closest(u);
53
+ const t = this.currentNode.closest(m);
84
54
  if (!t || !("querySelectorAll" in t))
85
55
  return;
86
- const s = Array.from(
87
- t.querySelectorAll(`[esd-extension-block-id="${l.NAME}"]`)
56
+ const i = Array.from(
57
+ t.querySelectorAll(`[esd-extension-block-id="${a.NAME}"]`)
88
58
  );
89
- if (!s.length)
59
+ if (!i.length)
90
60
  return;
91
- e && this._ensureCssRulesExist();
92
- const r = this.api.getDocumentModifier();
93
- s.forEach((n) => {
94
- e ? r.modifyHtml(n).setClass(o) : r.modifyHtml(n).removeClass(o);
95
- }), r.apply(
96
- new a(
61
+ e && T(this.api);
62
+ const o = this.api.getDocumentModifier();
63
+ i.forEach((n) => {
64
+ e ? o.modifyHtml(n).setClass(r) : o.modifyHtml(n).removeClass(r);
65
+ }), o.apply(
66
+ new l(
97
67
  e ? "Enable product name text trimming" : "Disable product name text trimming"
98
68
  )
99
69
  );
100
70
  }
101
71
  _listenToFormUpdates() {
102
- this.api.onValueChanged(i.TEXT_TRIM_ENABLED, (e) => {
72
+ this.api.onValueChanged(s.TEXT_TRIM_ENABLED, (e) => {
103
73
  this._onTextTrimChange(e);
104
74
  });
105
75
  }
@@ -0,0 +1,14 @@
1
+ import { ModificationDescription as r } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ const t = "text-trim-enabled", l = `.${t}`, c = `.${t} p`, S = `.${t} { max-width: 0; }`, T = `.${t} p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0; display: block; }`;
3
+ function f(n) {
4
+ const e = n.getDocumentRootCssNode();
5
+ if (!e)
6
+ return;
7
+ const o = n.getDocumentModifier();
8
+ let i = !1;
9
+ e.querySelector(l) || (o.modifyCss(e).appendRule(S), i = !0), e.querySelectorAll(`*${t}`).some((s) => "getSelector" in s && typeof s.getSelector == "function" && s.getSelector() === c) || (o.modifyCss(e).appendRule(T), i = !0), i && o.apply(new r("Add text trim CSS rules"));
10
+ }
11
+ export {
12
+ t as CSS_CLASS_TEXT_TRIM,
13
+ f as ensureTextTrimCssRulesExist
14
+ };
@@ -85,21 +85,28 @@ class C {
85
85
  *
86
86
  * Called when a block is first created (dropped into template).
87
87
  * Can optionally merge in partial config from migration.
88
+ *
89
+ * The `wasFreshDrop` flag distinguishes a brand-new drop (no prior config)
90
+ * from a clone (Stripo replays the source's setNodeConfig payload before
91
+ * onCreated fires). Callers use this to skip side-effects already inherited
92
+ * from the source.
88
93
  * @example
89
94
  * // In Block.onCreated lifecycle
90
- * RecommendationConfigService.initializeConfig(this.api, node);
95
+ * const { config, wasFreshDrop } = RecommendationConfigService.initializeConfig(this.api, node);
91
96
  * @param api - Stripo extension API with document modifier
92
97
  * @param node - The immutable HTML node to initialize
93
98
  * @param partialConfig - Optional partial config to merge with defaults
94
- * @returns The initialized configuration
99
+ * @returns The initialized configuration and whether the node was a fresh drop
95
100
  */
96
101
  static initializeConfig(i, t, o) {
102
+ if (this.hasConfig(t))
103
+ return { config: o ? this.updateConfig(i, t, o, "Initialize recommendation block") : this.getConfig(t), wasFreshDrop: !1 };
97
104
  const n = o ? this.mergeWithDefaults(o) : this.cloneDefaults();
98
105
  return this.saveConfig(i, t, n, "Initialize recommendation block"), g({
99
106
  currentNode: t,
100
107
  documentModifier: i.getDocumentModifier(),
101
108
  currency: n.currency
102
- }), n;
109
+ }), { config: n, wasFreshDrop: !0 };
103
110
  }
104
111
  /**
105
112
  * Save complete configuration to a node
@@ -143,7 +150,7 @@ class C {
143
150
  const c = t.getAttribute("data-row-spacing");
144
151
  c && (o.rowSpacing = parseInt(c) || e.rowSpacing);
145
152
  }
146
- return this.initializeConfig(i, t, o);
153
+ return this.initializeConfig(i, t, o).config;
147
154
  }
148
155
  /**
149
156
  * Check if configuration needs migration