@useinsider/guido 3.1.1 → 3.2.0-beta.080341b

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 (189) hide show
  1. package/README.md +117 -0
  2. package/dist/@types/config/schemas.js +166 -96
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +92 -80
  5. package/dist/components/organisms/AutoSaveController.vue.js +17 -0
  6. package/dist/components/organisms/AutoSaveController.vue2.js +13 -0
  7. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +7 -7
  8. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +12 -20
  9. package/dist/components/organisms/header/AutoSaveToggle.vue.js +22 -0
  10. package/dist/components/organisms/header/AutoSaveToggle.vue2.js +19 -0
  11. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  12. package/dist/components/organisms/header/EditorActions.vue2.js +51 -36
  13. package/dist/components/organisms/header/RightSlot.vue.js +11 -11
  14. package/dist/components/organisms/header/RightSlot.vue2.js +17 -13
  15. package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
  16. package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
  17. package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
  18. package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
  19. package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
  20. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
  21. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
  22. package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
  23. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +18 -17
  24. package/dist/composables/useActionsApi.js +4 -4
  25. package/dist/composables/useAutoSave.js +71 -0
  26. package/dist/composables/useFullStoryBridge.js +14 -0
  27. package/dist/composables/useHtmlCompiler.js +23 -21
  28. package/dist/composables/useHtmlValidator.js +40 -38
  29. package/dist/composables/usePreviewMode.js +20 -16
  30. package/dist/composables/useRecommendation.js +46 -26
  31. package/dist/composables/useRibbonOffset.js +21 -0
  32. package/dist/composables/useSave.js +26 -15
  33. package/dist/composables/useStripo.js +48 -45
  34. package/dist/composables/validators/useCouponBlockValidator.js +24 -0
  35. package/dist/composables/validators/useLiquidValidator.js +42 -0
  36. package/dist/config/compiler/liquidCompilerRules.js +15 -0
  37. package/dist/config/compiler/recommendationCompilerRules.js +162 -43
  38. package/dist/config/compiler/unsubscribeCompilerRules.js +48 -45
  39. package/dist/config/compiler/utils/recommendationCompilerUtils.js +110 -71
  40. package/dist/config/i18n/en/tooltips.json.js +2 -1
  41. package/dist/config/migrator/checkboxMigrator.js +5 -3
  42. package/dist/config/migrator/index.js +9 -9
  43. package/dist/config/migrator/radioButtonMigrator.js +66 -44
  44. package/dist/config/migrator/recommendation/compositionMapper.js +98 -0
  45. package/dist/config/migrator/recommendation/extractors.js +27 -0
  46. package/dist/config/migrator/recommendation/htmlBuilder.js +496 -0
  47. package/dist/config/migrator/recommendation/parseLegacyConfig.js +33 -0
  48. package/dist/config/migrator/recommendation/settingsMapper.js +70 -0
  49. package/dist/config/migrator/recommendation/themeMapper.js +93 -0
  50. package/dist/config/migrator/recommendationMigrator.js +74 -290
  51. package/dist/enums/extensions/recommendationBlock.js +16 -12
  52. package/dist/enums/onboarding.js +7 -2
  53. package/dist/enums/recommendation.js +2 -2
  54. package/dist/enums/unsubscribe.js +34 -27
  55. package/dist/extensions/Blocks/CouponBlock/template.js +24 -13
  56. package/dist/extensions/Blocks/Items/controls/price/singlePrice.js +38 -38
  57. package/dist/extensions/Blocks/Items/enums/productEnums.js +19 -7
  58. package/dist/extensions/Blocks/RadioButton/template.js +1 -1
  59. package/dist/extensions/Blocks/Recommendation/block.js +60 -50
  60. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  61. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +5 -5
  62. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +27 -11
  63. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +185 -172
  64. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +21 -18
  65. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +99 -0
  66. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +27 -26
  67. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +3 -1
  68. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +211 -162
  69. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +27 -57
  70. package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +14 -0
  71. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +75 -73
  72. package/dist/extensions/Blocks/Recommendation/services/configService.js +76 -33
  73. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +18 -17
  74. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +123 -79
  75. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +24 -13
  76. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -29
  77. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -7
  78. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +27 -15
  79. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
  80. package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -50
  81. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +17 -14
  82. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMap.js +21 -0
  83. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +13 -22
  84. package/dist/extensions/Blocks/Recommendation/utils/tagName.js +6 -6
  85. package/dist/extensions/Blocks/Unsubscribe/block.js +11 -11
  86. package/dist/extensions/Blocks/Unsubscribe/settingsPanel.js +16 -17
  87. package/dist/extensions/DynamicContent/dynamic-content.js +17 -12
  88. package/dist/guido.css +1 -1
  89. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +393 -264
  90. package/dist/node_modules/valibot/dist/index.js +450 -235
  91. package/dist/package.json.js +1 -1
  92. package/dist/services/recommendationApi.js +15 -15
  93. package/dist/services/stripoApi.js +9 -9
  94. package/dist/services/templateLibraryApi.js +49 -46
  95. package/dist/src/@types/config/defaults.d.ts +5 -1
  96. package/dist/src/@types/config/index.d.ts +3 -3
  97. package/dist/src/@types/config/schemas.d.ts +245 -0
  98. package/dist/src/@types/config/types.d.ts +11 -1
  99. package/dist/src/@types/generic.d.ts +0 -1
  100. package/dist/src/@types/save-as-template.d.ts +1 -0
  101. package/dist/src/components/Guido.vue.d.ts +1 -1
  102. package/dist/src/components/organisms/AutoSaveController.vue.d.ts +2 -0
  103. package/dist/src/components/organisms/header/AutoSaveToggle.vue.d.ts +2 -0
  104. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  105. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  106. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  107. package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
  108. package/dist/src/composables/useActionsApi.d.ts +1 -1
  109. package/dist/src/composables/useAutoSave.d.ts +3 -0
  110. package/dist/src/composables/useConfig.d.ts +70 -0
  111. package/dist/src/composables/useFullStoryBridge.d.ts +11 -0
  112. package/dist/src/composables/useRecommendation.d.ts +10 -1
  113. package/dist/src/composables/useRecommendation.test.d.ts +1 -0
  114. package/dist/src/composables/useRibbonOffset.d.ts +4 -0
  115. package/dist/src/composables/useSave.d.ts +1 -1
  116. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  117. package/dist/src/composables/validators/useLiquidValidator.d.ts +3 -0
  118. package/dist/src/config/compiler/liquidCompilerRules.d.ts +2 -0
  119. package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +1 -1
  120. package/dist/src/config/migrator/index.d.ts +2 -1
  121. package/dist/src/config/migrator/recommendation/compositionMapper.d.ts +2 -0
  122. package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +1 -0
  123. package/dist/src/config/migrator/recommendation/extractors.d.ts +7 -0
  124. package/dist/src/config/migrator/recommendation/extractors.test.d.ts +1 -0
  125. package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +11 -0
  126. package/dist/src/config/migrator/recommendation/parseLegacyConfig.d.ts +15 -0
  127. package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +1 -0
  128. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +7 -0
  129. package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +1 -0
  130. package/dist/src/config/migrator/recommendation/themeMapper.d.ts +5 -0
  131. package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +1 -0
  132. package/dist/src/config/migrator/recommendation/types.d.ts +205 -0
  133. package/dist/src/config/migrator/recommendationMigrator.d.ts +13 -1
  134. package/dist/src/config/migrator/recommendationMigrator.test.d.ts +1 -0
  135. package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
  136. package/dist/src/enums/onboarding.d.ts +6 -0
  137. package/dist/src/enums/unsubscribe.d.ts +5 -0
  138. package/dist/src/extensions/Blocks/CouponBlock/template.d.ts +2 -0
  139. package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
  140. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  141. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  142. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +5 -0
  143. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +5 -0
  144. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +3 -0
  145. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +35 -0
  146. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +1 -0
  147. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +3 -20
  148. package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +29 -0
  149. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +21 -3
  150. package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +1 -0
  151. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +34 -0
  152. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  153. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  154. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +20 -3
  155. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -1
  156. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.d.ts +21 -0
  157. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +1 -0
  158. package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -3
  159. package/dist/src/library.d.ts +1 -1
  160. package/dist/src/services/templateLibraryApi.d.ts +1 -1
  161. package/dist/src/stores/autosave.d.ts +12 -0
  162. package/dist/src/stores/config.d.ts +630 -0
  163. package/dist/src/stores/editor.d.ts +23 -0
  164. package/dist/src/stores/onboarding.d.ts +4 -0
  165. package/dist/src/stores/preview.d.ts +3 -0
  166. package/dist/src/utils/genericUtil.d.ts +1 -1
  167. package/dist/src/utils/htmlCompiler.d.ts +2 -1
  168. package/dist/src/utils/htmlEscape.d.ts +5 -0
  169. package/dist/src/utils/htmlEscape.test.d.ts +1 -0
  170. package/dist/src/utils/timeUtil.d.ts +8 -0
  171. package/dist/static/styles/base.css.js +7 -2
  172. package/dist/static/styles/components/button.css.js +16 -9
  173. package/dist/static/styles/components/loader.css.js +4 -0
  174. package/dist/static/styles/components/narrow-panel.css.js +52 -0
  175. package/dist/stores/autosave.js +17 -0
  176. package/dist/stores/editor.js +3 -1
  177. package/dist/stores/onboarding.js +4 -0
  178. package/dist/stores/preview.js +4 -3
  179. package/dist/utils/genericUtil.js +42 -20
  180. package/dist/utils/htmlCompiler.js +48 -41
  181. package/dist/utils/htmlEscape.js +13 -0
  182. package/dist/utils/pairProductVariables.js +89 -88
  183. package/dist/utils/templatePreparation.js +75 -24
  184. package/dist/utils/timeUtil.js +19 -0
  185. package/dist/utils/tooltipUtils.js +4 -5
  186. package/package.json +8 -4
  187. package/dist/enums/displayConditions.js +0 -80
  188. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +0 -251
  189. package/dist/src/enums/displayConditions.d.ts +0 -2
