@designcrowd/library.brand-page 5.10.20 → 5.10.31

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 (146) hide show
  1. package/lib/src/brand-page/constants/font.constants.d.ts +4 -4
  2. package/lib/src/brand-page/models/index.d.ts +5 -0
  3. package/lib/src/brand-page/models/index.js +4 -0
  4. package/lib/src/brand-page/models/styles.model.d.ts +5 -5
  5. package/lib/src/brand-page/utils/style.util.d.ts +8 -1
  6. package/lib/src/brand-page/utils/style.util.js +58 -5
  7. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.js +2 -2
  8. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +1 -1
  9. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +1 -0
  10. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/page-content-items.d.ts +1 -1
  11. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/page-content-items.js +2 -1
  12. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +33 -0
  13. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +35 -1
  14. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +2 -2
  15. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +3 -3
  16. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +1 -0
  17. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +17 -0
  18. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +2 -2
  19. package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +19 -0
  20. package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +31 -0
  21. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +2 -0
  22. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.js +161 -0
  23. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.js +3 -3
  24. package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +1 -1
  25. package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +0 -1
  26. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +1 -1
  27. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +0 -1
  28. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +19 -0
  29. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +87 -0
  30. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +1 -1
  31. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +0 -1
  32. package/lib/src/brand-page-maker/composables/rich-text-editor/textAlign.d.ts +1 -1
  33. package/lib/src/brand-page-maker/composables/rich-text-editor/textAlign.js +0 -1
  34. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +24 -3
  35. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +214 -33
  36. package/lib/src/brand-page-maker/constants/brandpage-meta-constant.d.ts +5 -5
  37. package/lib/src/brand-page-maker/constants/index.d.ts +2 -2
  38. package/lib/src/brand-page-maker/models/button-group.model.d.ts +2 -0
  39. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +19 -2
  40. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +340 -8
  41. package/lib/src/bundled-translations-BXxQYq2i.js +119 -0
  42. package/lib/src/bundled-translations.de-DE-BXcluMZ2.js +119 -0
  43. package/lib/src/{bundled-translations.de-DE-O4sKkzBX.js → bundled-translations.de-DE-DjQFwukR.js} +1 -1
  44. package/lib/src/{bundled-translations.es-ES-C4lGaf08.js → bundled-translations.es-ES--EbGRI7e.js} +1 -1
  45. package/lib/src/bundled-translations.es-ES-DSd-wV16.js +119 -0
  46. package/lib/src/{bundled-translations.fr-FR-CIy8KjAV.js → bundled-translations.fr-FR-VtC2JYUC.js} +1 -1
  47. package/lib/src/bundled-translations.fr-FR-jKR_dxWR.js +119 -0
  48. package/lib/src/bundled-translations.pt-PT-CwvYqXXo.js +119 -0
  49. package/lib/src/{bundled-translations.pt-PT-C8EcSdyX.js → bundled-translations.pt-PT-l9cEldEo.js} +1 -1
  50. package/lib/src/bundles/bundled-translations.de-DE.json +11 -0
  51. package/lib/src/bundles/bundled-translations.es-ES.json +11 -0
  52. package/lib/src/bundles/bundled-translations.fr-FR.json +13 -2
  53. package/lib/src/bundles/bundled-translations.json +11 -0
  54. package/lib/src/bundles/bundled-translations.pt-PT.json +11 -0
  55. package/lib/src/composables/useTranslate.d.ts +64 -62
  56. package/lib/src/composables/useTranslate.js +18 -7
  57. package/lib/src/css/library.brand-page-brandCrowd.min.css +101 -75
  58. package/lib/src/css/library.brand-page-brandPage.min.css +101 -75
  59. package/lib/src/css/library.brand-page-designCom.min.css +101 -75
  60. package/lib/src/css/library.brand-page-preview.min.css +101 -75
  61. package/lib/src/index.d.ts +3 -1
  62. package/lib/src/index.mjs +30209 -27738
  63. package/lib/src/lib.js +2 -1
  64. package/lib/src/mockServiceWorker.js +91 -54
  65. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +2 -2
  66. package/lib/src/shared/content-settings/components/color-field/ColorField.mixin.d.ts +11 -0
  67. package/lib/src/shared/content-settings/components/color-field/ColorField.mixin.js +5 -0
  68. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +2 -2
  69. package/lib/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.mixin.d.ts +11 -1
  70. package/lib/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.mixin.js +4 -0
  71. package/lib/src/shared/content-settings/components/shape-field/ShapeField.mixin.d.ts +1 -1
  72. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +2 -2
  73. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +2 -2
  74. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +2 -2
  75. package/lib/src/shared/content-settings/components/text-image-field/TextImageField.mixin.d.ts +2 -2
  76. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +2 -2
  77. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +2 -2
  78. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +4 -2
  79. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.js +12 -7
  80. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +2 -2
  81. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +3 -3
  82. package/lib/src/shared/my-uploads/MyUploads.mixin.d.ts +1 -1
  83. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +1 -1
  84. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +4 -2
  85. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +4 -4
  86. package/lib/src/shared/shape-library/ShapeLibrary.mixin.d.ts +1 -1
  87. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -2
  88. package/lib/src/shared/template-settings/models.d.ts +3 -3
  89. package/package.json +6 -3
  90. package/src/brand-page/components/banner-section/BannerSection.vue +6 -0
  91. package/src/brand-page/components/sensitive-content/SensitiveContentModal.vue +28 -11
  92. package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.de-DE.json +13 -0
  93. package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.es-ES.json +13 -0
  94. package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.fr-FR.json +13 -0
  95. package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.json +13 -0
  96. package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.pt-PT.json +13 -0
  97. package/src/brand-page/components/text/Text.vue +2 -0
  98. package/src/brand-page/components/text-wrapper/TextWrapper.vue +31 -11
  99. package/src/brand-page/models/index.ts +6 -0
  100. package/src/brand-page/utils/style.util.ts +105 -5
  101. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.ts +2 -2
  102. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +1 -1
  103. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +1 -0
  104. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/page-content-items.ts +2 -0
  105. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +44 -1
  106. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.vue +1 -0
  107. package/src/brand-page-maker/components/brandpage-settings/i18n/brand-page-settings.fr-FR.json +1 -1
  108. package/src/brand-page-maker/components/google-analytics/i18n/google-analytics.fr-FR.json +1 -1
  109. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +539 -50
  110. package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +22 -0
  111. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +1 -1
  112. package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +42 -0
  113. package/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.ts +227 -0
  114. package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +1 -1
  115. package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.ts +4 -15
  116. package/src/brand-page-maker/composables/rich-text-editor/font.ts +1 -1
  117. package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +1 -1
  118. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +114 -0
  119. package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +1 -1
  120. package/src/brand-page-maker/composables/rich-text-editor/textAlign.ts +1 -1
  121. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +299 -41
  122. package/src/brand-page-maker/models/button-group.model.ts +2 -0
  123. package/src/brand-page-maker/stores/brandpage-maker/__snapshots__/brandpage-maker-store.test.ts.snap +1 -0
  124. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +418 -0
  125. package/src/brand-page-maker/utils/rich-text-editor.util.ts +470 -25
  126. package/src/bundles/bundled-translations.de-DE.json +11 -0
  127. package/src/bundles/bundled-translations.es-ES.json +11 -0
  128. package/src/bundles/bundled-translations.fr-FR.json +13 -2
  129. package/src/bundles/bundled-translations.json +11 -0
  130. package/src/bundles/bundled-translations.pt-PT.json +11 -0
  131. package/src/composables/useTranslate.ts +25 -8
  132. package/src/lib.ts +7 -1
  133. package/src/shared/content-settings/components/color-field/ColorField.mixin.ts +5 -0
  134. package/src/shared/content-settings/components/color-field/ColorField.vue +1 -1
  135. package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.mixin.ts +4 -0
  136. package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +2 -2
  137. package/src/shared/content-settings/components/text-field/TextField.vue +1 -1
  138. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +2 -2
  139. package/src/shared/content-settings/components/textarea-field/TextareaField.vue +3 -3
  140. package/src/shared/content-settings/components/url-field/UrlField.mixin.ts +15 -10
  141. package/src/shared/content-settings/components/url-field/UrlField.vue +1 -0
  142. package/lib/src/bundled-translations-DaK60m67.js +0 -117
  143. package/lib/src/bundled-translations.de-DE-848cpWPB.js +0 -117
  144. package/lib/src/bundled-translations.es-ES-CtPI5G7I.js +0 -117
  145. package/lib/src/bundled-translations.fr-FR-CTnDppmf.js +0 -117
  146. package/lib/src/bundled-translations.pt-PT-Balnne-7.js +0 -117
