@useinsider/guido 3.12.0-beta.40db55d → 3.12.0-beta.4e0547f

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 (32) hide show
  1. package/README.md +2 -14
  2. package/dist/components/Guido.vue.js +1 -1
  3. package/dist/components/Guido.vue2.js +110 -101
  4. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
  5. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
  6. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  7. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
  8. package/dist/components/organisms/header/ViewOptions.vue.js +3 -3
  9. package/dist/components/organisms/header/version-history/ViewOptions.vue.js +1 -1
  10. package/dist/composables/usePreviewInteractionGuard.js +36 -11
  11. package/dist/composables/useRecommendationPreview.js +61 -60
  12. package/dist/composables/useStripo.js +72 -69
  13. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  14. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  15. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  16. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  17. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  18. package/dist/extensions/Blocks/controlFactories.js +125 -75
  19. package/dist/guido.css +1 -1
  20. package/dist/src/components/Guido.vue.d.ts +18 -2
  21. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  22. package/dist/src/composables/useStripo.d.ts +3 -2
  23. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  24. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  25. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  26. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  27. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  28. package/dist/src/stores/config.d.ts +3 -1
  29. package/dist/src/utils/urlSchemes.d.ts +6 -0
  30. package/dist/stores/config.js +21 -19
  31. package/dist/utils/urlSchemes.js +4 -0
  32. package/package.json +5 -10
@@ -0,0 +1,14 @@
1
+ export declare const BlockBackgroundColorControl: {
2
+ new (): {
3
+ getId(): string;
4
+ getLabels(): {
5
+ title: string;
6
+ };
7
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
8
+ getAdditionalModifications(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
9
+ getParentControlId(): string;
10
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
11
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
12
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
13
+ };
14
+ };
@@ -20,6 +20,7 @@ export { ButtonControls } from './button';
20
20
  export { ImageControls } from './image';
21
21
  export { CustomAttributeControls } from './customAttribute';
22
22
  export { SpacingControl, SPACING_CONTROL_ID } from './spacing';
23
+ export { BlockBackgroundColorControl } from './blockBackground';
23
24
  export { CardBackgroundColorControl, CARD_BACKGROUND_COLOR_CONTROL_ID } from './cardBackground';
24
25
  export { RecommendationCardCompositionControl, COMPOSITION_CONTROL_BLOCK_ID } from './cardComposition';
25
26
  export { SyncInfoMessageControl, SYNC_INFO_MESSAGE_CONTROL_ID } from './syncInfoMessage';
@@ -9,3 +9,4 @@ export declare const DATA_ATTRIBUTES: {
9
9
  readonly BLOCK_ID: "data-unsubscribe-block-id";
10
10
  };
11
11
  export declare const UNSUBSCRIBE_BLOCK_SELECTOR = ".unsubscribe-block-v2";
12
+ export declare const UNSUBSCRIBE_LINK_SELECTOR = "a[data-unsubscribe-link=\"true\"], a.unsubscribe-link";
@@ -115,6 +115,42 @@ export declare function createTextBackgroundColorControl(controlId: string, targ
115
115
  isVisible(_node: ImmutableHtmlNode): boolean;
116
116
  };
117
117
  };
118
+ /**
119
+ * Factory for a background-color control that paints a whole extension block (SD-145082).
120
+ *
121
+ * Base is `ButtonBackgroundColorBuiltInControl` because its `GENERAL.BACKGROUND_COLOR` form key
122
+ * round-trips through `getValues()`; the block-text base (`TextBlockBackgroundBuiltInControl`, the
123
+ * built-in this replaces) reports `textBlockBackgroundColor`, which our read path never sees. That
124
+ * borrowed base targets the block's Buy buttons, so `getTargetNodes` here is a GUARD that keeps it
125
+ * off the buttons — not the write path.
126
+ *
127
+ * The write is entirely ours (`getAdditionalModifications`): Stripo's built-in emits a stylesheet
128
+ * rule that inline styles from regeneration outrank (SD-143023), so it would silently no-op on the
129
+ * next edit. We write inline `background-color` + `bgcolor` on the block `<td>` instead — surviving
130
+ * regeneration and reaching Outlook, matching the migrator's convention.
131
+ */
132
+ export declare function createBlockBackgroundColorControl(controlId: string, blockRootSelector?: string): {
133
+ new (): {
134
+ getId(): string;
135
+ /** The parent control renders its own generic title; restore the block-level wording. */
136
+ getLabels(): {
137
+ title: string;
138
+ };
139
+ /** Guard: redirect the borrowed button parent onto the block `<td>` so it never paints the Buy buttons. */
140
+ getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
141
+ /**
142
+ * Writes the picked background onto the block as an inline style plus a `bgcolor`
143
+ * attribute. This is the whole mechanism, not a mirror: the parent control's own
144
+ * write never reaches the block element (verified at runtime). `bgcolor` is the
145
+ * channel Outlook honours on a `<td>`, and matches what the migrator emits.
146
+ */
147
+ getAdditionalModifications(root: ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
148
+ getParentControlId(): string;
149
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
150
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
151
+ isVisible(_node: ImmutableHtmlNode): boolean;
152
+ };
153
+ };
118
154
  /**
119
155
  * Factory function to create paddings controls for different block elements
120
156
  * When targetBlockId and containerSelector are not provided, applies directly to root
@@ -2336,7 +2336,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2336
2336
  } | null;
2337
2337
  } & import("pinia").PiniaCustomStateProperties<ConfigStoreState>) => boolean;
2338
2338
  /**
2339
- * Check if a specific feature is enabled
2339
+ * Check if a specific feature is enabled.
2340
+ * Returns false before init (config null) so header controls don't
2341
+ * flash on during loading, then disappear once config resolves.
2340
2342
  */
2341
2343
  isFeatureEnabled: (state: {
2342
2344
  initialized: boolean;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * URL schemes that are safe to follow from partner-authored email HTML. Shared so a
3
+ * future bypass fix lands in one place — the preview guard and the recommendation
4
+ * sanitizer both gate on it. Stored with the trailing colon to match `anchor.protocol`.
5
+ */
6
+ export declare const BASE_SAFE_URL_SCHEMES: readonly string[];
@@ -75,65 +75,67 @@ const f = r("guido-config", {
75
75
  * Get the template ID
76
76
  */
77
77
  templateId: (i) => {
78
- var e, t;
79
- return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.templateId) ?? "";
78
+ var e, n;
79
+ return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.templateId) ?? "";
80
80
  },
81
81
  /**
82
82
  * Get the user ID
83
83
  */
84
84
  userId: (i) => {
85
- var e, t;
86
- return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.userId) ?? "";
85
+ var e, n;
86
+ return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.userId) ?? "";
87
87
  },
88
88
  /**
89
89
  * Get the variation ID
90
90
  */
91
91
  variationId: (i) => {
92
- var e, t;
93
- return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.variationId) ?? "";
92
+ var e, n;
93
+ return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.variationId) ?? "";
94
94
  },
