@designcrowd/library.brand-page 6.1.1-json-prereq-3 → 6.1.1

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 (216) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-hj_ievMc.js → CreatedOnBrandCrowd-de-de-B5B5ThJ6.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-jAOSpfCw.js → CreatedOnBrandCrowd-en-us-a48CaORy.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-DZMVc-y3.js → CreatedOnBrandCrowd-es-es-xpuZ317-.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-DvB54H38.js → CreatedOnBrandCrowd-fr-ca-V-iUMArW.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-DvB54H38.js → CreatedOnBrandCrowd-fr-fr-V-iUMArW.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-bf-x1xhi.js → CreatedOnBrandCrowd-pt-br-DZ0NKSAy.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-bf-x1xhi.js → CreatedOnBrandCrowd-pt-pt-DZ0NKSAy.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-B-NY1B44.js → CreatedOnDcom-de-de-_950cgGp.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-Cd4C6KQf.js → CreatedOnDcom-en-us-DogKzH-g.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-DONlsQsm.js → CreatedOnDcom-es-es-CmGM3IPX.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-Dsv3FRpZ.js → CreatedOnDcom-fr-ca-BonEDkWZ.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DOgyvY5C.js → CreatedOnDcom-fr-fr-DQHtKrd_.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-DX66MhJS.js → CreatedOnDcom-pt-br-CtYJSBjs.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-COe2G0bU.js → CreatedOnDcom-pt-pt-DoO9r4lA.js} +1 -1
  15. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +7 -8
  16. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +6 -4
  17. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +1 -0
  18. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +4 -1
  19. package/lib/src/brand-page/components/payment/Payment.mixin.js +4 -3
  20. package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +1 -0
  21. package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +1 -0
  22. package/lib/src/brand-page/components/payment/request-payment/RequestPayment.mixin.d.ts +1 -0
  23. package/lib/src/brand-page/components/payment/request-payment/RequestPayment.mixin.js +4 -1
  24. package/lib/src/brand-page/composables/consent.composable.d.ts +2 -0
  25. package/lib/src/brand-page/composables/consent.composable.js +9 -3
  26. package/lib/src/brand-page/models/brand-page-context.model.d.ts +7 -0
  27. package/lib/src/brand-page/models/index.d.ts +26 -34
  28. package/lib/src/brand-page/utils/context.util.d.ts +8 -0
  29. package/lib/src/brand-page/utils/context.util.js +8 -0
  30. package/lib/src/brand-page/utils/migration.util.js +0 -11
  31. package/lib/src/brand-page/utils/text.util.d.ts +1 -13
  32. package/lib/src/brand-page/utils/text.util.js +0 -64
  33. package/lib/src/brand-page/utils/vcard.util.js +4 -4
  34. package/lib/src/brand-page/utils/view-model.util.d.ts +0 -1
  35. package/lib/src/brand-page/utils/view-model.util.js +20 -68
  36. package/lib/src/brand-page/view-models.d.ts +3 -3
  37. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -1
  38. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +51 -18
  39. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
  40. package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +9 -2
  41. package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +10 -6
  42. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.d.ts +20 -0
  43. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.js +44 -0
  44. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.d.ts +27 -0
  45. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.js +44 -0
  46. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
  47. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +103 -24
  48. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +8 -0
  49. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +9 -3
  50. package/lib/src/brand-page-maker/stores/ui/ui-store.d.ts +1 -1
  51. package/lib/src/brand-page-maker/utils/index.d.ts +0 -2
  52. package/lib/src/brand-page-maker/utils/index.js +0 -2
  53. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +5 -28
  54. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +5 -48
  55. package/lib/src/brand-page-maker/validators/field.validator.js +2 -10
  56. package/lib/src/clients/models.d.ts +2 -0
  57. package/lib/src/css/library.brand-page-brandCrowd.min.css +99 -102
  58. package/lib/src/css/library.brand-page-brandPage.min.css +99 -102
  59. package/lib/src/css/library.brand-page-designCom.min.css +99 -102
  60. package/lib/src/css/library.brand-page-preview.min.css +99 -102
  61. package/lib/src/index.d.ts +1 -1
  62. package/lib/src/index.mjs +219 -221
  63. package/lib/src/{lib-scDtk-Pi.js → lib-DtalJKI3.js} +72445 -75920
  64. package/lib/src/lib.js +1 -2
  65. package/lib/src/metadata-builder/ai-metadata-executor.d.ts +1 -0
  66. package/lib/src/metadata-builder/ai-metadata-executor.js +19 -0
  67. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -2
  68. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -2
  69. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -2
  70. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -3
  71. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -2
  72. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -1
  73. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -1
  74. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -3
  75. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -2
  76. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -1
  77. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +11 -15
  78. package/lib/src/metadata-builder/builders/update-content-text-builder.d.ts +17 -0
  79. package/lib/src/metadata-builder/builders/update-content-text-builder.js +103 -0
  80. package/lib/src/metadata-builder/builders/update-content-text-style-builder.d.ts +16 -0
  81. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +216 -0
  82. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +13 -11
  83. package/lib/src/metadata-builder/helpers/rte.helpers.js +73 -14
  84. package/lib/src/metadata-builder/metadata-executor.js +4 -0
  85. package/lib/src/metadata-builder/models.d.ts +2 -0
  86. package/lib/src/metadata-builder/models.js +2 -0
  87. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +19 -0
  88. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +4 -0
  89. package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +8 -7
  90. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +52 -21
  91. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +1 -1
  92. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +10 -35
  93. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +1 -1
  94. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +3 -12
  95. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +1 -1
  96. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +1 -1
  97. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +2 -3
  98. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +3 -10
  99. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +1 -1
  100. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
  101. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -4
  102. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +1 -1
  103. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +1 -1
  104. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +1 -1
  105. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +1 -1
  106. package/lib/src/shared/logo-versions/LogoVersions.mixin.d.ts +1 -1
  107. package/lib/src/shared/my-designs/MyDesigns.mixin.d.ts +1 -1
  108. package/lib/src/shared/my-uploads/MyMedia.mixin.d.ts +1 -1
  109. package/lib/src/shared/my-uploads/MyUploads.mixin.d.ts +1 -1
  110. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +1 -1
  111. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +1 -1
  112. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +1 -1
  113. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +1 -1
  114. package/lib/src/shared/template-settings/store/template-settings-store.d.ts +2 -0
  115. package/lib/src/shared/template-settings/store/template-settings-store.js +72 -24
  116. package/lib/src/shared/unsplash-library/UnsplashLibrary.mixin.d.ts +1 -1
  117. package/lib/src/utils/minify-brand-page-metadata.js +1 -4
  118. package/package.json +15 -17
  119. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +9 -7
  120. package/src/brand-page/components/cookie-consent/CookieConsent.vue +1 -0
  121. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +8 -3
  122. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +5 -1
  123. package/src/brand-page/components/page-footer/PageFooter.mixin.ts +4 -1
  124. package/src/brand-page/components/page-footer/PageFooter.vue +1 -1
  125. package/src/brand-page/components/payment/Payment.mixin.ts +4 -3
  126. package/src/brand-page/components/payment/request-payment/RequestPayment.mixin.ts +8 -1
  127. package/src/brand-page/components/payment/request-payment/RequestPayment.vue +1 -1
  128. package/src/brand-page/components/save-contact/SaveContactWidget.vue +2 -1
  129. package/src/brand-page/components/shop/Shop.vue +6 -3
  130. package/src/brand-page/components/social-links/SocialLinks.vue +5 -2
  131. package/src/brand-page/components/text-wrapper/TextWrapper.vue +6 -17
  132. package/src/brand-page/composables/consent.composable.ts +18 -4
  133. package/src/brand-page/models/brand-page-context.model.ts +7 -0
  134. package/src/brand-page/models/index.ts +26 -35
  135. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
  136. package/src/brand-page/utils/context.util.test.ts +43 -0
  137. package/src/brand-page/utils/context.util.ts +10 -0
  138. package/src/brand-page/utils/migration.util.ts +0 -12
  139. package/src/brand-page/utils/style.util.test.ts +0 -51
  140. package/src/brand-page/utils/text.util.ts +4 -83
  141. package/src/brand-page/utils/vcard.util.ts +4 -6
  142. package/src/brand-page/utils/view-model.util.ts +26 -94
  143. package/src/brand-page/view-models.ts +2 -3
  144. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +4 -5
  145. package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.test.ts +135 -0
  146. package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +62 -21
  147. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +1 -0
  148. package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +10 -6
  149. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.ts +73 -0
  150. package/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.ts +85 -0
  151. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +111 -27
  152. package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +9 -0
  153. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +11 -3
  154. package/src/brand-page-maker/stores/ui/ui-store.ts +1 -1
  155. package/src/brand-page-maker/utils/index.ts +0 -2
  156. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +3 -37
  157. package/src/brand-page-maker/utils/rich-text-editor.util.ts +11 -66
  158. package/src/brand-page-maker/validators/field.validator.ts +2 -10
  159. package/src/clients/models.ts +3 -0
  160. package/src/lib.ts +1 -9
  161. package/src/metadata-builder/ai-metadata-executor.ts +26 -0
  162. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +3 -2
  163. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +3 -2
  164. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -2
  165. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +4 -3
  166. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +3 -2
  167. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +2 -1
  168. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +2 -1
  169. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +6 -3
  170. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +3 -2
  171. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +2 -1
  172. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +13 -19
  173. package/src/metadata-builder/builders/update-content-text-builder.ts +148 -0
  174. package/src/metadata-builder/builders/update-content-text-style-builder.ts +352 -0
  175. package/src/metadata-builder/helpers/rte.helpers.ts +101 -15
  176. package/src/metadata-builder/metadata-executor.ts +5 -0
  177. package/src/metadata-builder/models.ts +3 -0
  178. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +27 -0
  179. package/src/metadata-builder/sanitizers/rte-schema-check.ts +53 -24
  180. package/src/shared/content-settings/components/GenericTextInput.mixin.ts +11 -42
  181. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +3 -16
  182. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +4 -13
  183. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +4 -6
  184. package/src/shared/content-settings/components/text-image-field/TextImageField.vue +3 -6
  185. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -6
  186. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +1 -1
  187. package/src/shared/template-settings/store/template-settings-store.ts +93 -27
  188. package/src/utils/minify-brand-page-metadata.ts +1 -4
  189. package/lib/src/brand-page/utils/migration/migration-20.d.ts +0 -2
  190. package/lib/src/brand-page/utils/migration/migration-20.js +0 -66
  191. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +0 -22
  192. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +0 -22
  193. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.d.ts +0 -14
  194. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.js +0 -39
  195. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  196. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +0 -117
  197. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
  198. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -95
  199. package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +0 -6
  200. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +0 -156
  201. package/src/brand-page/utils/migration/migration-20.server.test.ts +0 -125
  202. package/src/brand-page/utils/migration/migration-20.test.ts +0 -72
  203. package/src/brand-page/utils/migration/migration-20.ts +0 -87
  204. package/src/brand-page/utils/text.util.test.ts +0 -106
  205. package/src/brand-page/utils/view-model.pageid-rte.test.ts +0 -104
  206. package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +0 -23
  207. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +0 -52
  208. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.ts +0 -42
  209. package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +0 -162
  210. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +0 -202
  211. package/src/brand-page-maker/utils/rte-features.test.ts +0 -378
  212. package/src/brand-page-maker/utils/rte-render-parity.test.ts +0 -164
  213. package/src/brand-page-maker/utils/rte-render.util.ts +0 -165
  214. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +0 -172
  215. package/src/brand-page-maker/utils/rte-sanitize.util.ts +0 -192
  216. package/src/brand-page-maker/validators/field.validator.test.ts +0 -55