@@ -263,4 +263,27 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
263
263
  templateId: string;
264
264
  syncModulesEnabled: boolean;
265
265
  }>) => boolean;
266
+ isInSaveableState: (state: {
267
+ loadingStatus: boolean;
268
+ isCodeEditorOpen: boolean;
269
+ isSaveAsTemplateDrawerOpen: boolean;
270
+ isVersionHistoryOpen: boolean;
271
+ isPreviewModeOpen: boolean;
272
+ editorVisualMode: string;
273
+ hasChanges: boolean;
274
+ isStripoInitialized: boolean;
275
+ templateId: string;
276
+ syncModulesEnabled: boolean;
277
+ } & import("pinia").PiniaCustomStateProperties<{
278
+ loadingStatus: boolean;
279
+ isCodeEditorOpen: boolean;
280
+ isSaveAsTemplateDrawerOpen: boolean;
281
+ isVersionHistoryOpen: boolean;
282
+ isPreviewModeOpen: boolean;
283
+ editorVisualMode: string;
284
+ hasChanges: boolean;
285
+ isStripoInitialized: boolean;
286
+ templateId: string;
287
+ syncModulesEnabled: boolean;
288
+ }>) => boolean;
266
289
  }, {}>;
@@ -1392,6 +1392,10 @@ export declare const useOnboardingStore: import("pinia").StoreDefinition<"guidoO
1392
1392
  close(type: OnboardingType): Promise<void>;