95
95
  /**
96
96
  * Get the partner name
97
97
  */
98
98
  partnerName: (i) => {
99
- var e, t;
100
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.name) ?? "";
99
+ var e, n;
100
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.name) ?? "";
101
101
  },
102
102
  /**
103
103
  * Get the product type
104
104
  */
105
105
  productType: (i) => {
106
- var e, t;
107
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.productType) ?? 60;
106
+ var e, n;
107
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.productType) ?? 60;
108
108
  },
109
109
  /**
110
110
  * Get the message type
111
111
  */
112
112
  messageType: (i) => {
113
- var e, t;
114
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.messageType) ?? 1;
113
+ var e, n;
114
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.messageType) ?? 1;
115
115
  },
116
116
  /**
117
117
  * Get the username
118
118
  */
119
119
  username: (i) => {
120
- var e, t;
121
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.username) ?? "Guido User";
120
+ var e, n;
121
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.username) ?? "Guido User";
122
122
  },
123
123
  /**
124
124
  * Check if header should be shown
125
125
  */
126
126
  showHeader: (i) => {
127
- var e, t;
128
- return ((t = (e = i.config) == null ? void 0 : e.ui) == null ? void 0 : t.showHeader) ?? !0;
127
+ var e, n;
128
+ return ((n = (e = i.config) == null ? void 0 : e.ui) == null ? void 0 : n.showHeader) ?? !0;
129
129
  },
130
130
  /**
131
- * Check if a specific feature is enabled
131
+ * Check if a specific feature is enabled.
132
+ * Returns false before init (config null) so header controls don't
133
+ * flash on during loading, then disappear once config resolves.
132
134
  */
133
135
  // eslint-disable-next-line @stylistic/max-len
134
136
  isFeatureEnabled: (i) => (e) => {
135
- var t, n;
136
- return ((n = (t = i.config) == null ? void 0 : t.features) == null ? void 0 : n[e]) ?? !0;
137
+ var n, t;
138
+ return ((t = (n = i.config) == null ? void 0 : n.features) == null ? void 0 : t[e]) ?? !1;
137
139
  }
138
140
  },
139
141
  actions: {
@@ -0,0 +1,4 @@
1
+ const t = ["http:", "https:", "mailto:"];
2
+ export {
3
+ t as BASE_SAFE_URL_SCHEMES
4
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.12.0-beta.40db55d",
3
+ "version": "3.12.0-beta.4e0547f",
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",
@@ -44,15 +44,13 @@
44
44
  "license": "ISC",
45
45
  "dependencies": {
46
46
  "@stripoinc/ui-editor-extensions": "3.8.0",
47
+ "@useinsider/design-system-vue": "1.3.0",
47
48
  "@vueuse/core": "11.3.0",
48
49
  "lodash-es": "4.17.21",
50
+ "pinia": "2.3.1",
49
51
  "valibot": "1.2.0",
50
- "vite": "6.3.5"
51
- },
52
- "peerDependencies": {
53
- "@useinsider/design-system-vue": "^2.0.0",
54
- "pinia": "^2.3.0",
55
- "vue": "^2.7.0"
52
+ "vite": "6.3.5",
53
+ "vue": "2.7.14"
56
54
  },
57
55
  "devDependencies": {
58
56
  "@commitlint/cli": "20.2.0",
@@ -72,7 +70,6 @@
72
70
  "@types/node": "20.10.4",
73
71
  "@typescript-eslint/eslint-plugin": "7.18.0",
74
72
  "@typescript-eslint/parser": "7.18.0",
75
- "@useinsider/design-system-vue": "2.0.0",
76
73
  "@useinsider/eslint-config": "1.5.3",
77
74
  "@vitejs/plugin-vue2": "2.3.1",
78
75
  "@vitest/coverage-v8": "2.1.9",
@@ -89,14 +86,12 @@
89
86
  "husky": "9.1.7",
90
87
  "msw": "2.10.3",
91
88
  "nyc": "17.1.0",
92
- "pinia": "2.3.1",
93
89
  "sass": "1.69.7",
94
90
  "typescript": "5.5.4",
95
91
  "typescript-eslint": "8.26.0",
96
92
  "vite-plugin-dts": "4.5.4",
97
93
  "vite-plugin-istanbul": "7.0.0",
98
94
  "vitest": "2.1.9",
99
- "vue": "2.7.14",
100
95
  "vue-tsc": "2.2.10"
101
96
  },
102
97
  "overrides": {