@@ -12,6 +12,7 @@ import {
12
12
  getMessageValidationError,
13
13
  getNameValidationError,
14
14
  getPhoneValidationError,
15
+ isPreviewMode,
15
16
  } from '@brand-page/utils';
16
17
  import { isDecorativeButtonStyle } from '../../utils/button.util';
17
18
  import brandPageClient from '../../clients/brand-page.client';
@@ -32,7 +33,7 @@ import {
32
33
  mutedTextForBackground,
33
34
  backgroundColorFromStyle,
34
35
  } from '@brand-page/utils';
35
- import { hasRTEContent, getPlainTextFromRTE } from '@brand-page-maker/utils';
36
+ import { hasRTEContent } from '@brand-page-maker/utils';
36
37
  import { useReCaptcha } from '../../composables/recaptcha.composable';
37
38
 
38
39
  export interface FieldValue {
@@ -180,10 +181,7 @@ export default defineComponent({
180
181
  },
181
182
 
182
183
  title(): string {
183
- // BP-5787: title may be RTE JSON (not a string), so `.trim()` would
184
- // throw — read the visible text via getPlainTextFromRTE to decide
185
- // whether to fall back to the default.
186
- return getPlainTextFromRTE(this.viewModel.title)
184
+ return this.viewModel.title && this.viewModel.title.trim() !== ''
187
185
  ? this.viewModel.title
188
186
  : 'Contact Us';
189
187
  },
@@ -265,7 +263,11 @@ export default defineComponent({
265
263
  }));
266
264
  },