@@ -23,10 +23,10 @@ export declare const MAX_LINE_HEIGHT = 2.5;
23
23
  export declare const MAX_TITLE_LENGTH = 200;
24
24
  export declare const MAX_DESCRIPTION_LENGTH = 1000;
25
25
  export declare const MAX_TEXT_LENGTH = 2000;
26
- export declare const MAX_LENGTH_ERROR_MESSAGE: () => string;
27
- export declare const INVALID_URL_MESSAGE: () => string;
28
- export declare const EMPTY_TESTIMONIAL: () => string;
29
- export declare const TEXT_EMPTY: () => string;
26
+ export declare const MAX_LENGTH_ERROR_MESSAGE: () => any;
27
+ export declare const INVALID_URL_MESSAGE: () => any;
28
+ export declare const EMPTY_TESTIMONIAL: () => any;
29
+ export declare const TEXT_EMPTY: () => any;
30
30
  export declare const GOOGLE_FONT_BASE_URL = "https://fonts.googleapis.com/css2";
31
31
  export declare const GOOGLE_FONT_URL_SUFFIX = "&display=swap";
32
32
  export declare const FALLBACK_DEFAULT_LINK_COLOR = "#000000";
@@ -207,6 +207,11 @@ export declare const BUTTON_LINK_TYPE: {
207
207
  readonly tel: "tel";
208
208
  };
209
209
  export type ButtonLinkType = keyof typeof BUTTON_LINK_TYPE;
