@useinsider/guido 3.7.0-beta.24a845f → 3.7.0-beta.30ff65e

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.
@@ -1,12 +1,12 @@
1
1
  import { BlockId as g } from "../../../enums/block.js";
2
- import { useOnboardingStore as u } from "../../../stores/onboarding.js";
3
- import { getMigrationBannerHtml as p } from "../../../utils/migrationBannerHtml.js";
4
- import { Block as f, BlockCompositionType as I, ModificationDescription as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { useOnboardingStore as p } from "../../../stores/onboarding.js";
3
+ import { getMigrationBannerHtml as f } from "../../../utils/migrationBannerHtml.js";
4
+ import { Block as u, BlockCompositionType as I, ModificationDescription as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
5
  import { SETTINGS_ENUMS as a, DefaultConfigValues as i } from "./enums/settingsEnums.js";
6
6
  import { getDefaultTemplate as C } from "./template.js";
7
7
  import { getItemsBlockContainer as y, getItemsBlockConfig as b, getDefaultItemsBlockConfig as h } from "./utils/nodeConfigUtils.js";
8
8
  const c = g.Items;
9
- class E extends f {
9
+ class E extends u {
10
10
  getId() {
11
11
  return c;
12
12
  }
@@ -23,7 +23,7 @@ class E extends f {
23
23
  return this.api.translate("Items lets you display personalized products based on user behavior.");
24
24
  }
25
25
  getSettingsPanelTitleHtml() {
26
- return p(
26
+ return f(
27
27
  c,
28
28
  this.api.translate("Items"),
29
29
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Items block and test your message to ensure it works properly.")
@@ -42,23 +42,18 @@ class E extends f {
42
42
  allowInnerBlocksDND() {
43
43
  return !1;
44
44
  }
45
- // Stripo's Block default is false. Items keeps its full config in nodeConfig
46
- // (esd-ext-config), so a saved module is self-contained and restores on re-drop.
47
- canBeSavedAsModule() {
48
- return !0;
49
- }
50
45
  onCreated(n) {
51
46
  const l = this.api.getDocumentModifier(), r = this.api.getDocumentRootCssNode();
52
47
  r.querySelector('[product-attr="imageSrc"] img') || l.modifyCss(r).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
53
- const t = y(n);
54
- if (!t)
48
+ const e = y(n);
49
+ if (!e)
55
50
  return;
56
- const s = t.getNodeConfig(), m = s && Object.keys(s).length > 0, e = b(n);
57
- if (e != null && e.initialized)
58
- m ? e.blockInstanceId || this.api.getDocumentModifier().modifyHtml(t).setNodeConfig({ ...e, blockInstanceId: String(Date.now()) }).apply(new o("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(t).setNodeConfig(e).apply(new o("Migrate legacy config to nodeConfig"));
51
+ const s = e.getNodeConfig(), m = s && Object.keys(s).length > 0, t = b(n);
52
+ if (t != null && t.initialized)
53
+ m ? t.blockInstanceId || this.api.getDocumentModifier().modifyHtml(e).setNodeConfig({ ...t, blockInstanceId: String(Date.now()) }).apply(new o("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(t).apply(new o("Migrate legacy config to nodeConfig"));
59
54
  else {
60
55
  const d = h();
61
- this.api.getDocumentModifier().modifyHtml(t).setNodeConfig(d).apply(new o("Initialize Items block with default configuration")), u().startOnboarding("itemsOnboarding");
56
+ this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(d).apply(new o("Initialize Items block with default configuration")), p().startOnboarding("itemsOnboarding");
62
57
  }
63
58
  }
64
59
  }
@@ -47,9 +47,9 @@ class q extends R {
47
47
  allowInnerBlocksDND() {
48
48
  return !1;
49
49
  }
50
- // Full config persists in nodeConfig (esd-ext-config) and is rebuilt at
51
- // compile time by hydrateRecommendationStoreFromRawHtml, so a saved module
52
- // restores its campaign/layout/styles when re-dropped into another email.
50
+ // A saved module carries its config in the esd-config blob, restored on
51
+ // re-drop by migrateFromDataAttributes; per-element styles ride the
52
+ // preserved inner HTML. (onCreated early-returns for re-drops, never clobbers.)
53
53
  canBeSavedAsModule() {
54
54
  return !0;
55
55
  }
@@ -1,29 +1,29 @@
1
- var J = Object.defineProperty;
2
- var Q = (p, _, t) => _ in p ? J(p, _, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[_] = t;
3
- var S = (p, _, t) => Q(p, typeof _ != "symbol" ? _ + "" : _, t);
4
- import { UIElementType as f, UEAttr as I, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as Z } from "../../../common-control.js";
6
- import { ATTR_PRODUCT_IMAGE as D, ATTR_PRODUCT_NAME as tt, ATTR_PRODUCT_PRICE as et, ATTR_PRODUCT_OLD_PRICE as rt, ATTR_PRODUCT_OMNIBUS_PRICE as ot, ATTR_PRODUCT_OMNIBUS_DISCOUNT as st, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as q, ATTR_CUSTOM_PREFIX as m, BUILT_IN_DEFAULT_ATTRIBUTES as it } from "../../constants/selectors.js";
7
- import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as F } from "../../constants/defaultConfig.js";
8
- import { RecommendationConfigService as nt } from "../../services/configService.js";
1
+ var Q = Object.defineProperty;
2
+ var Z = (p, g, t) => g in p ? Q(p, g, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[g] = t;
3
+ var S = (p, g, t) => Z(p, typeof g != "symbol" ? g + "" : g, t);
4
+ import { UIElementType as f, UEAttr as v, ModificationDescription as C } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as tt } from "../../../common-control.js";
6
+ import { ATTR_PRODUCT_IMAGE as H, ATTR_PRODUCT_NAME as et, ATTR_PRODUCT_PRICE as rt, ATTR_PRODUCT_OLD_PRICE as ot, ATTR_PRODUCT_OMNIBUS_PRICE as st, ATTR_PRODUCT_OMNIBUS_DISCOUNT as it, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as F, ATTR_CUSTOM_PREFIX as d, BUILT_IN_DEFAULT_ATTRIBUTES as nt } from "../../constants/selectors.js";
7
+ import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as w } from "../../constants/defaultConfig.js";
8
+ import { RecommendationConfigService as $ } from "../../services/configService.js";
9
9
  import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
10
10
  import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as ut, buildFillerCell as dt } from "../../templates/grid/elementRenderer.js";
11
11
  import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
12
- import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as _t, buildElementRenderer as w } from "../../templates/utils.js";
12
+ import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as gt, buildElementRenderer as M } from "../../templates/utils.js";
13
13
  import { getTableDisplayValue as ft } from "../../utils/tagName.js";
14
- import { getCurrentLayout as gt } from "../main/utils.js";
15
- const bt = "ui-elements-recommendation-card-composition", C = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", M = ".product-info-cell > table > tbody", V = "data-card-composition", y = "data-attribute-type", v = "data-visibility", x = {
14
+ import { getCurrentLayout as _t } from "../main/utils.js";
15
+ const bt = "ui-elements-recommendation-card-composition", A = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", V = ".product-info-cell > table > tbody", x = "data-card-composition", y = "data-attribute-type", N = "data-visibility", j = {
16
16
  ADD_ATTRIBUTE: "addAttribute"
17
- }, g = 5, E = "reorderIcon_", h = [
18
- { key: D, label: "Product Image" },
19
- { key: tt, label: "Product Name" },
20
- { key: et, label: "Product Price" },
21
- { key: rt, label: "Product Original Price" },
22
- { key: ot, label: "Omnibus Price" },
23
- { key: st, label: "Omnibus Discount" },
17
+ }, _ = 5, R = "reorderIcon_", h = [
18
+ { key: H, label: "Product Image" },
19
+ { key: et, label: "Product Name" },
20
+ { key: rt, label: "Product Price" },
21
+ { key: ot, label: "Product Original Price" },
22
+ { key: st, label: "Omnibus Price" },
23
+ { key: it, label: "Omnibus Discount" },
24
24
  { key: U, label: "Product Button" }
25
- ], yt = new Set(h.map((p) => p.key)), T = "customAttr_", R = "deleteAttr_";
26
- class Ut extends Z {
25
+ ], yt = new Set(h.map((p) => p.key)), T = "customAttr_", E = "deleteAttr_";
26
+ class Ht extends tt {
27
27
  constructor() {
28
28
  super(...arguments);
29
29
  S(this, "store", lt());
@@ -47,7 +47,7 @@ class Ut extends Z {
47
47
  ${this._GuToggle(`visibility_${l.key}`)}
48
48
  </div>
49
49
  `).join(""), r = Array.from(
50
- { length: g },
50
+ { length: _ },
51
51
  (l, u) => `
52
52
  <div data-custom-select-key="${T}${u}" style="display: none;">
53
53
  ${this._GuSelect({
@@ -57,13 +57,13 @@ class Ut extends Z {
57
57
  })}
58
58
  </div>
59
59
  `
60
- ).join(""), e = h.length + g, o = Array.from(
60
+ ).join(""), e = h.length + _, o = Array.from(
61
61
  { length: e },
62
62
  (l, u) => `
63
- <div data-reorder-icon-key="${E}${u}" style="display: none;">
63
+ <div data-reorder-icon-key="${R}${u}" style="display: none;">
64
64
  <${f.BUTTON}
65
65
  class="drag-handle-btn flat-inline flat-white"
66
- ${I.BUTTON.name}="${E}${u}"
66
+ ${v.BUTTON.name}="${R}${u}"
67
67
  >
68
68
  <${f.ICON}
69
69
  src="reorder"
@@ -73,12 +73,12 @@ class Ut extends Z {
73
73
  </div>
74
74
  `
75
75
  ).join(""), s = Array.from(
76
- { length: g },
76
+ { length: _ },
77
77
  (l, u) => `
78
- <div data-custom-delete-key="${R}${u}" style="display: none;">
78
+ <div data-custom-delete-key="${E}${u}" style="display: none;">
79
79
  <${f.BUTTON}
80
80
  class="custom-attr-delete flat-inline flat-white"
81
- ${I.BUTTON.name}="${R}${u}"
81
+ ${v.BUTTON.name}="${E}${u}"
82
82
  >
83
83
  <${f.ICON}
84
84
  src="delete"
@@ -89,15 +89,15 @@ class Ut extends Z {
89
89
  `
90
90
  ).join(""), i = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
91
91
  "Drag and drop the card elements to reorder them, adjust their visibility or add new attributes up to 5."
92
- ), a = this.api.translate("For more information, you can"), c = this.api.translate("visit Academy");
92
+ ), c = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
93
93
  return `
94
94
  <div class="recommendation-controls-container" data-card-composition-control>
95
95
  <div class="container">
96
96
  <p class="card-composition-description">
97
97
  ${n}
98
- ${a}
98
+ ${c}
99
99
  <!-- cspell:disable-next-line -->
100
- <a href="${i}" target="_blank" rel="noopener noreferrer">${c}</a>.
100
+ <a href="${i}" target="_blank" rel="noopener noreferrer">${a}</a>.
101
101
  </p>
102
102
  </div>
103
103
 
@@ -120,7 +120,7 @@ class Ut extends Z {
120
120
  <div class="orderable-list" data-composition-list></div>
121
121
 
122
122
  ${this._GuButton({
123
- name: x.ADD_ATTRIBUTE,
123
+ name: j.ADD_ATTRIBUTE,
124
124
  label: this.api.translate("Add Attribute"),
125
125
  id: "guido__btn-add-attribute"
126
126
  })}
@@ -149,7 +149,7 @@ class Ut extends Z {
149
149
  this._applyVisibilityToBlock(t.key, r);
150
150
  });
151
151
  });
152
- for (let t = 0; t < g; t++) {
152
+ for (let t = 0; t < _; t++) {
153
153
  const r = `${T}${t}`, e = t;
154
154
  this.api.onValueChanged(r, (o) => {
155
155
  this._onCustomAttributeChanged(e, o);
@@ -162,36 +162,42 @@ class Ut extends Z {
162
162
  _readCompositionFromNode() {
163
163
  if (!this.currentNode || !("getAttribute" in this.currentNode))
164
164
  return [...P];
165
- const t = this.currentNode.getAttribute(V);
166
- return t ? t.split(",").filter(Boolean) : [...P];
165
+ const t = this.currentNode.getAttribute(x);
166
+ if (t)
167
+ return t.split(",").filter(Boolean);
168
+ const { composition: r } = $.getConfig(this.currentNode);
169
+ return r != null && r.length ? [...r] : [...P];
167
170
  }
168
171
  _readCustomAttributesFromNode() {
169
172
  if (!this.currentNode || !("getAttribute" in this.currentNode))
170
173
  return [];
171
- const t = this.currentNode.getAttribute(q);
172
- if (!t)
173
- return [];
174
- try {
175
- return JSON.parse(t);
176
- } catch {
177
- return [];
178
- }
174
+ const t = this.currentNode.getAttribute(F);
175
+ if (t)
176
+ try {
177
+ return JSON.parse(t);
178
+ } catch {
179
+ return [];
180
+ }
181
+ return this._readCompositionFromNode().filter((r) => r.startsWith(d)).map((r) => r.substring(d.length));
179
182
  }
180
183
  _readVisibilityFromRows() {
181
184
  if (!this.currentNode)
182
185
  return this._getDefaultVisibilities();
183
- const t = Array.from(this.currentNode.querySelectorAll(C)), r = this._extractVisibilityFromRows(t);
184
- return this._mergeWithDefaults(r);
186
+ const t = Array.from(this.currentNode.querySelectorAll(A)), r = this._extractVisibilityFromRows(t);
187
+ if (Object.keys(r).length > 0)
188
+ return this._mergeWithDefaults(r);
189
+ const e = $.getConfig(this.currentNode).visibility;
190
+ return this._mergeWithDefaults({ ...e });
185
191
  }
186
192
  _getDefaultVisibilities() {
187
- return { ...F };
193
+ return { ...w };
188
194
  }
189
195
  _extractVisibilityFromRows(t) {
190
196
  const r = {};
191
197
  return t.forEach((e) => {
192
198
  if (!("getAttribute" in e))
193
199
  return;
194
- const o = e.getAttribute(y), s = e.getAttribute(v);
200
+ const o = e.getAttribute(y), s = e.getAttribute(N);
195
201
  o && s !== null && (r[o] = this._parseVisibilityValue(s));
196
202
  }), r;
197
203
  }
@@ -199,7 +205,7 @@ class Ut extends Z {
199
205
  return t === "1" || t === "true";
200
206
  }
201
207
  _mergeWithDefaults(t) {
202
- return Object.entries(F).forEach(([r, e]) => {
208
+ return Object.entries(w).forEach(([r, e]) => {
203
209
  r in t || (t[r] = e);
204
210
  }), t;
205
211
  }
@@ -223,19 +229,19 @@ class Ut extends Z {
223
229
  return !1;
224
230
  const s = new Set(r);
225
231
  let i = 0, n = 0;
226
- const a = t.map((c) => {
227
- if (yt.has(c)) {
228
- const l = h.find((u) => u.key === c);
232
+ const c = t.map((a) => {
233
+ if (yt.has(a)) {
234
+ const l = h.find((u) => u.key === a);
229
235
  return this._createBuiltInItemHtml(l, n++);
230
236
  }
231
- if (c.startsWith(m)) {
232
- const l = c.substring(m.length);
237
+ if (a.startsWith(d)) {
238
+ const l = a.substring(d.length);
233
239
  if (s.has(l))
234
- return this._createCustomItemHtml(c, i++, n++);
240
+ return this._createCustomItemHtml(a, i++, n++);
235
241
  }
236
242
  return "";
237
243
  }).join("");
238
- return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = a, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
244
+ return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = c, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
239
245
  }
240
246
  /**
241
247
  * Attempts to reorder existing orderable-item elements to match the composition order.
@@ -247,27 +253,27 @@ class Ut extends Z {
247
253
  const e = Array.from(t.querySelectorAll(".orderable-item"));
248
254
  if (e.length !== r.length)
249
255
  return !1;
250
- const o = e.map((c) => c.dataset.key).filter(Boolean);
256
+ const o = e.map((a) => a.dataset.key).filter(Boolean);
251
257
  if (o.length !== r.length)
252
258
  return !1;
253
259
  const s = [...o].sort().join(","), i = [...r].sort().join(",");
254
- if (s !== i || r.some((c) => c.startsWith(m)))
260
+ if (s !== i || r.some((a) => a.startsWith(d)))
255
261
  return !1;
256
262
  const n = /* @__PURE__ */ new Map();
257
- e.forEach((c) => {
258
- const { key: l } = c.dataset;
263
+ e.forEach((a) => {
264
+ const { key: l } = a.dataset;
259
265
  if (l) {
260
266
  const u = n.get(l) || [];
261
- u.push(c), n.set(l, u);
267
+ u.push(a), n.set(l, u);
262
268
  }
263
269
  });
264
- const a = /* @__PURE__ */ new Map();
265
- return r.forEach((c) => {
266
- const l = n.get(c);
270
+ const c = /* @__PURE__ */ new Map();
271
+ return r.forEach((a) => {
272
+ const l = n.get(a);
267
273
  if (!l)
268
274
  return;
269
- const u = a.get(c) || 0;
270
- a.set(c, u + 1), l[u] && t.appendChild(l[u]);
275
+ const u = c.get(a) || 0;
276
+ c.set(a, u + 1), l[u] && t.appendChild(l[u]);
271
277
  }), !0;
272
278
  }
273
279
  _createBuiltInItemHtml(t, r) {
@@ -316,7 +322,7 @@ class Ut extends Z {
316
322
  t.length !== 0 && setTimeout(() => {
317
323
  t.forEach((r, e) => {
318
324
  const o = `${T}${e}`, s = this._getSelectOptions(r, t);
319
- this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
325
+ this.api.setUIEAttribute(o, v.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
320
326
  });
321
327
  }, 0);
322
328
  }
@@ -366,7 +372,7 @@ class Ut extends Z {
366
372
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
367
373
  */
368
374
  _rescueSelectsToStore(t) {
369
- for (let r = 0; r < g; r++) {
375
+ for (let r = 0; r < _; r++) {
370
376
  const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
371
377
  if (s) {
372
378
  const i = s.querySelector("ue-select");
@@ -380,7 +386,7 @@ class Ut extends Z {
380
386
  */
381
387
  _moveDeleteButtonsIntoItems(t, r) {
382
388
  for (let e = 0; e < r; e++) {
383
- const o = `${R}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
389
+ const o = `${E}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
384
390
  if (s && i) {
385
391
  const n = s.querySelector("ue-button");
386
392
  n && i.appendChild(n);
@@ -392,8 +398,8 @@ class Ut extends Z {
392
398
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
393
399
  */
394
400
  _rescueDeleteButtonsToStore(t) {
395
- for (let r = 0; r < g; r++) {
396
- const e = `${R}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
401
+ for (let r = 0; r < _; r++) {
402
+ const e = `${E}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
397
403
  if (s) {
398
404
  const i = s.querySelector("ue-button");
399
405
  i && o && o.appendChild(i);
@@ -406,7 +412,7 @@ class Ut extends Z {
406
412
  */
407
413
  _moveReorderIconsIntoItems(t, r) {
408
414
  for (let e = 0; e < r; e++) {
409
- const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
415
+ const o = `${R}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
410
416
  if (s && i) {
411
417
  const n = s.querySelector("ue-button");
412
418
  n && i.appendChild(n);
@@ -418,9 +424,9 @@ class Ut extends Z {
418
424
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
419
425
  */
420
426
  _rescueReorderIconsToStore(t) {
421
- const r = h.length + g;
427
+ const r = h.length + _;
422
428
  for (let e = 0; e < r; e++) {
423
- const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
429
+ const o = `${R}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
424
430
  if (i) {
425
431
  const n = i.querySelector("ue-button");
426
432
  n && s && s.appendChild(n);
@@ -444,24 +450,24 @@ class Ut extends Z {
444
450
  _setupDragAndDrop(t, r) {
445
451
  let e = null, o = null;
446
452
  t.addEventListener("dragstart", (s) => {
447
- var a;
453
+ var c;
448
454
  const n = s.target.closest(".orderable-item");
449
- n && (e = n, n.classList.add("dragging"), (a = s.dataTransfer) == null || a.setData("text/plain", n.dataset.key || ""));
455
+ n && (e = n, n.classList.add("dragging"), (c = s.dataTransfer) == null || c.setData("text/plain", n.dataset.key || ""));
450
456
  }, { signal: r }), t.addEventListener("dragend", () => {
451
457
  e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
452
458
  }, { signal: r }), t.addEventListener("dragover", (s) => {
453
459
  s.preventDefault();
454
- const n = s.target.closest(".orderable-item"), a = n && n !== e ? n : null;
455
- a !== o && (o == null || o.classList.remove("drag-over"), o = a, o == null || o.classList.add("drag-over"));
460
+ const n = s.target.closest(".orderable-item"), c = n && n !== e ? n : null;
461
+ c !== o && (o == null || o.classList.remove("drag-over"), o = c, o == null || o.classList.add("drag-over"));
456
462
  }, { signal: r }), t.addEventListener("drop", (s) => {
457
463
  s.preventDefault();
458
464
  const n = s.target.closest(".orderable-item");
459
465
  if (!n || !e || n === e)
460
466
  return;
461
- const a = n.getBoundingClientRect(), c = a.top + a.height / 2;
462
- s.clientY < c ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
463
- const u = t.querySelectorAll(".orderable-item"), d = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
464
- this._onReorder(d), e = null;
467
+ const c = n.getBoundingClientRect(), a = c.top + c.height / 2;
468
+ s.clientY < a ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
469
+ const u = t.querySelectorAll(".orderable-item"), m = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
470
+ this._onReorder(m), e = null;
465
471
  }, { signal: r });
466
472
  }
467
473
  _setupDeleteHandler(t, r) {
@@ -477,7 +483,7 @@ class Ut extends Z {
477
483
  // Actions (Add, Delete, Reorder)
478
484
  // ========================================================================
479
485
  _onAddAttribute(t, r) {
480
- const e = `${m}${t}`, o = this._readCompositionFromNode();
486
+ const e = `${d}${t}`, o = this._readCompositionFromNode();
481
487
  o.push(e);
482
488
  const s = [...this._readCustomAttributesFromNode(), t];
483
489
  this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
@@ -490,7 +496,7 @@ class Ut extends Z {
490
496
  const r = this._readCustomAttributesFromNode();
491
497
  if (r[t] === void 0)
492
498
  return;
493
- const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((a, c) => c !== s), n = r.filter((a, c) => c !== t);
499
+ const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((c, a) => a !== s), n = r.filter((c, a) => a !== t);
494
500
  this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
495
501
  }
496
502
  /**
@@ -501,13 +507,13 @@ class Ut extends Z {
501
507
  const e = this._readCustomAttributesFromNode(), o = e[t];
502
508
  if (o === void 0 || o === r)
503
509
  return;
504
- const s = `${m}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
510
+ const s = `${d}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
505
511
  n !== -1 && (i[n] = s), e[t] = r;
506
- const a = this._getDisplayNameForAttribute(r);
507
- this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, a, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
512
+ const c = this._getDisplayNameForAttribute(r);
513
+ this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, c, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
508
514
  }
509
515
  _onReorder(t) {
510
- const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
516
+ const r = t.filter((e) => e.startsWith(d)).map((e) => e.substring(d.length));
511
517
  this.reorderInProgress = !0;
512
518
  try {
513
519
  this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
@@ -528,58 +534,58 @@ class Ut extends Z {
528
534
  const s = this.currentNode.querySelectorAll(L);
529
535
  if (!(s != null && s.length))
530
536
  return;
531
- const i = nt.getConfig(this.currentNode), a = `0 ${Math.floor(i.columnSpacing / 2)}px`, c = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
537
+ const i = $.getConfig(this.currentNode), c = `0 ${Math.floor(i.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
532
538
  let u = 0;
533
- s.forEach((d) => {
534
- var H;
535
- const b = d.querySelector(C), $ = ((H = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : H.length) || 1, B = (100 / $).toFixed(2), { bgStyle: j, bgAttr: W } = this._extractSegmentBgFromCard(d), O = l > 0 ? Math.min($, l - u) : $, K = o.map((k) => {
536
- if (k === e) {
537
- const z = Array.from(
539
+ s.forEach((m) => {
540
+ var k;
541
+ const b = m.querySelector(A), I = ((k = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : k.length) || 1, B = (100 / I).toFixed(2), { bgStyle: W, bgAttr: K } = this._extractSegmentBgFromCard(m), O = l > 0 ? Math.min(I, l - u) : I, z = o.map((q) => {
542
+ if (q === e) {
543
+ const G = Array.from(
538
544
  { length: O },
539
- (At, Y) => {
540
- const X = this._resolveAttributeContent(
545
+ (Ct, X) => {
546
+ const J = this._resolveAttributeContent(
541
547
  t,
542
548
  r,
543
- u + Y
549
+ u + X
544
550
  );
545
551
  return this._getGridCellHtml(
546
552
  t,
547
- X,
553
+ J,
548
554
  B,
549
- j,
550
555
  W,
551
- a
556
+ K,
557
+ c
552
558
  );
553
559
  }
554
- ).join(""), G = dt(B, a).repeat($ - O);
555
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${z}${G}</tr>`;
560
+ ).join(""), Y = dt(B, c).repeat(I - O);
561
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${N}="1">${G}${Y}</tr>`;
556
562
  }
557
- const N = d.querySelector(
558
- `${C}[${y}="${k}"]`
563
+ const D = m.querySelector(
564
+ `${A}[${y}="${q}"]`
559
565
  );
560
- return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
566
+ return D && "getOuterHTML" in D ? D.getOuterHTML() : "";
561
567
  }).join("");
562
- u += O, l > 0 && u >= l && (u = 0), c.modifyHtml(d).setInnerHtml(K);
563
- }), c.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
568
+ u += O, l > 0 && u >= l && (u = 0), a.modifyHtml(m).setInnerHtml(z);
569
+ }), a.apply(new C(`${this.api.translate("Add custom attribute")}: ${r}`));
564
570
  }
565
571
  _injectListAttributeRow(t, r, e, o) {
566
- const s = this.currentNode.querySelectorAll(M);
572
+ const s = this.currentNode.querySelectorAll(V);
567
573
  if (!(s != null && s.length))
568
574
  return;
569
- const i = o.filter((a) => a !== D && a !== U), n = this.api.getDocumentModifier();
570
- s.forEach((a, c) => {
575
+ const i = o.filter((c) => c !== H && c !== U), n = this.api.getDocumentModifier();
576
+ s.forEach((c, a) => {
571
577
  const l = i.map((u) => {
572
578
  if (u === e) {
573
- const b = this._resolveAttributeContent(t, r, c);
579
+ const b = this._resolveAttributeContent(t, r, a);
574
580
  return this._getListRowHtml(t, b, e);
575
581
  }
576
- const d = a.querySelector(
577
- `${C}[${y}="${u}"]`
582
+ const m = c.querySelector(
583
+ `${A}[${y}="${u}"]`
578
584
  );
579
- return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
585
+ return m && "getOuterHTML" in m ? m.getOuterHTML() : "";
580
586
  }).join("");
581
- n.modifyHtml(a).setInnerHtml(l);
582
- }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
587
+ n.modifyHtml(c).setInnerHtml(l);
588
+ }), n.apply(new C(`${this.api.translate("Add custom attribute")}: ${r}`));
583
589
  }
584
590
  /**
585
591
  * Removes a custom attribute by rebuilding product card content without it.
@@ -596,13 +602,13 @@ class Ut extends Z {
596
602
  e.modifyHtml(s).setInnerHtml(i);
597
603
  });
598
604
  } else {
599
- const o = t.filter((i) => i !== D && i !== U), s = this.currentNode.querySelectorAll(M);
605
+ const o = t.filter((i) => i !== H && i !== U), s = this.currentNode.querySelectorAll(V);
600
606
  s == null || s.forEach((i) => {
601
607
  const n = this._buildCompositionHtml(i, o);
602
608
  e.modifyHtml(i).setInnerHtml(n);
603
609
  });
604
610
  }
605
- e.apply(new A(this.api.translate("Remove custom attribute")));
611
+ e.apply(new C(this.api.translate("Remove custom attribute")));
606
612
  }
607
613
  // ========================================================================
608
614
  // DOM Mutation (Block Root Attributes, Reorder)
@@ -615,7 +621,13 @@ class Ut extends Z {
615
621
  * producing a flicker on the custom attribute dropdowns.
616
622
  */
617
623
  _updateBothAttributes(t, r) {
618
- this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(V, t.join(",")).setAttribute(q, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
624
+ if (!this.currentNode)
625
+ return;
626
+ const e = {
627
+ ...$.getConfig(this.currentNode),
628
+ composition: t
629
+ };
630
+ this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(x, t.join(",")).setAttribute(F, JSON.stringify(r)).setNodeConfig(e).apply(new C(this.api.translate("Update card composition")));
619
631
  }
620
632
  /**
621
633
  * Reorders attribute rows within each product card based on composition order.
@@ -631,7 +643,7 @@ class Ut extends Z {
631
643
  r.forEach((o) => {
632
644
  const s = this._buildCompositionHtml(o, t);
633
645
  e.modifyHtml(o).setInnerHtml(s);
634
- }), e.apply(new A(this.api.translate("Reorder product attributes")));
646
+ }), e.apply(new C(this.api.translate("Reorder product attributes")));
635
647
  }
636
648
  /**
637
649
  * Builds HTML string with attributes ordered according to composition.
@@ -639,7 +651,7 @@ class Ut extends Z {
639
651
  */
640
652
  _buildCompositionHtml(t, r) {
641
653
  return r.reduce((e, o) => {
642
- const s = t.querySelector(`${C}[${y}="${o}"]`);
654
+ const s = t.querySelector(`${A}[${y}="${o}"]`);
643
655
  return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
644
656
  }, "");
645
657
  }
@@ -649,14 +661,19 @@ class Ut extends Z {
649
661
  _applyVisibilityToBlock(t, r) {
650
662
  if (!this.currentNode)
651
663
  return;
652
- const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
664
+ const e = this.currentNode.querySelectorAll(`${A}[${y}="${t}"]`);
653
665
  if (!(e != null && e.length))
654
666
  return;
655
667
  const o = r ? "1" : "0", s = r ? this.api.translate("visible") : this.api.translate("hidden"), i = `${this.api.translate("Set visibility")}: ${t} → ${s}`, n = this.api.getDocumentModifier();
656
668
  e.forEach((a) => {
657
- const c = ft(a), l = r ? c : "none";
658
- n.modifyHtml(a).setStyle("display", l).setAttribute(v, o);
659
- }), n.apply(new A(i));
669
+ const l = ft(a), u = r ? l : "none";
670
+ n.modifyHtml(a).setStyle("display", u).setAttribute(N, o);
671
+ });
672
+ const c = {
673
+ ...$.getConfig(this.currentNode),
674
+ visibility: { ...this._readVisibilityFromRows(), [t]: r }
675
+ };
676
+ n.modifyHtml(this.currentNode).setNodeConfig(c), n.apply(new C(i));
660
677
  }
661
678
  // ========================================================================
662
679
  // Utilities
@@ -669,7 +686,7 @@ class Ut extends Z {
669
686
  _findNthCustomKeyIndex(t, r) {
670
687
  let e = 0;
671
688
  for (let o = 0; o < t.length; o++)
672
- if (t[o].startsWith(m)) {
689
+ if (t[o].startsWith(d)) {
673
690
  if (e === r)
674
691
  return o;
675
692
  e++;
@@ -677,7 +694,7 @@ class Ut extends Z {
677
694
  return -1;
678
695
  }
679
696
  _getCurrentLayout() {
680
- return this.store.recommendationConfigs.orientation || gt(this.currentNode);
697
+ return this.store.recommendationConfigs.orientation || _t(this.currentNode);
681
698
  }
682
699
  /**
683
700
  * Extracts background color properties from existing card elements.
@@ -728,10 +745,10 @@ class Ut extends Z {
728
745
  * or when all available filters have already been added (no unused attributes left).
729
746
  */
730
747
  _updateAddButtonState() {
731
- const t = this._readCustomAttributesFromNode(), r = t.length >= g, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
748
+ const t = this._readCustomAttributesFromNode(), r = t.length >= _, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
732
749
  this.api.setUIEAttribute(
733
- x.ADD_ATTRIBUTE,
734
- I.BUTTON.disabled,
750
+ j.ADD_ATTRIBUTE,
751
+ v.BUTTON.disabled,
735
752
  r || s ? "true" : "false"
736
753
  );
737
754
  }
@@ -754,7 +771,7 @@ class Ut extends Z {
754
771
  * excluding default attributes already covered by built-in toggle items.
755
772
  */
756
773
  _getAddableFilters() {
757
- return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && it.has(t.attributeName)));
774
+ return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && nt.has(t.attributeName)));
758
775
  }
759
776
  /**
760
777
  * Looks up the display name for an attribute from the store's filterList.
@@ -771,28 +788,28 @@ class Ut extends Z {
771
788
  _resolveAttributeContent(t, r, e) {
772
789
  var n;
773
790
  const s = this.store.recommendationProducts[e], i = pt(t, this.store.filterList) ? s == null ? void 0 : s[t] : (n = s == null ? void 0 : s.product_attributes) == null ? void 0 : n[t];
774
- return _t(i) ?? r;
791
+ return gt(i) ?? r;
775
792
  }
776
793
  _getGridCellHtml(t, r, e, o = "", s = "", i = "") {
777
- const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
794
+ const n = `${d}${t}`, c = M(ct, [n], this.store.filterList), a = {
778
795
  [t]: r,
779
796
  product_attributes: { [t]: r }
780
797
  };
781
- let l = a[n](c);
798
+ let l = c[n](a);
782
799
  return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
783
800
  `padding: ${ut}`,
784
801
  `padding: ${i}`
785
802
  )), o && (l = l.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), s && (l = l.replace(/border="0"/, `border="0" bgcolor="${s}"`)), l;
786
803
  }
787
804
  _getListRowHtml(t, r, e) {
788
- const o = w(mt, [e], this.store.filterList), s = {
805
+ const o = M(mt, [e], this.store.filterList), s = {
789
806
  [t]: r,
790
807
  product_attributes: { [t]: r }
791
808
  }, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
792
- return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
809
+ return `<tr class="recommendation-attribute-row" ${y}="${e}" ${N}="1">${n}</tr>`;
793
810
  }
794
811
  }
795
812
  export {
796
813
  bt as COMPOSITION_CONTROL_BLOCK_ID,
797
- Ut as RecommendationCardCompositionControl
814
+ Ht as RecommendationCardCompositionControl
798
815
  };
@@ -24,6 +24,5 @@ export declare class ItemsBlock extends Block {
24
24
  getSettingsPanelTitleHtml(): string;
25
25
  getTemplate(): string;
26
26
  allowInnerBlocksDND(): boolean;
27
- canBeSavedAsModule(): boolean;
28
27
  onCreated(node: ImmutableHtmlNode): void;
29
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.7.0-beta.24a845f",
3
+ "version": "3.7.0-beta.30ff65e",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",