1393
1393
  next(type: OnboardingType): void;
1394
1394
  previous(type: OnboardingType): void;
1395
+ updateCardPosition(type: OnboardingType, cardIndex: number, position: {
1396
+ top: string;
1397
+ position: string;
1398
+ }): void;
1395
1399
  setConfig(type: OnboardingType, config: OnboardingCardConfig[]): void;
1396
1400
  onDiscoverNowClicked(): Promise<void>;
1397
1401
  onRemindMeLater(): void;
@@ -7,6 +7,7 @@ export declare const usePreviewStore: import("pinia").StoreDefinition<"guidoPrev
7
7
  templateHtml: string;
8
8
  isLoaded: boolean;
9
9
  isAMPErrorModalVisible: boolean;
10
+ emailSizeKB: number;
10
11
  } & import("pinia").PiniaCustomStateProperties<PreviewState>) => boolean;
11
12
  previewHtml(): string;
12
13
  hasAMP: (state: {
@@ -16,6 +17,7 @@ export declare const usePreviewStore: import("pinia").StoreDefinition<"guidoPrev
16
17
  templateHtml: string;
17
18
  isLoaded: boolean;
18
19
  isAMPErrorModalVisible: boolean;
20
+ emailSizeKB: number;
19
21
  } & import("pinia").PiniaCustomStateProperties<PreviewState>) => boolean;