210
+ export declare const HYPERLINK_TYPE: {
211
+ readonly url: "url";
212
+ readonly page: "page";
213
+ };
214
+ export type HyperlinkType = keyof typeof HYPERLINK_TYPE;
210
215
  export declare const URL_TYPE: {
211
216
  readonly url: "url";
212
217
  readonly email: "email";
@@ -136,6 +136,10 @@ export const BUTTON_LINK_TYPE = {
136
136
  mailTo: 'mailTo',
137
137
  tel: 'tel',
138
138
  };
139
+ export const HYPERLINK_TYPE = {
140
+ url: 'url',
141
+ page: 'page',
142
+ };
139
143
  export const URL_TYPE = {
140
144
  url: 'url',
141
145
  email: 'email',
@@ -7,11 +7,11 @@ export declare const TEXT_STYLE_TYPES: {
7
7
  };
8
8
  export type TextStyleType = keyof typeof TEXT_STYLE_TYPES;
9
9
  export declare const TEXT_STYLE_TYPES_DISPLAY_NAME_MAP: () => {
10
- titles: string;
11
- headings: string;
12
- paragraphs: string;
13
- buttons: string;
14
- none: string;
10
+ titles: any;
11
+ headings: any;
12
+ paragraphs: any;
13
+ buttons: any;
14
+ none: any;
15
15
  };
16
16
  export type TextStyleDeclaration = BrandPageCssStyle & {
17
17
  textStyleType?: TextStyleType;
@@ -1,6 +1,13 @@
1
- import type { BrandPageModel, LogoTheme, FabricLogoTheme, ButtonStyles, PageModel } from '../models';
1
+ import type { BrandPageModel, LogoTheme, ThemeColor, FabricLogoTheme, ButtonStyles, PageModel } from '../models';
2
2
  import { NavigationDesktop, NavigationMobile } from '../models';
3
3
  import { PageStyles, PageHeaderMobile, PageHeaderDesktop, PageFooterMobile, PageFooterDesktop } from '../models';
4
+ /**
5
+ * @function getColorValueForCorrectCssProperty
6
+ * @param k: string
7
+ * @param colorData { rgb: 'rgb(0,255,0)', gradient: 'linear-gradient(180deg, rgb(0,0,0), rgb(255,0,0), 100%)'}
8
+ * @returns string - rgb() or linear-gradient()
9
+ */
10
+ export declare const getColorValueForCorrectCssProperty: (k: string, colorData: ThemeColor) => string;
4
11
  export declare const colorMatchCssKeyValue: (cssKey: string, cssValue: string, logoTheme: LogoTheme, applyColorWithMatchingLuminance?: {
5
12
  originalColor: string;
6
13
  }) => {
@@ -4,6 +4,7 @@ import { STYLE_THEME_KEYS } from '../constants';
4
4
  import { arrayToLinearGradient, linearGradientToArray, isColorLinearGradient, RGBAtoHex, } from '../../utils/helpers';
5
5
  import { addTransparentAlphaChannelToHex, calculateLuminanceRatio, getNewColorBasedOnTargetColorTheme, } from './color.util';
6
6
  import chroma from 'chroma-js';
7
+ import { hasRTEContent } from '../../brand-page-maker/utils';
7
8
  const MIN_LUM_RATIO = 0.3;
8
9
  const parseFabricColorToCssStyle = (fabricColor) => {
9
10
  if (fabricColor && typeof fabricColor === 'object') {
@@ -25,7 +26,7 @@ const parseFabricColorToCssStyle = (fabricColor) => {
25
26
  * @param colorData { rgb: 'rgb(0,255,0)', gradient: 'linear-gradient(180deg, rgb(0,0,0), rgb(255,0,0), 100%)'}
26
27
  * @returns string - rgb() or linear-gradient()
27
28
  */
28
- const getColorValueForCorrectCssProperty = (k, colorData) => {
29
+ export const getColorValueForCorrectCssProperty = (k, colorData) => {
29
30
  const gradientSupportedCssProperties = ['background', 'backgroundImage'];
30
31
  return colorData.gradient && gradientSupportedCssProperties.indexOf(k) > -1
31
32
  ? colorData.gradient
@@ -49,13 +50,15 @@ export const colorMatchCssKeyValue = (cssKey, cssValue, logoTheme, applyColorWit
49
50
  return { cssValue: newColor, isModified: true };
50
51
  }
51
52
  }
52
- if (cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoTextColor, 'g')) ||
53
- cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoTextMultiColor, 'g'))) {
53
+ if ((cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoTextColor, 'g')) ||
54
+ cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoTextMultiColor, 'g'))) &&
55
+ !hasRTEContent(cssValue)) {
54
56
  cssValue = getColorValueForCorrectCssProperty(cssKey, logoTheme.logoTextColor);
55
57
  return { cssValue, isModified: true };
56
58
  }
57
- else if (cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoBackgroundColor, 'g')) ||
58
- cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoBackgroundMultiColor, 'g'))) {
59
+ else if ((cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoBackgroundColor, 'g')) ||
60
+ cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoBackgroundMultiColor, 'g'))) &&
61
+ !hasRTEContent(cssValue)) {
59
62
  cssValue = getColorValueForCorrectCssProperty(cssKey, logoTheme.logoBackgroundColor);
60
63
  return { cssValue, isModified: true };
61
64
  }