267
265
  mounted(): void {
268
- if (this.context?.recaptchaSiteKey && !this.isPreview && this.recaptcha) {
266
+ if (
267
+ this.context?.recaptchaSiteKey &&
268
+ !isPreviewMode(this.context) &&
269
+ this.recaptcha
270
+ ) {
269
271
  this.recaptcha.initialise({ siteKey: this.context.recaptchaSiteKey });
270
272
  }
271
273
  },
@@ -277,7 +279,7 @@ export default defineComponent({
277
279
  return;
278
280
  }
279
281
 
280
- if (this.isPreview || !this.context.brandPageToken) {
282
+ if (isPreviewMode(this.context) || !this.context.brandPageToken) {
281
283
  if (
282
284
  process.env.NODE_ENV !== 'production' &&
283
285
  !this.context.brandPageSlug
@@ -21,6 +21,7 @@ watch(
21
21
  <div
22
22
  v-if="isEnabled"
23
23
  id="cookie-consent-modal"
24
+ data-component="cookie-consent"
24
25
  class="c-container tw-fixed tw-bottom-0 tw-left-0 tw-right-0 tw-z-50 tw-p-6 tw-flex tw-gap-4 tw-justify-between tw-flex-col tw-bg-white tw-items-center"
25
26
  >
26
27
  <p class="c-text tw-font-sans tw-m-0 tw-text-grayscale-800">
@@ -5,6 +5,7 @@ import brandPageClient from '../../clients/brand-page.client';
5
5
  import {
6
6
  getEmailValidationError,
7
7
  contentPaddingStyle as toContentPaddingStyle,
8
+ isPreviewMode,
8
9
  mutedTextForBackground,
9
10
  backgroundColorFromStyle,
10
11
  } from '@brand-page/utils';
@@ -61,7 +62,11 @@ export default defineComponent({
61
62
  mounted() {
62
63
  this.show = true;
63
64
 
64
- if (this.context?.recaptchaSiteKey && !this.isPreview && this.recaptcha) {
65
+ if (
66
+ this.context?.recaptchaSiteKey &&
67
+ !isPreviewMode(this.context) &&
68
+ this.recaptcha
69
+ ) {
65
70
  this.recaptcha.initialise({ siteKey: this.context.recaptchaSiteKey });
66
71
  }
67
72
  },
@@ -138,7 +143,7 @@ export default defineComponent({
138
143
  isFormDisabled(): boolean {
139
144
  return (
140
145
  this.hasFormError ||
141
- this.isPreview ||
146
+ isPreviewMode(this.context) ||
142
147
  !this.brandPageToken ||
143
148
  this.isSubmitting
144
149
  );
@@ -166,7 +171,7 @@ export default defineComponent({
166
171
  return;
167
172
  }
168
173
 
169
- if (this.isPreview || !this.brandPageToken) {
174
+ if (isPreviewMode(this.context) || !this.brandPageToken) {
170
175
  return;
171
176
  }
172
177
 
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <div ref="containerRef" class="tw-flex tw-items-center tw-gap-2">
2
+ <div
3
+ ref="containerRef"
4
+ data-component="navigation-carousel"
5
+ class="tw-flex tw-items-center tw-gap-2"
6
+ >
3
7
  <div
4
8
  :class="[
5
9
  'tw-flex-shrink-0',
@@ -2,7 +2,7 @@ import { defineComponent } from 'vue';
2
2
  import type { PageFooterViewModel } from '@brand-page/view-models';
3
3
  import type { PropType } from 'vue';
4
4
  import type { BrandPageContext } from '@brand-page/models';
5
- import { getRenderText } from '@brand-page/utils';
5
+ import { getRenderText, isPreviewMode } from '@brand-page/utils';
6
6
  import { FOOTER_DISPLAY } from '../../constants';
7
7
 
8
8
  export default defineComponent({
@@ -27,6 +27,9 @@ export default defineComponent({
27
27
  },
28
28
  emits: ['on-logo-click', 'footer-container-click'],
29
29
  computed: {
30
+ isInPreviewMode(): boolean {
31
+ return isPreviewMode(this.context);
32
+ },
30
33
  containerStyle(): BrandPageCssStyle {
31
34
  return this.viewModel.backgroundStyle;
32
35
  },
@@ -46,7 +46,7 @@
46
46
  :icon-style="socialLinksIconStyle"
47
47
  :is-stack-layout-on-mobile="false"
48
48
  :links="viewModel.socialLinks"
49
- :is-preview="context.isPreview"
49
+ :is-preview="isInPreviewMode"
50
50
  :context="context"
51
51
  />
52
52
  <!-- end social links -->
@@ -18,6 +18,7 @@ import type {
18
18
  SupportMeViewModel,
19
19
  } from '@brand-page/view-models';
20
20
  import raygunUtil from '@brand-page/utils/raygun.util';
21
+ import { isPreviewMode } from '@brand-page/utils';
21
22
  import { paymentTr } from '@src/composables/useTranslate';
22
23
 
23
24
  const DEFAULT_PAYMENT_SUCCESS_MESSAGE = paymentTr(
@@ -99,11 +100,11 @@ export default defineComponent({
99
100
  },
100
101
 
101
102
  canMakePayment(): boolean {
102
- return !this.context.isPreview && this.isPaymentConfigActive;
103
+ return !isPreviewMode(this.context) && this.isPaymentConfigActive;
103
104
  },
104
105
 
105
106
  showPaymentBlock(): boolean {
106
- return this.context.isPreview || this.isPaymentConfigActive;
107
+ return isPreviewMode(this.context) || this.isPaymentConfigActive;
107
108
  },
108
109
 
109
110
  paymentOptions(): PaymentOption[] {
@@ -214,7 +215,7 @@ export default defineComponent({
214
215
  ? paymentState.PaymentOptionSelection
215
216
  : paymentState.IncompleteConfig;
216
217
 
217
- if (this.context.isPreview || !paymentConfigId) {
218
+ if (isPreviewMode(this.context) || !paymentConfigId) {
218
219
  return;
219
220
  }
220
221
 
@@ -14,7 +14,10 @@ import type { RequestPaymentViewModel } from '../../../view-models';
14
14
  import type { PaymentRequestDetails } from '../Payment.mixin';
15
15
  import { DEFAULT_CURRENCY_SYMBOL } from '../../../constants';
16
16
  import { addOpacityToHex } from '../../../utils/color.util';
17
- import { contentPaddingStyle as toContentPaddingStyle } from '../../../utils';
17
+ import {
18
+ contentPaddingStyle as toContentPaddingStyle,
19
+ isPreviewMode,
20
+ } from '../../../utils';
18
21
  import { RGBAtoHex } from '@utils/helpers';
19
22
 
20
23
  const MAX_CUSTOM_REQUEST_CHARS = 500;
@@ -43,6 +46,10 @@ export default defineComponent({
43
46
  };
44
47
  },
45
48
  computed: {
49
+ isInPreviewMode(): boolean {
50
+ return isPreviewMode(this.context);
51
+ },
52
+
46
53
  contentPaddingStyle(): { paddingTop: string; paddingBottom: string } {
47
54
  return toContentPaddingStyle(this.viewModel);
48
55
  },
@@ -51,7 +51,7 @@
51
51
  <div
52
52
  v-if="
53
53
  !isTextDisplayStyle &&
54
- (paymentOption.imageUrl || context.isPreview)
54
+ (paymentOption.imageUrl || isInPreviewMode)
55
55
  "
56
56
  class="tw-rounded tw-overflow-hidden tw-shrink-0"
57
57
  :class="{
@@ -51,6 +51,7 @@ import {
51
51
  getCurrentLocale,
52
52
  } from '@src/composables/useTranslate';
53
53
  import { hasProfileContent, saveContact } from '@brand-page/utils/vcard.util';
54
+ import { isPreviewMode } from '@brand-page/utils';
54
55
  import { useConsent } from '../../composables/consent.composable';
55
56
  import PopupCard from './popup-card/PopupCard.vue';
56
57
  import Button from '../button/Button.vue';
@@ -185,7 +186,7 @@ const url = computed((): string => {
185
186
  }
186
187
 
187
188
  return localisedRouteStore.getBuilderLandingPageByTypeUrl(
188
- props.context.isPreview,
189
+ isPreviewMode(props.context),
189
190
  props.context.brandPageType,
190
191
  props.context.isDesignCom,
191
192
  getCurrentLocale(),
@@ -148,7 +148,10 @@ import brandPageClient from '../../clients/brand-page.client';
148
148
  import raygunUtil from '@brand-page/utils/raygun.util';
149
149
  import { shopTr } from '@src/composables/useTranslate';
150
150
  import { useShopConfigStore } from '@shared/ecommerce-settings/store/shop-settings-store';
151
- import { contentPaddingStyle as toContentPaddingStyle } from '@brand-page/utils';
151
+ import {
152
+ contentPaddingStyle as toContentPaddingStyle,
153
+ isPreviewMode,
154
+ } from '@brand-page/utils';
152
155
 
153
156
  const props = withDefaults(
154
157
  defineProps<{
@@ -166,13 +169,13 @@ const cart = computed(() => cartSettingsStore.cartItems);
166
169
  const PAYMENT_CONFIG_ACTIVE = 'Active';
167
170
 
168
171
  const shouldShowContainer = computed(() => {
169
- return props.context.isPreview || data.isActivePaymentProvider;
172
+ return isPreviewMode(props.context) || data.isActivePaymentProvider;
170
173
  });
171
174
 
172
175
  const checkPaymentConfigStatus = async () => {
173
176
  const paymentConfigId = props.viewModel.shopPaymentConfig.paymentConfig?.id;
174
177
 
175
- if (props.context.isPreview || !paymentConfigId) {
178
+ if (isPreviewMode(props.context) || !paymentConfigId) {
176
179
  return;
177
180
  }
178
181
 
@@ -33,7 +33,10 @@ import TextWrapper from '../text-wrapper/TextWrapper.vue';
33
33
  import type { SocialLinksViewModel } from 'src/brand-page/view-models';
34
34
  import { SOCIAL_LINKS_ICON_DISPLAY_STYLES } from '@brand-page/models';
35
35
  import type { BrandPageContext, LinksItem } from '@brand-page/models';
36
- import { contentPaddingStyle as toContentPaddingStyle } from '@brand-page/utils';
36
+ import {
37
+ contentPaddingStyle as toContentPaddingStyle,
38
+ isPreviewMode,
39
+ } from '@brand-page/utils';
37
40
  import { computed } from 'vue';
38
41
 
39
42
  const props = withDefaults(
@@ -87,7 +90,7 @@ const id = computed((): string => {
87
90
  });
88
91
 
89
92
  const isPreview = computed((): boolean => {
90
- return props.context.isPreview;
93
+ return isPreviewMode(props.context);
91
94
  });
92
95
 
93
96
  const links = computed((): LinksItem[] => {
@@ -21,13 +21,7 @@
21
21
  </div>
22
22
  </template>
23
23
  <script setup lang="ts">
24
- import {
25
- hasRTEContent,
26
- getPlainTextFromRTE,
27
- renderRteToHtml,
28
- isTiptapDocument,
29
- type RichTextValue,
30
- } from '@brand-page-maker/utils';
24
+ import { hasRTEContent, getPlainTextFromRTE } from '@brand-page-maker/utils';
31
25
  import {
32
26
  type FluidTextData,
33
27
  type TextStyleDeclaration,
@@ -43,8 +37,7 @@ import {
43
37
 
44
38
  interface Props {
45
39
  textStyle: TextStyleDeclaration | undefined;
46
- // BP-5787: an RTE field is a legacy inline-HTML string or a Tiptap JSON doc.
47
- text: RichTextValue;
40
+ text: string;
48
41
  element?: string;
49
42
  slug?: string;
50
43
  }
@@ -86,20 +79,16 @@ const textStyleRTE = computed(() => {
86
79
  };
87
80
  });
88
81
 
89
- // Render either form (legacy HTML string or Tiptap JSON) to final HTML.
90
- // For a string this returns it unchanged, so the legacy path is unaffected.
91
- const renderedHtml = computed(() => renderRteToHtml(props.text));
92
-
93
82
  const isRTEContent = computed(() => {
94
- return isTiptapDocument(props.text) || hasRTEContent(renderedHtml.value);
83
+ return hasRTEContent(props.text);
95
84
  });
96
85
 
97
86
  const sanitizeText = computed(() => {
98
- if (isRTEContent.value && !getPlainTextFromRTE(renderedHtml.value)) {
87
+ if (isRTEContent.value && !getPlainTextFromRTE(props.text)) {
99
88
  return '';
100
89
  }
101
90
 
102
- return renderedHtml.value;
91
+ return props.text;
103
92
  });
104
93
 
105
94
  const fontSize = computed<any>(() => props.textStyle.fontSize);
@@ -171,7 +160,7 @@ const applyScale = () => {
171
160
  }
172
161
 
173
162
  const fontSizeMatchInRTEText = [
174
- ...renderedHtml.value.matchAll(
163
+ ...props.text.matchAll(
175
164
  /style="(?:[^"]*?)\bfont-size\s*:\s*(?<fontSize>[^;"']+)[^"]*?"/gm,
176
165
  ),
177
166
  ].map((x) => parseFloat(x.groups?.fontSize || '1em'));
@@ -38,26 +38,34 @@ type Store = {
38
38
  updateConsent: (c: ConsentType) => void;
39
39
  featureEnabled: boolean;
40
40
  showConsentModal: boolean;
41
+ /** When false, consent is not read from / written to localStorage — used in
42
+ * preview so the modal re-shows on every refresh. */
43
+ persist: boolean;
41
44
  };
42
45
 
43
46
  const store = reactive<Store>({
44
47
  consent: undefined,
45
48
  featureEnabled: false,
46
49
  showConsentModal: false,
50
+ persist: true,
47
51
  updateConsent(c) {
48
52
  this.consent = c;
49
53
  },
50
54
  });
51
55
 
52
56
  export const useConsent = () => {
53
- const initialise = (options: { featureEnabled: boolean }): ConsentType => {
57
+ const initialise = (options: {
58
+ featureEnabled: boolean;
59
+ persist?: boolean;
60
+ }): ConsentType => {
54
61
  if (!options.featureEnabled) {
55
62
  return undefined;
56
63
  }
57
64
 
58
65
  store.featureEnabled = options.featureEnabled;
66
+ store.persist = options.persist ?? true;
59
67
 
60
- store.consent = getStoredConsent();
68
+ store.consent = store.persist ? getStoredConsent() : undefined;
61
69
 
62
70
  store.showConsentModal =
63
71
  options.featureEnabled && !accepted.value && !declined.value;
@@ -74,14 +82,20 @@ export const useConsent = () => {
74
82
  );
75
83
 
76
84
  const grant = (cb?: () => unknown) => {
77
- storeConsent('granted');
85
+ if (store.persist) {
86
+ storeConsent('granted');
87
+ }
88
+
78
89
  store.updateConsent('granted');
79
90
  store.showConsentModal = store.featureEnabled && !accepted.value;
80
91
  cb && cb();
81
92
  };
82
93
 
83
94
  const deny = (cb?: () => unknown) => {
84
- storeConsent('denied');
95
+ if (store.persist) {
96
+ storeConsent('denied');
97
+ }
98
+
85
99
  store.updateConsent('denied');
86
100
  store.showConsentModal = false;
87
101
  cb && cb();
@@ -67,6 +67,13 @@ export type MediaSizes = keyof typeof MEDIA_SIZES;
67
67
  export interface BrandPageContext {
68
68
  isTemplate: boolean;
69
69
  isPreview: boolean;
70
+ /**
71
+ * Rendered as a customer-facing live preview (safe/inert actions, no
72
+ * watermark, ephemeral consent). Distinct from the editor `isPreview`, which
73
+ * also drives editor/thumbnail-only behaviour. Use `isPreviewMode()` to gate
74
+ * inert-action behaviour that applies to both.
75
+ */
76
+ isLivePreview?: boolean;
70
77
  /** @deprecated should be used on maker only */
71
78
  isMobile?: boolean;
72
79
  isDesignCom: boolean;
@@ -30,15 +30,6 @@ import type { LogoImageModel, LogoTemplateImageModel } from './logo.model';
30
30
  import cloneDeep from 'lodash.clonedeep';
31
31
  import * as uuid from 'uuid';
32
32
  import type { BrandPagePaymentConfig } from './payment.model';
33
- import type { JSONContent } from '@tiptap/vue-3';
34
-
35
- /**
36
- * BP-5787 — a rich-text field is either a legacy inline-HTML string or a
37
- * Tiptap JSON document. Typing RTE content fields as RichTextValue (instead of
38
- * `string`) forces every consumer to handle both forms — surfacing at compile
39
- * time any code that assumes a plain string (e.g. `.replace`, `.length`).
40
- */
41
- export type RichTextValue = string | JSONContent;
42
33
 
43
34
  export * from './brand-page-context.model';
44
35
  export * from './payment.model';
@@ -289,7 +280,7 @@ export interface TextContent extends Content {
289
280
  /**
290
281
  * For BrandPage/BrandContact only
291
282
  */
292
- text: RichTextValue;
283
+ text: string;
293
284
  /**
294
285
  * For BrandSite
295
286
  */
@@ -313,9 +304,9 @@ export interface TextContent extends Content {
313
304
 
314
305
  export interface ProfileContent extends Content {
315
306
  avatarImageUrl: string;
316
- name: RichTextValue;
317
- title: RichTextValue;
318
- description: RichTextValue;
307
+ name: string;
308
+ title: string;
309
+ description: string;
319
310
  backgroundColor: BrandPageCssStyle;
320
311
  colorReplacements: ColorReplacement[];
321
312
  mediaType?: string;
@@ -336,7 +327,7 @@ export interface MapContent extends Content {
336
327
 
337
328
  export interface MailingListContent extends Content {
338
329
  acceptedFields?: 'emailOnly' | 'nameAndEmail';
339
- title: RichTextValue;
330
+ title: string;
340
331
  buttonText: string;
341
332
  titleStyle: TextStyleDeclaration;
342
333
  buttonTextStyle: TextStyleDeclaration;
@@ -396,10 +387,10 @@ export interface FormField {
396
387
  export interface ContactFormContent extends Content {
397
388
  type: 'contact-form';
398
389
  displayStyle: string;
399
- title: RichTextValue;
400
- description: RichTextValue;
390
+ title: string;
391
+ description: string;
401
392
  buttonText: string;
402
- successMessage: RichTextValue;
393
+ successMessage: string;
403
394
  fields: FormField[];
404
395
  responseEmail: string;
405
396
  imageUrl?: string;
@@ -419,8 +410,8 @@ export interface ContactFormContent extends Content {
419
410
  export interface BannerSectionContent extends Content {
420
411
  type: 'banner-section';
421
412
  imageUrl: string;
422
- title: RichTextValue;
423
- description: RichTextValue;
413
+ title: string;
414
+ description: string;
424
415
  buttonText: string | false;
425
416
  url: string;
426
417
  email?: string;
@@ -450,8 +441,8 @@ export const MEDIA_TYPES = {
450
441
  export type MediaType = keyof typeof MEDIA_TYPES;
451
442
 
452
443
  export interface TextMediaItem extends ImageItem {
453
- title: RichTextValue;
454
- paragraph: RichTextValue;
444
+ title: string;
445
+ paragraph: string;
455
446
  itemsId: number;
456
447
 
457
448
  buttonText?: string | false;
@@ -475,8 +466,8 @@ export interface TextShapeItem extends TextMediaItem {
475
466
  export interface ShapeItem extends ImageItem {
476
467
  colorReplacements: ColorReplacement[];
477
468
  mediaType: MediaType;
478
- title?: RichTextValue;
479
- paragraph?: RichTextValue;
469
+ title?: string;
470
+ paragraph?: string;
480
471
 
481
472
  // overrides for personalisation
482
473
  titleOverride?: string;
@@ -487,9 +478,9 @@ export interface TestimonialItems {
487
478
  /** Stable per-item identifier. See ImageItem.id. */
488
479
  id: string;
489
480
  imageUrl: string;
490
- name: RichTextValue;
491
- position: RichTextValue;
492
- testimonials: RichTextValue;
481
+ name: string;
482
+ position: string;
483
+ testimonials: string;
493
484
  colorReplacements: ColorReplacement[];
494
485
  mediaType: string;
495
486
  size?: string;
@@ -505,7 +496,7 @@ export interface TestimonialItems {
505
496
  export interface TextItem {
506
497
  /** Stable per-item identifier. See ImageItem.id. */
507
498
  id: string;
508
- text: RichTextValue;
499
+ text: string;
509
500
  textStyle: TextStyleDeclaration;
510
501
 
511
502
  // overrides for personalisation
@@ -527,8 +518,8 @@ export interface ImagesSectionContent extends Content, MediaSection {
527
518
  }
528
519
 
529
520
  export interface MediaSection extends Content {
530
- title: RichTextValue;
531
- description: RichTextValue;
521
+ title: string;
522
+ description: string;
532
523
  displayStyle: ImagesSectionContentDisplayStyle;
533
524
  items: TextShapeItem[] | TextMediaItem[];
534
525
  titleStyle: TextStyleDeclaration;
@@ -547,7 +538,7 @@ export interface ColorReplacement {
547
538
 
548
539
  export interface TestimonialSectionContent extends Content {
549
540
  type: 'testimonial-section';
550
- title: RichTextValue;
541
+ title: string;
551
542
  displayStyle: string;
552
543
  items: TestimonialItems[];
553
544
  titleStyle: TextStyleDeclaration;
@@ -562,8 +553,8 @@ export interface TestimonialSectionContent extends Content {
562
553
  export interface AboutSectionContent extends Content {
563
554
  type: 'about-section';
564
555
  imageUrl: string;
565
- title: RichTextValue;
566
- paragraph: RichTextValue;
556
+ title: string;
557
+ paragraph: string;
567
558
  displayStyle: string;
568
559
  titleStyle: TextStyleDeclaration;
569
560
  paragraphStyle: TextStyleDeclaration;
@@ -592,7 +583,7 @@ export type SocialLinksIconDisplayStyle =
592
583
 
593
584
  export interface SocialLinksContent extends Content {
594
585
  type: 'social-links';
595
- title: RichTextValue;
586
+ title: string;
596
587
  links: LinksItem[];
597
588
  iconDisplayStyle: SocialLinksIconDisplayStyle;
598
589
  iconFillStyles: BrandPageCssStyle;
@@ -619,8 +610,8 @@ export interface DividerSectionContent extends Content {
619
610
 
620
611
  export interface BookingSectionContent extends Content {
621
612
  type: 'booking-section';
622
- title: RichTextValue;
623
- description: RichTextValue;
613
+ title: string;
614
+ description: string;
624
615
  buttonText: string;
625
616
  url: string;
626
617
  email?: string;
@@ -462,7 +462,7 @@ exports[`migration.util > Banner Contents - text Align and Font Family should no
462
462
  },
463
463
  },
464
464
  },
465
- "v": 20,
465
+ "v": 19,
466
466
  },
467
467
  "useOldLogoRenderSize": true,
468
468
  }
@@ -914,7 +914,7 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
914
914
  },
915
915
  },
916
916
  },
917
- "v": 20,
917
+ "v": 19,
918
918
  },
919
919
  "useOldLogoRenderSize": true,
920
920
  }
@@ -1373,7 +1373,7 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
1373
1373
  },
1374
1374
  },
1375
1375
  },
1376
- "v": 20,
1376
+ "v": 19,
1377
1377
  },
1378
1378
  "useOldLogoRenderSize": true,
1379
1379
  }
@@ -0,0 +1,43 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import type { BrandPageContext } from '../models';
3
+ import { getSlugFromContext, isPreviewMode } from './context.util';
4
+
5
+ const baseContext = {
6
+ isPreview: false,
7
+ isLivePreview: false,
8
+ brandPageSlug: 'my-site',
9
+ } as unknown as BrandPageContext;
10
+
11
+ describe('isPreviewMode', () => {
12
+ it('is false for a live render (neither preview flag set)', () => {
13
+ expect(isPreviewMode(baseContext)).toBe(false);
14
+ });
15
+
16
+ it('is true for the editor preview', () => {
17
+ expect(isPreviewMode({ ...baseContext, isPreview: true })).toBe(true);
18
+ });
19
+
20
+ it('is true for the customer live-preview', () => {
21
+ expect(isPreviewMode({ ...baseContext, isLivePreview: true })).toBe(true);
22
+ });
23
+
24
+ it('treats a missing isLivePreview as not-preview', () => {
25
+ const ctx = { isPreview: false } as unknown as BrandPageContext;
26
+
27
+ expect(isPreviewMode(ctx)).toBe(false);
28
+ });
29
+ });
30
+
31
+ describe('getSlugFromContext', () => {
32
+ it('returns the literal editor slug for the editor preview only', () => {
33
+ expect(getSlugFromContext({ ...baseContext, isPreview: true })).toBe(
34
+ 'slug',
35
+ );
36
+ });
37
+
38
+ it('returns the real slug for a customer preview (renders like live)', () => {
39
+ expect(getSlugFromContext({ ...baseContext, isLivePreview: true })).toBe(
40
+ 'my-site',
41
+ );
42
+ });
43
+ });
@@ -7,3 +7,13 @@ export const getSlugFromContext = (context: BrandPageContext) => {
7
7
 
8
8
  return context.brandPageSlug;
9
9
  };
10
+
11
+ /**
12
+ * True when interactive actions must be inert and payment/shop blocks always
13
+ * shown — i.e. the render is a preview, not a live site. Covers both the
14
+ * editor preview (`isPreview`) and the customer live-preview
15
+ * (`isLivePreview`). Editor-only artifacts (cursor, nav interception,
16
+ * placeholders) must keep reading `context.isPreview` directly.
17
+ */
18
+ export const isPreviewMode = (context: BrandPageContext): boolean =>
19
+ !!(context.isPreview || context.isLivePreview);