20
22
  hasAMPErrors: (state: {
21
23
  emailFormat: EmailFormat;
@@ -24,6 +26,7 @@ export declare const usePreviewStore: import("pinia").StoreDefinition<"guidoPrev
24
26
  templateHtml: string;
25
27
  isLoaded: boolean;
26
28
  isAMPErrorModalVisible: boolean;
29
+ emailSizeKB: number;
27
30
  } & import("pinia").PiniaCustomStateProperties<PreviewState>) => boolean;
28
31
  showAMPErrorButton(): boolean;
29
32
  isAMPResponsive(): boolean;
@@ -1,6 +1,6 @@
1
1
  import type { DynamicContent, MergeTag } from '@@/Types/generic';
2
2
  export declare const mergeTagToDynamicContent: (mergeTag: MergeTag) => DynamicContent;
3
- export declare const dynamicContentToMergeTags: (dynamicContentList: DynamicContent[]) => MergeTag[];
3
+ export declare const dynamicContentToMergeTags: (dynamicContentList: DynamicContent[], liquidSyntax?: boolean) => MergeTag[];
4
4
  export declare const getCsrfToken: () => string;
5
5
  /**
6
6
  * URL Parameter utilities
@@ -1,8 +1,9 @@
1
+ import type { FallbackFont } from '@@/Types/config';
1
2
  import type { CompilerRule, CompilationResult, HtmlCompiler } from '@@/Types/html-compiler';
2
3
  export declare class HtmlCompilerEngine implements HtmlCompiler {
3
4
  private rules;
4
5
  constructor(rules?: CompilerRule[]);
5
- compile(html: string, rules?: CompilerRule[]): CompilationResult;
6
+ compile(html: string, rules?: CompilerRule[], fallbackFont?: FallbackFont): CompilationResult;
6
7
  private applyRule;
7
8
  private applyReplaceRule;
8
9
  private applyRegexRule;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Escape HTML special characters for safe inclusion in attribute values
3
+ * or text content. Use for any string that may contain untrusted input.
4
+ */
5
+ export declare function escapeHtml(text: string): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Formats a Date as local time in 24-hour format.
3
+ * Pass `useTimezone = true` to append the UTC offset and city name — useful when the
4
+ * timestamp must clearly communicate the client's timezone.
5
+ * @example formatLocalTime(date) -> 12:20:02
6
+ * @example formatLocalTime(date, true) -> 12:20:02 (UTC+3 Istanbul)
7
+ */
8
+ export declare const formatLocalTime: (date: Date, useTimezone?: boolean) => string;
@@ -1,11 +1,16 @@
1
- const t = `.amp-input-list,
1
+ const n = `.amp-input-list,
2
2
  .button,
3
3
  .base-input,
4
4
  ue-stripe-thumb,
5
5
  .ue-stripe-thumb {
6
6
  transition: all .5s ease;
7
7
  }