@@ -196,6 +199,8 @@ const CONTENT_STYLE_PROP_NAME_SUFFIX = [
196
199
  'Color',
197
200
  'Replacements',
198
201
  ];
202
+ const RTE_ALLOWED_SECTION_TYPES = ['text', 'banner-section'];
203
+ const RTE_ALLOWED_FIELDS = ['title', 'description', 'text', 'textItems'];
199
204
  export const applyLogoThemeToContents = (logoTheme, pages) => {
200
205
  let isModified = false;
201
206
  const newPages = pages.map((page) => {
@@ -211,12 +216,60 @@ export const applyLogoThemeToContents = (logoTheme, pages) => {
211
216
  newContent[styleKey] = newStyle;
212
217
  isModified = isModified || isApplied;
213
218
  }
219
+ const rteContentKeys = RTE_ALLOWED_SECTION_TYPES.includes(content.type)
220
+ ? Object.keys(content).filter((k) => RTE_ALLOWED_FIELDS.includes(k))
221
+ : [];
222
+ for (const key of rteContentKeys) {
223
+ const { newRTEContent, isApplied } = applyLogoThemeToBrandPageRTEContentColorsRecursive(newContent[key], logoTheme, isModified);
224
+ newContent[key] = newRTEContent;
225
+ isModified = isModified || isApplied;
226
+ }
214
227
  return newContent;
215
228
  });
216
229
  return { ...page, contents: newContents };
217
230
  });
218
231
  return { pages: newPages, isModified };
219
232
  };
233
+ const applyLogoThemeToBrandPageRTEContentColorsRecursive = (content, logoTheme, isModified) => {
234
+ let isApplied = false;
235
+ let newRTEContent = {};
236
+ if (typeof content === 'string' && hasRTEContent(content)) {
237
+ newRTEContent = replaceRTEContentColors(content, logoTheme);
238
+ isApplied = true;
239
+ }
240
+ else if (Array.isArray(content)) {
241
+ newRTEContent = content.map((item) => {
242
+ const { newRTEContent: recursiveContent, isApplied: recursiveIsApplied } = applyLogoThemeToBrandPageRTEContentColorsRecursive(item, logoTheme, isModified);
243
+ isApplied = recursiveIsApplied;
244
+ return recursiveContent;
245
+ });
246
+ }
247
+ else if (typeof content === 'object') {
248
+ for (const [key, value] of Object.entries(content)) {
249
+ if (RTE_ALLOWED_FIELDS.includes(key) &&
250
+ typeof value === 'string' &&
251
+ hasRTEContent(value)) {
252
+ newRTEContent[key] = replaceRTEContentColors(value, logoTheme);
253
+ isApplied = true;
254
+ }
255
+ else {
256
+ newRTEContent[key] = value;
257
+ }
258
+ }
259
+ }
260
+ else {
261
+ newRTEContent = content;
262
+ isApplied = false;
263
+ }
264
+ return { isApplied, newRTEContent };
265
+ };
266
+ const replaceRTEContentColors = (content, logoTheme) => {
267
+ return content
268
+ .replace(new RegExp(`var\\(--${STYLE_THEME_KEYS.LogoTextColor}\\)`, 'g'), logoTheme.logoTextColor.rgb)
269
+ .replace(new RegExp(`var\\(--${STYLE_THEME_KEYS.LogoBackgroundColor}\\)`, 'g'), logoTheme.logoBackgroundColor.rgb)
270
+ .replace(new RegExp(`var\\(--${STYLE_THEME_KEYS.LogoTextMultiColor}\\)`, 'g'), logoTheme.logoTextColor.rgb)
271
+ .replace(new RegExp(`var\\(--${STYLE_THEME_KEYS.LogoBackgroundMultiColor}\\)`, 'g'), logoTheme.logoBackgroundColor.rgb);
272
+ };
220
273
  export const applyLogoThemeToBrandPageStyles = (logoTheme, pageStyles) => {
221
274
  let isModified = false;
222
275
  const newStyle = new PageStyles();
@@ -193,7 +193,7 @@ const renderKeyForForcedRerender = ref(0);
193
193
  export const Sample = (args, { globals }) => {
194
194
  InitialiseMakerStores({});
195
195
  watchEffect(async () => {
196
- await setLocaleAsync(globals.locale || 'en-US');
196
+ await setLocaleAsync(globals.locale);
197
197
  renderKeyForForcedRerender.value++;
198
198
  });
199
199
  return {
@@ -224,7 +224,7 @@ export const Sample = (args, { globals }) => {
224
224
  `,
225
225
  pinia: setupStoryPinia(),
226
226
  async beforeMount() {
227
- await setLocaleAsync(globals.locale || 'en-US');
227
+ await setLocaleAsync(globals.locale);
228
228
  this.show = true;
229
229
  },
230
230
  };
@@ -171,7 +171,7 @@ export const BRAND_SITE = {
171
171
  color: 'logo-text-color',
172
172
  fontSize: '1.5rem',
173
173
  textAlign: 'center',
174
- fontFamily: 'Nunito',
174
+ fontFamily: 'Exo 2',
175
175
  lineHeight: '2rem',
176
176
  },
177
177
  colorReplacements: [
@@ -43,6 +43,7 @@ export const textContent = {
43
43
  textSize: {},
44
44
  textStyle: {
45
45
  textAlign: DEFAULT_TEXT_ALIGN,
46
+ fontSize: '2em',
46
47
  },
47
48
  textAlignment: {},
48
49
  textColor: {},
@@ -1,2 +1,2 @@
1
- export declare const brandPageContentsSampleData: (import("../../../../brand-page").ButtonContent | import("../../../../brand-page").ProfileContent | import("../../../../brand-page").LogoContent)[];
1
+ export declare const brandPageContentsSampleData: (import("../../../../brand-page").ButtonContent | import("../../../../brand-page").ProfileContent | import("../../../../brand-page").TextContent | import("../../../../brand-page").LogoContent)[];
2
2
  export declare const brandPageContentsSampleDataStarterKit: (import("../../../../brand-page").ButtonContent | import("../../../../brand-page").ProfileContent | import("../../../../brand-page").LogoContent)[];
@@ -1,7 +1,8 @@
1
- import { logoContent, profileContent, generalLink, facebookLink, websiteLink, emailLink, phoneLink, twitterLink, instagramLink, youtubeLink, linkedinLink, pinterestLink, twitchLink, tiktokLink, } from './content-settings-items.fixture';
1
+ import { logoContent, profileContent, generalLink, facebookLink, websiteLink, emailLink, phoneLink, twitterLink, instagramLink, youtubeLink, linkedinLink, pinterestLink, twitchLink, tiktokLink, textContent, } from './content-settings-items.fixture';
2
2
  export const brandPageContentsSampleData = [
3
3
  logoContent,
4
4
  profileContent,
5
+ textContent,
5
6
  generalLink,
6
7
  websiteLink,
7
8
  emailLink,
@@ -37,6 +37,38 @@ declare const _default: import("vue").DefineComponent<{}, {
37
37
  selectedTemplateId: import("vue").ComputedRef<string | false>;
38
38
  canUseRichTextEditor: import("vue").ComputedRef<boolean>;
39
39
  isAdmin: import("vue").ComputedRef<boolean>;
40
+ logoTheme: import("vue").ComputedRef<{
41
+ logoTextColor: {
42
+ rgb: string;
43
+ gradient?: string | undefined;
44
+ 50?: string | undefined;
45
+ 100?: string | undefined;
46
+ 200?: string | undefined;
47
+ 300?: string | undefined;
48
+ 400?: string | undefined;
49
+ 500?: string | undefined;
50
+ 600?: string | undefined;
51
+ 700?: string | undefined;
52
+ 800?: string | undefined;
53
+ 900?: string | undefined;
54
+ 950?: string | undefined;
55
+ };
56
+ logoBackgroundColor: {
57
+ rgb: string;
58
+ gradient?: string | undefined;
59
+ 50?: string | undefined;
60
+ 100?: string | undefined;
61
+ 200?: string | undefined;
62
+ 300?: string | undefined;
63
+ 400?: string | undefined;
64
+ 500?: string | undefined;
65
+ 600?: string | undefined;
66
+ 700?: string | undefined;
67
+ 800?: string | undefined;
68
+ 900?: string | undefined;
69
+ 950?: string | undefined;
70
+ };
71
+ }>;
40
72
  contentSettingsStore: import("pinia").Store<"uiContentSettings", import("../../../shared/content-settings/store").ContentSettingsState, {
41
73
  contentErrorCount(): number;
42
74
  getContent(state: {
@@ -1030,6 +1062,7 @@ declare const _default: import("vue").DefineComponent<{}, {
1030
1062
  };
1031
1063
  isDraggableEnabled(): boolean;
1032
1064
  isItemSelected(): (itemIdx: any) => boolean;
1065
+ styleHtml(): string;
1033
1066
  }, {
1034
1067
  dispatchViewPortChangeEvent(): void;
1035
1068
  onDraggingStart(): void;
@@ -14,6 +14,7 @@ import debounce from 'lodash.debounce';
14
14
  import { transformToRTE } from '../../../brand-page-maker/utils';
15
15
  import { useExternalRichTextEditor } from '../../../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
16
16
  import { useUiStyleSettingsStore } from '../../../shared/style-settings/store';
17
+ import { STYLE_THEME_KEYS } from '../../../brand-page/constants';
17
18
  export default defineComponent({
18
19
  mixins: [PageMixin],
19
20
  setup() {
@@ -40,6 +41,7 @@ export default defineComponent({
40
41
  selectedTemplateId: computed(() => brandPageMakerStore.selectedTemplateId),
41
42
  canUseRichTextEditor: computed(() => brandPageMakerUserStore.features.canUseRichTextEditor),
42
43
  isAdmin: computed(() => brandPageMakerUserStore.isAdmin),
44
+ logoTheme: computed(() => uiStore.logoTheme),
43
45
  contentSettingsStore,
44
46
  brandPageMakerStore,
45
47
  brandPageContainerStore,
@@ -97,6 +99,31 @@ export default defineComponent({
97
99
  return this.isContentSelected ? item.id === this.selectedItemId : false;
98
100
  };
99
101
  },
102
+ styleHtml() {
103
+ if (!this.logoTheme) {
104
+ return '';
105
+ }
106
+ // Generate CSS variables for logo theme colors
107
+ const cssVariables = Object.entries(STYLE_THEME_KEYS)
108
+ .map(([key, value]) => {
109
+ const themeColor = key.includes('Background')
110
+ ? this.logoTheme.logoBackgroundColor
111
+ : this.logoTheme.logoTextColor;
112
+ if (themeColor?.rgb) {
113
+ return `--${value}: ${themeColor.rgb};`;
114
+ }
115
+ return '';
116
+ })
117
+ .filter(Boolean)
118
+ .join('\n ');
119
+ return cssVariables
120
+ ? `<style>
121
+ :root {
122
+ ${cssVariables}
123
+ }
124
+ </style>`
125
+ : '';
126
+ },
100
127
  },
101
128
  mounted() {
102
129
  this.dispatchViewPortChangeEvent();
@@ -180,7 +207,14 @@ export default defineComponent({
180
207
  this.isContentSelected = true;
181
208
  if ((item.type === 'banner-section' || item.type === 'text') &&
182
209
  this.canUseRichTextEditor) {
183
- transformToRTE(this.pageSettingsStore, this.externalEditor, this.styleSettingsStore, item);
210
+ let selectedItem = item;
211
+ if (this.isAdmin) {
212
+ const currentItem = this.items.find((i) => i.id === item.id);
213
+ if (currentItem) {
214
+ selectedItem = currentItem.settings.content;
215
+ }
216
+ }
217
+ transformToRTE(this.pageSettingsStore, this.externalEditor, this.styleSettingsStore, selectedItem);
184
218
  }
185
219
  if (this.selectEventDebounceHandler) {
186
220
  this.selectEventDebounceHandler();
@@ -27,7 +27,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
27
27
  backButtonLabel: {
28
28
  type: StringConstructor;
29
29
  required: false;
30
- default: () => string;
30
+ default: () => any;
31
31
  };
32
32
  isDesignCom: {
33
33
  type: BooleanConstructor;
@@ -66,7 +66,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
66
66
  backButtonLabel: {
67
67
  type: StringConstructor;
68
68
  required: false;
69
- default: () => string;
69
+ default: () => any;
70
70
  };
71
71
  isDesignCom: {
72
72
  type: BooleanConstructor;
@@ -374,9 +374,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
374
374
  duplicateActionPath(): string;
375
375
  hasSlug(): boolean;
376
376
  publishedUrl(): string | undefined;
377
- titleError(): string | undefined;
378
- descriptionError(): string | undefined;
379
- metaKeywordsError(): string | undefined;
377
+ titleError(): any;
378
+ descriptionError(): any;
379
+ metaKeywordsError(): any;
380
380
  isPublishing(): any;
381
381
  isUpdateButtonEnabled(): any;
382
382
  isDirty(): boolean;
@@ -185,6 +185,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
185
185
  scaledContainerStyle(): BrandPageCssStyle;
186
186
  innerContainerStyle(): BrandPageCssStyle;
187
187
  isPersonalisable(): boolean;
188
+ cssVariablesStyle(): Record<string, string>;
188
189
  }, {
189
190
  onOverlayClicked(): void;
190
191
  onResize(): void;
@@ -1,6 +1,7 @@
1
1
  import { computed, defineComponent } from 'vue';
2
2
  import { BRAND_PAGE_TYPES, MEDIA_SIZES, VIEWPORTS } from '../../../brand-page';
3
3
  import { applyLogoThemeToBrandPageModel, applyUserPersonalisationToBrandPageModelAsync, getBrandPageViewModelFromBrandPageModel, } from '../../../brand-page/utils';
4
+ import { STYLE_THEME_KEYS } from '../../../brand-page/constants';
4
5
  import debounce from 'lodash.debounce';
5
6
  import { MOBILE_HEIGHT, MOBILE_WIDTH } from '../../constants';
6
7
  import { useBrandPageMakerStore } from '../../stores';
@@ -128,6 +129,22 @@ export default defineComponent({
128
129
  isPersonalisable() {
129
130
  return this.template.isPersonalisable || false;
130
131
  },
132
+ cssVariablesStyle() {
133
+ if (!this.logoTheme) {
134
+ return {};
135
+ }
136
+ const cssVariables = {};
137
+ // Generate CSS variables for logo theme colors
138
+ Object.entries(STYLE_THEME_KEYS).forEach(([key, value]) => {
139
+ const themeColor = key.includes('Background')
140
+ ? this.logoTheme.logoBackgroundColor
141
+ : this.logoTheme.logoTextColor;
142
+ if (themeColor?.rgb) {
143
+ cssVariables[`--${value}`] = themeColor.rgb;
144
+ }
145
+ });
146
+ return cssVariables;
147
+ },
131
148
  },
132
149
  watch: {
133
150
  logoTheme: {
@@ -2,7 +2,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
2
2
  label: {
3
3
  type: StringConstructor;
4
4
  required: false;
5
- default: () => string;
5
+ default: () => any;
6
6
  };
7
7
  }>, {
8
8
  brandPageContainerStore: import("pinia").Store<"brandPageContainer", import("../../stores").BrandPageContainerState, {
@@ -224,7 +224,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
224
224
  label: {
225
225
  type: StringConstructor;
226
226
  required: false;
227
- default: () => string;
227
+ default: () => any;
228
228
  };
229
229
  }>> & Readonly<{}>, {
230
230
  label: string;
@@ -0,0 +1,19 @@
1
+ import type { Editor } from '@tiptap/vue-3';
2
+ import type { Ref } from 'vue';
3
+ export declare const useBubbleMenu: (editor: Editor, isHyperlinkPopupOpen?: Ref<boolean>) => {
4
+ shouldShow: ({ editor, state }: {
5
+ editor: any;
6
+ state: any;
7
+ }) => any;
8
+ tippyOptions: {
9
+ duration: number;
10
+ placement: "bottom";
11
+ interactive: boolean;
12
+ appendTo: "parent";
13
+ hideOnClick: boolean;
14
+ arrow: boolean;
15
+ offset: [number, number];
16
+ trigger: "manual";
17
+ zIndex: number;
18
+ };
19
+ };
@@ -0,0 +1,31 @@
1
+ export const useBubbleMenu = (editor, isHyperlinkPopupOpen) => {
2
+ const shouldShow = ({ editor, state }) => {
3
+ if (!editor || !state)
4
+ return false;
5
+ // Hide preview popup if the hyperlink popup is open
6
+ if (isHyperlinkPopupOpen?.value)
7
+ return false;
8
+ const { selection } = state;
9
+ // Only show bubble menu if there's a selection and it contains a link
10
+ if (!selection.empty) {
11
+ const linkAttrs = editor.getAttributes('link');
12
+ return linkAttrs.href && linkAttrs.href.trim() !== '';
13
+ }
14
+ return false;
15
+ };
16
+ const tippyOptions = {
17
+ duration: 100,
18
+ placement: 'bottom',
19
+ interactive: true,
20
+ appendTo: 'parent',
21
+ hideOnClick: false,
22
+ arrow: false,
23
+ offset: [0, 10],
24
+ trigger: 'manual',
25
+ zIndex: 10,
26
+ };
27
+ return {
28
+ shouldShow,
29
+ tippyOptions,
30
+ };
31
+ };
@@ -0,0 +1,2 @@
1
+ import { Extension } from '@tiptap/core';
2
+ export declare const AutoLink: Extension<any, any>;
@@ -0,0 +1,161 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
3
+ const LINK_COLOR = '#0097d7';
4
+ const isLinkMark = (mark) => mark.type.name === 'link';
5
+ const isUnderlineMark = (mark) => mark.type.name === 'underline';
6
+ const isTextStyleMark = (mark) => mark.type.name === 'textStyle';
7
+ const isBlueColorMark = (mark) => isTextStyleMark(mark) && mark.attrs.color === LINK_COLOR;
8
+ const hasLinkMark = (marks) => marks.some(isLinkMark);
9
+ const hasUnderlineMark = (marks) => marks.some(isUnderlineMark);
10
+ const createStylesWithoutColor = (schema, textStyleMark) => {
11
+ const { color: _color, ...otherAttrs } = textStyleMark.attrs;
12
+ return Object.keys(otherAttrs).length > 0
13
+ ? schema.marks.textStyle?.create(otherAttrs)
14
+ : null;
15
+ };
16
+ const applyDefaultLinkStyling = (tr, schema, node, pos) => {
17
+ const range = { from: pos, to: pos + node.nodeSize };
18
+ let modified = false;
19
+ const textStyleMark = node.marks.find(isTextStyleMark);
20
+ // Always apply blue color to newly created links, regardless of existing colors
21
+ const attrs = { ...textStyleMark?.attrs, color: LINK_COLOR };
22
+ const colorMark = schema.marks.textStyle?.create(attrs);
23
+ if (colorMark) {
24
+ if (textStyleMark) {
25
+ tr.removeMark(range.from, range.to, textStyleMark);
26
+ }
27
+ tr.addMark(range.from, range.to, colorMark);
28
+ modified = true;
29
+ }
30
+ // Add underline to newly detected URLs (auto-links)
31
+ // This ensures typed URLs get the same styling as manually created links
32
+ if (!hasUnderlineMark(node.marks)) {
33
+ const underlineMark = schema.marks.underline?.create();
34
+ if (underlineMark) {
35
+ tr.addMark(range.from, range.to, underlineMark);
36
+ modified = true;
37
+ }
38
+ }
39
+ return modified;
40
+ };
41
+ const removeHyperlinkStyles = (tr, schema, node, pos) => {
42
+ const range = { from: pos, to: pos + node.nodeSize };
43
+ let modified = false;
44
+ // Only remove blue color that was added for link styling
45
+ const textStyleMark = node.marks.find(isBlueColorMark);
46
+ if (textStyleMark) {
47
+ tr.removeMark(range.from, range.to, textStyleMark);
48
+ const newTextStyleMark = createStylesWithoutColor(schema, textStyleMark);
49
+ if (newTextStyleMark) {
50
+ tr.addMark(range.from, range.to, newTextStyleMark);
51
+ }
52
+ modified = true;
53
+ }
54
+ // Don't automatically remove underlines from non-link text
55
+ // Users should be able to have underlined text that's not a link
56
+ return modified;
57
+ };
58
+ export const AutoLink = Extension.create({
59
+ name: 'autoLink',
60
+ addKeyboardShortcuts() {
61
+ return {
62
+ // Handle any character input at the end of links
63
+ Backspace: () => false, // Let default behavior handle backspace
64
+ };
65
+ },
66
+ addProseMirrorPlugins() {
67
+ return [
68
+ new Plugin({
69
+ key: new PluginKey('autoLinkStyling'),
70
+ props: {
71
+ handleTextInput(view, from, to, text) {
72
+ const { state } = view;
73
+ const { selection } = state;
74
+ const { $anchor } = selection;
75
+ // Only handle when typing at a cursor position (from === to)
76
+ if (from !== to) {
77
+ return false;
78
+ }
79
+ // Check if we have link marks at cursor position
80
+ const currentMarks = $anchor.marks();
81
+ const linkMark = currentMarks.find(isLinkMark);
82
+ if (linkMark) {
83
+ // Check if we're at the end of the link
84
+ const currentPos = $anchor.pos;
85
+ const nextPos = currentPos + 1;
86
+ const hasLinkAfter = nextPos <= state.doc.content.size &&
87
+ state.doc
88
+ .resolve(Math.min(nextPos, state.doc.content.size))
89
+ .marks()
90
+ .some((mark) => isLinkMark(mark) && mark.eq(linkMark));
91
+ if (!hasLinkAfter) {
92
+ // detach the link after the attached link mark
93
+ const preservedMarks = currentMarks
94
+ .filter((mark) => {
95
+ if (isLinkMark(mark))
96
+ return false;
97
+ // Only preserve underlines if there's no blue color (manually added underlines)
98
+ // Remove underlines that were part of link styling (with blue color)
99
+ if (isUnderlineMark(mark)) {
100
+ const hasBlueColor = currentMarks.some(isBlueColorMark);
101
+ return !hasBlueColor; // Keep underline only if no blue color
102
+ }
103
+ // Remove blue color styling but preserve other text styles
104
+ if (isBlueColorMark(mark)) {
105
+ return createStylesWithoutColor(state.schema, mark);
106
+ }
107
+ return true;
108
+ })
109
+ .filter(Boolean); // Insert text with only preserved marks
110
+ let tr = state.tr;
111
+ tr = tr.setStoredMarks(preservedMarks);
112
+ tr = tr.insertText(text, from, to);
113
+ tr = tr.setMeta('autoLinkDetached', true);
114
+ view.dispatch(tr);
115
+ return true;
116
+ }
117
+ }
118
+ return false;
119
+ },
120
+ },
121
+ appendTransaction(transactions, oldState, newState) {
122
+ const tr = newState.tr;
123
+ let modified = false;
124
+ const hasDocChanges = transactions.some((transaction) => transaction.docChanged);
125
+ if (!hasDocChanges)
126
+ return null;
127
+ const wasDetached = transactions.some((transaction) => transaction.getMeta('autoLinkDetached'));
128
+ // Apply default styling to links (unless just detached)
129
+ if (!wasDetached) {
130
+ newState.doc.descendants((node, pos) => {
131
+ if (!node.isText || !node.text || !hasLinkMark(node.marks))
132
+ return;
133
+ // Check if this is a newly created link by comparing with old state
134
+ const oldNode = pos < oldState.doc.nodeSize ? oldState.doc.nodeAt(pos) : null;
135
+ const wasAlreadyLink = oldNode && hasLinkMark(oldNode.marks);
136
+ // Only apply full styling (including underline) to newly created links
137
+ if (wasAlreadyLink === false) {
138
+ if (applyDefaultLinkStyling(tr, newState.schema, node, pos)) {
139
+ modified = true;
140
+ }
141
+ }
142
+ else {
143
+ // For existing links, preserve their current color and underline choices
144
+ // Don't override user customizations on existing links
145
+ }
146
+ });
147
+ }
148
+ // Clean up hyperlink styling from text without link marks
149
+ newState.doc.descendants((node, pos) => {
150
+ if (!node.isText || !node.text || hasLinkMark(node.marks))
151
+ return;
152
+ if (removeHyperlinkStyles(tr, newState.schema, node, pos)) {
153
+ modified = true;
154
+ }
155
+ });
156
+ return modified ? tr : null;
157
+ },
158
+ }),
159
+ ];
160
+ },
161
+ });