8
+
9
+ :host {
10
+ height: 100% !important;
11
+ min-height: 0 !important;
12
+ }
8
13
  `;
9
14
  export {
10
- t as default
15
+ n as default
11
16
  };
@@ -1,4 +1,4 @@
1
- const o = `.control-shadow-wrapper:has(.button) {
1
+ const n = `.control-shadow-wrapper:has(.button) {
2
2
  border-radius: 0;
3
3
  box-shadow: none;
4
4
  background-color: transparent;
@@ -99,18 +99,12 @@ ue-check-button.checked:not(.flat-white) input:checked + label .icon-button {
99
99
  color: var(--guido-color-primary-500);
100
100
  }
101
101
 
102
- ue-select.full-width .button {
103
- border: none !important;
104
- background-color: var(--guido-color-neutral-200) !important;
105
- color: var(--guido-color-neutral-800) !important;
106
- }
107
-
108
102
  ue-select.full-width .button .icon-button {
109
103
  color: var(--guido-color-gray-600) !important;
110
104
  }
111
105
 
112
106
  ue-select.full-width .button:hover:not(:disabled,.disabled) {
113
- background-color: var(--guido-color-neutral-100) !important;
107
+ background-color: var(--guido-color-gray-0) !important;
114
108
  }
115
109
 
116
110
  ue-color {
@@ -130,7 +124,20 @@ ue-select-text-input .select-text-input-toggle .button {
130
124
  justify-content: center;
131
125
  background-color: transparent !important;
132
126
  }
127
+
128
+
129
+ .control-shadow-wrapper,
130
+ ue-button:not(.no-shadow,.flat-white),
131
+ ue-toggle:not(.no-shadow,.flat-white),
132
+ :is(ue-popover-toggler,ue-toggle-icon-picker,ue-emoji-toggle),
133
+ .button-group,
134
+ ue-counter:not(.no-shadow),
135
+ :is(ue-select,ue-mergetags,ue-font-family-select):not(.no-shadow),
136
+ ue-check-button:not(.no-shadow,.flat-white) {
137
+ background: none;
138
+ padding: 0;
139
+ }
133
140
  `;
134
141
  export {
135
- o as default
142
+ n as default
136
143
  };
@@ -4,6 +4,10 @@ const n = `ue-loader-component.full-height {
4
4
  z-index: 9;
5
5
  backdrop-filter: blur(2px);
6
6
  }
7
+
8
+ ue-loader-component .service-element.loader {
9
+ box-shadow: var(--guido-color-primary-500) 1px 1px 0 0 !important;
10
+ }
7
11
  `;
8
12
  export {
9
13
  n as default
@@ -28,6 +28,58 @@ ue-stripe-thumb:hover:not(.disabled),
28
28
  border-color: var(--guido-color-primary-500);
29
29
  }
30
30
 
31
+ /* Module search — initial */
32
+ .module-search-container {
33
+ background-color: var(--guido-color-gray-0);
34
+ border: 1px solid var(--guido-color-gray-300);
35
+ border-radius: 4px;
36
+ }
37
+
38
+ .module-search-container .service-element {
39
+ background-color: unset;
40
+ }
41
+
42
+ .module-filter-toggle {
43
+ top: -1px !important;
44
+ right: -1px !important;
45
+ }
46
+
47
+ .module-filter-toggle > .button,
48
+ .module-search-container:hover .module-filter-toggle > .button {
49
+ border: none;
50
+ background: transparent;
51
+ }
52
+
53
+ /* Module search — hover */
54
+ .module-search-container:has(.module-search-chip-input:hover) {
55
+ border-color: var(--guido-color-primary-500);
56
+ }
57
+
58
+ .module-search-container .module-search-chip-input .service-element:hover {
59
+ background-color: var(--guido-color-gray-0);
60
+ border-radius: 4px;
61
+ }
62
+
63
+ .module-search-container .module-filter-toggle:hover > .button {
64
+ background-color: var(--guido-color-gray-1);
65
+ }
66
+
67
+ /* Module search — selected (.on) */
68
+ .module-search-container:has(.module-search-chip-input.on),
69
+ .module-search-container:has(.module-search-chip-input.on):hover {
70
+ border-color: var(--guido-color-primary-500);
71
+ box-shadow: 0 0 0 3px var(--guido-color-primary-200) !important;
72
+ }
73
+
74
+ .module-search-container .module-search-chip-input.on .input-section {
75
+ background-color: unset;
76
+ box-shadow: unset;
77
+ }
78
+
79
+ .module-categories-list .menu-item {
80
+ padding: 8px 20px !important;
81
+ }
82
+
31
83
  .modules-layout-wrapper {
32
84
  padding: 0 16px 16px;
33
85
  grid-row-gap: 16px;
@@ -0,0 +1,17 @@
1
+ import { defineStore as e } from "pinia";
2
+ const t = {
3
+ IDLE: "idle",
4
+ SAVING: "saving",
5
+ SAVED: "saved",
6
+ ERROR: "error"
7
+ }, o = e("guidoAutosave", {
8
+ state: () => ({
9
+ isOn: !1,
10
+ lastSavedAt: null,
11
+ status: t.IDLE
12
+ })
13
+ });
14
+ export {
15
+ t as AUTOSAVE_STATUS,
16
+ o as useAutosaveStore
17
+ };
@@ -25,7 +25,9 @@ const o = e("guidoEditor", {
25
25
  isExportButtonDisabled: (i) => i.loadingStatus || i.isVersionHistoryOpen,
26
26
  isSaveAsButtonDisabled: (i) => i.loadingStatus || i.isVersionHistoryOpen,
27
27
  isTestButtonDisabled: (i) => i.loadingStatus || i.isVersionHistoryOpen,
28
- isSaveButtonDisabled: (i) => i.loadingStatus || i.isVersionHistoryOpen || i.isPreviewModeOpen
28
+ isSaveButtonDisabled: (i) => i.loadingStatus || i.isVersionHistoryOpen || i.isPreviewModeOpen,
29
+ // Autosave
30
+ isInSaveableState: (i) => !i.loadingStatus && !i.isVersionHistoryOpen && !i.isPreviewModeOpen && !i.isCodeEditorOpen
29
31
  }
30
32
  });
31
33
  export {
@@ -71,6 +71,10 @@ const t = () => ({
71
71
  previous(n) {
72
72
  this.onboardings[n].cardIndex > 0 && this.onboardings[n].cardIndex--;
73
73
  },
74
+ updateCardPosition(n, i, o) {
75
+ const s = this.onboardings[n].config[i];
76
+ s && (s.top = o.top, s.position = o.position);
77
+ },
74
78
  setConfig(n, i) {
75
79
  this.onboardings[n].config = i ?? [], this.onboardings[n].cardIndex >= this.onboardings[n].config.length && (this.onboardings[n].cardIndex = 0);
76
80
  },
@@ -1,13 +1,14 @@
1
1
  import { defineStore as e } from "pinia";
2
- const s = () => ({
2
+ const i = () => ({
3
3
  emailFormat: "html",
4
4
  ampHtml: "",
5
5
  ampErrors: [],
6
6
  templateHtml: "",
7
7
  isLoaded: !1,
8
- isAMPErrorModalVisible: !1
8
+ isAMPErrorModalVisible: !1,
9
+ emailSizeKB: 0
9
10
  }), a = e("guidoPreview", {
10
- state: () => s(),
11
+ state: () => i(),
11
12
  getters: {
12
13
  isAMPModeEnabled: (t) => t.emailFormat === "AMP",
13
14
  previewHtml() {
@@ -1,25 +1,47 @@
1
- const f = (t) => {
2
- const n = t.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((l) => l.trim()), [r] = n, e = {
3
- text: t.label,
4
- value: r || ""
1
+ const s = (e) => {
2
+ const a = e.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((l) => l.trim()), [n] = a, c = {
3
+ text: e.label,
4
+ value: n || ""
5
5
  };
6
- if (n.length >= 2) {
7
- const [, l, o] = n, c = l.includes("=") ? { key: l.split("=")[0].trim(), value: l.split("=")[1].trim() } : null;
8
- c ? e.format = c : o || (e.fallback = l), o && (e.fallback = o);
6
+ if (a.length >= 2) {
7
+ const [, l, r] = a;
8
+ if (l.startsWith("default:")) {
9
+ let t = l.slice(8).trim();
10
+ t.startsWith('"') && t.endsWith('"') && (t = t.slice(1, -1)), c.fallback = t;
11
+ } else {
12
+ const t = l.includes("=") ? { key: l.split("=")[0].trim(), value: l.split("=")[1].trim() } : null;
13
+ t ? c.format = t : r || (c.fallback = l), r && (c.fallback = r);
14
+ }
9
15
  }
10
- return e;
11
- }, s = (t) => t.map((a) => a.format ? {
12
- label: `${a.text} | ${a.format.key}=${a.format.value}`,
13
- value: `{{${a.value}|${a.format.key}=${a.format.value}}}`
14
- } : {
15
- label: a.fallback ? `${a.text} | ${a.fallback}` : a.text,
16
- value: a.fallback ? `{{${a.value}|${a.fallback}}}` : `{{${a.value}}}`
17
- }), u = () => {
18
- var t;
19
- return ((t = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : t.getAttribute("content")) ?? "";
16
+ return c;
17
+ }, u = (e, f = !1) => e.map((a) => {
18
+ if (a.format)
19
+ return {
20
+ label: `${a.text} | ${a.format.key}=${a.format.value}`,
21
+ value: `{{${a.value}|${a.format.key}=${a.format.value}}}`
22
+ };
23
+ if (f) {
24
+ if (!a.fallback)
25
+ return {
26
+ label: a.text,
27
+ value: `{{ ${a.value} }}`
28
+ };
29
+ const c = !Number.isNaN(Number(a.fallback)) && a.fallback.trim() !== "" ? a.fallback : `"${a.fallback}"`;
30
+ return {
31
+ label: `${a.text} | ${a.fallback}`,
32
+ value: `{{ ${a.value} | default: ${c} }}`
33
+ };
34
+ }
35
+ return {
36
+ label: a.fallback ? `${a.text} | ${a.fallback}` : a.text,
37
+ value: a.fallback ? `{{${a.value}|${a.fallback}}}` : `{{${a.value}}}`
38
+ };
39
+ }), o = () => {
40
+ var e;
41
+ return ((e = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : e.getAttribute("content")) ?? "";
20
42
  };
21
43
  export {
22
- s as dynamicContentToMergeTags,
23
- u as getCsrfToken,
24
- f as mergeTagToDynamicContent
44
+ u as dynamicContentToMergeTags,
45
+ o as getCsrfToken,
46
+ s as mergeTagToDynamicContent
25
47
  };
@@ -1,70 +1,77 @@
1
- var y = Object.defineProperty;
2
- var g = (p, e, r) => e in p ? y(p, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : p[e] = r;
3
- var u = (p, e, r) => g(p, typeof e != "symbol" ? e + "" : e, r);
4
- import { useToaster as m } from "../composables/useToaster.js";
5
- class d {
1
+ var h = Object.defineProperty;
2
+ var f = (o, e, t) => e in o ? h(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var m = (o, e, t) => f(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import { useToaster as x } from "../composables/useToaster.js";
5
+ const E = /font-family\s*:[^;}"']+/gi;
6
+ class T {
6
7
  constructor(e = []) {
7
- u(this, "rules");
8
+ m(this, "rules");
8
9
  this.rules = e;
9
10
  }
10
- compile(e, r) {
11
- const l = performance.now(), t = e, o = e.length;
11
+ compile(e, t, r) {
12
+ const n = performance.now(), l = e, c = e.length;
12
13
  let s = e;
13
- const a = [];
14
- (r || this.rules).sort((n, c) => n.priority - c.priority).forEach((n) => {
15
- const c = s.length;
16
- s = this.applyRule(s, n), s.length !== c && a.push(n.id);
14
+ const i = [];
15
+ (t || this.rules).sort((p, a) => p.priority - a.priority).forEach((p) => {
16
+ const a = s.length;
17
+ s = this.applyRule(s, p), s.length !== a && i.push(p.id);
17
18
  });
18
- const i = s.length, R = o > 0 ? (o - i) / o * 100 : 0;
19
+ const u = s.length, R = c > 0 ? (c - u) / c * 100 : 0, d = new TextEncoder().encode(s).byteLength;
20
+ let y = 0;
21
+ if (r && r.name && r.family) {
22
+ const p = (s.match(E) || []).length, a = `, ${r.name}, ${r.family}`;
23
+ y = p * new TextEncoder().encode(a).byteLength;
24
+ }
25
+ const g = Math.round((d + y) / 1024);
19
26
  return {
20
- originalHtml: t,
27
+ originalHtml: l,
21
28
  compiledHtml: s,
22
- appliedRules: a,
23
- // TODO: We can use stats for monitoring in the future
29
+ appliedRules: i,
30
+ estimatedSizeKB: g,
24
31
  stats: {
25
- originalSize: o,
26
- compiledSize: i,
32
+ originalSize: c,
33
+ compiledSize: u,
27
34
  reductionPercentage: R,
28
- executionTime: performance.now() - l
35
+ executionTime: performance.now() - n
29
36
  }
30
37
  };
31
38
  }
32
- applyRule(e, r) {
39
+ applyRule(e, t) {
33
40
  try {
34
- switch (r.type) {
41
+ switch (t.type) {
35
42
  case "replace":
36
- return this.applyReplaceRule(e, r);
43
+ return this.applyReplaceRule(e, t);
37
44
  case "regex":
38
- return this.applyRegexRule(e, r);
45
+ return this.applyRegexRule(e, t);
39
46
  case "remove":
40
- return this.applyRemoveRule(e, r);
47
+ return this.applyRemoveRule(e, t);
41
48
  case "custom":
42
- return this.applyCustomRule(e, r);
49
+ return this.applyCustomRule(e, t);
43
50
  default:
44
51
  return e;
45
52
  }
46
- } catch (l) {
47
- const { handleError: t } = m();
48
- return t(l, `Failed to apply rule ${r.id}:`), e;
53
+ } catch (r) {
54
+ const { handleError: n } = x();
55
+ return n(r, `Failed to apply rule ${t.id}:`), e;
49
56
  }
50
57
  }
51
- applyReplaceRule(e, r) {
52
- const { search: l, replacement: t, replaceAll: o = !0 } = r;
53
- return o ? e.replaceAll(l, t) : e.replace(l, t);
58
+ applyReplaceRule(e, t) {
59
+ const { search: r, replacement: n, replaceAll: l = !0 } = t;
60
+ return l ? e.replaceAll(r, n) : e.replace(r, n);
54
61
  }
55
- applyRegexRule(e, r) {
56
- const { pattern: l, replacement: t, flags: o = "g" } = r, s = new RegExp(l, o);
57
- return e.replace(s, t);
62
+ applyRegexRule(e, t) {
63
+ const { pattern: r, replacement: n, flags: l = "g" } = t, c = new RegExp(r, l);
64
+ return e.replace(c, n);
58
65
  }
59
- applyRemoveRule(e, r) {
60
- return r.targets.reduce((l, t) => t instanceof RegExp ? l.replace(t, "") : l.replaceAll(t, ""), e);
66
+ applyRemoveRule(e, t) {
67
+ return t.targets.reduce((r, n) => n instanceof RegExp ? r.replace(n, "") : r.replaceAll(n, ""), e);
61
68
  }
62
- applyCustomRule(e, r) {
63
- return r.processor(e);
69
+ applyCustomRule(e, t) {
70
+ return t.processor(e);
64
71
  }
65
72
  }
66
- const A = (p = []) => new d(p);
73
+ const H = (o = []) => new T(o);
67
74
  export {
68
- d as HtmlCompilerEngine,
69
- A as createHtmlCompiler
75
+ T as HtmlCompilerEngine,
76
+ H as createHtmlCompiler
70
77
  };
@@ -0,0 +1,13 @@
1
+ const c = {
2
+ "&": "&amp;",
3
+ "<": "&lt;",
4
+ ">": "&gt;",
5
+ '"': "&quot;",
6
+ "'": "&#x27;"
7
+ };
8
+ function n(t) {
9
+ return t.replace(/[&<>"']/g, (e) => c[e]);
10
+ }
11
+ export {
12
+ n as escapeHtml
13
+ };