@designcrowd/library.brand-page 6.0.25-json-prereq-2 → 6.0.25

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 (155) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-MkdpvvLq.js → CreatedOnBrandCrowd-de-de-CS3ct0wa.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-0K8Va8jv.js → CreatedOnBrandCrowd-en-us-CmBcnDu6.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BXBXK85u.js → CreatedOnBrandCrowd-es-es-BdTuJtqV.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-wbrMlisb.js → CreatedOnBrandCrowd-fr-ca-Cx_H9X6l.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-wbrMlisb.js → CreatedOnBrandCrowd-fr-fr-Cx_H9X6l.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-BHBKnYHd.js → CreatedOnBrandCrowd-pt-br-BZZ9hjUi.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-BHBKnYHd.js → CreatedOnBrandCrowd-pt-pt-BZZ9hjUi.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BeG5A3Bb.js → CreatedOnDcom-de-de-SbONDQN1.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-DVCNhdLS.js → CreatedOnDcom-en-us-Beno1_gw.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-Ba8bq852.js → CreatedOnDcom-es-es-BBE_zdRu.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-DuNhf0PH.js → CreatedOnDcom-fr-ca-C6pgDB5x.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-CfofYZSL.js → CreatedOnDcom-fr-fr-FD1eqtg3.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-BMCBFLhc.js → CreatedOnDcom-pt-br-BiSx3OwM.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-CQS6Ft_9.js → CreatedOnDcom-pt-pt-Dn4DmKGA.js} +1 -1
  15. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +2 -5
  16. package/lib/src/brand-page/models/index.d.ts +26 -34
  17. package/lib/src/brand-page/utils/migration.util.js +0 -11
  18. package/lib/src/brand-page/utils/text.util.d.ts +1 -1
  19. package/lib/src/brand-page/utils/text.util.js +0 -32
  20. package/lib/src/brand-page/utils/vcard.util.js +4 -4
  21. package/lib/src/brand-page/utils/view-model.util.d.ts +0 -1
  22. package/lib/src/brand-page/utils/view-model.util.js +20 -68
  23. package/lib/src/brand-page/view-models.d.ts +3 -3
  24. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
  25. package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +9 -2
  26. package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +10 -6
  27. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.d.ts +20 -0
  28. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.js +44 -0
  29. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.d.ts +27 -0
  30. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.js +44 -0
  31. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
  32. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +103 -24
  33. package/lib/src/brand-page-maker/utils/index.d.ts +0 -2
  34. package/lib/src/brand-page-maker/utils/index.js +0 -2
  35. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +5 -28
  36. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +5 -48
  37. package/lib/src/brand-page-maker/validators/field.validator.js +2 -10
  38. package/lib/src/css/library.brand-page-brandCrowd.min.css +39 -39
  39. package/lib/src/css/library.brand-page-brandPage.min.css +39 -39
  40. package/lib/src/css/library.brand-page-designCom.min.css +39 -39
  41. package/lib/src/css/library.brand-page-preview.min.css +39 -39
  42. package/lib/src/index.d.ts +0 -1
  43. package/lib/src/index.mjs +138 -143
  44. package/lib/src/{lib-QPQAbiCG.js → lib-BVHFYSLL.js} +60149 -63629
  45. package/lib/src/lib.js +0 -2
  46. package/lib/src/metadata-builder/ai-metadata-executor.d.ts +1 -0
  47. package/lib/src/metadata-builder/ai-metadata-executor.js +19 -0
  48. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -2
  49. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -2
  50. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -2
  51. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -3
  52. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -2
  53. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -1
  54. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -1
  55. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -3
  56. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -2
  57. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -1
  58. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +11 -15
  59. package/lib/src/metadata-builder/builders/update-content-text-builder.d.ts +17 -0
  60. package/lib/src/metadata-builder/builders/update-content-text-builder.js +103 -0
  61. package/lib/src/metadata-builder/builders/update-content-text-style-builder.d.ts +16 -0
  62. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +216 -0
  63. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +13 -11
  64. package/lib/src/metadata-builder/helpers/rte.helpers.js +73 -14
  65. package/lib/src/metadata-builder/metadata-executor.js +4 -0
  66. package/lib/src/metadata-builder/models.d.ts +2 -0
  67. package/lib/src/metadata-builder/models.js +2 -0
  68. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +19 -0
  69. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +4 -0
  70. package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +8 -7
  71. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +52 -21
  72. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +1 -14
  73. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +3 -12
  74. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +2 -3
  75. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +3 -10
  76. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
  77. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -4
  78. package/lib/src/utils/minify-brand-page-metadata.js +1 -4
  79. package/package.json +15 -17
  80. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +2 -5
  81. package/src/brand-page/components/text-wrapper/TextWrapper.vue +6 -17
  82. package/src/brand-page/models/index.ts +26 -35
  83. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
  84. package/src/brand-page/utils/migration.util.ts +0 -12
  85. package/src/brand-page/utils/style.util.test.ts +0 -51
  86. package/src/brand-page/utils/text.util.ts +4 -43
  87. package/src/brand-page/utils/vcard.util.ts +4 -6
  88. package/src/brand-page/utils/view-model.util.ts +26 -94
  89. package/src/brand-page/view-models.ts +2 -3
  90. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +3 -4
  91. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +1 -0
  92. package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +10 -6
  93. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.ts +73 -0
  94. package/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.ts +85 -0
  95. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +111 -27
  96. package/src/brand-page-maker/utils/index.ts +0 -2
  97. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +3 -37
  98. package/src/brand-page-maker/utils/rich-text-editor.util.ts +11 -66
  99. package/src/brand-page-maker/validators/field.validator.ts +2 -10
  100. package/src/lib.ts +0 -9
  101. package/src/metadata-builder/ai-metadata-executor.ts +26 -0
  102. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +3 -2
  103. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +3 -2
  104. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -2
  105. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +4 -3
  106. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +3 -2
  107. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +2 -1
  108. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +2 -1
  109. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +6 -3
  110. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +3 -2
  111. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +2 -1
  112. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +13 -19
  113. package/src/metadata-builder/builders/update-content-text-builder.ts +148 -0
  114. package/src/metadata-builder/builders/update-content-text-style-builder.ts +352 -0
  115. package/src/metadata-builder/helpers/rte.helpers.ts +101 -15
  116. package/src/metadata-builder/metadata-executor.ts +5 -0
  117. package/src/metadata-builder/models.ts +3 -0
  118. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +27 -0
  119. package/src/metadata-builder/sanitizers/rte-schema-check.ts +53 -24
  120. package/src/shared/content-settings/components/GenericTextInput.mixin.ts +1 -17
  121. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +3 -16
  122. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +4 -13
  123. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +4 -6
  124. package/src/shared/content-settings/components/text-image-field/TextImageField.vue +3 -6
  125. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -6
  126. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +1 -1
  127. package/src/utils/minify-brand-page-metadata.ts +1 -4
  128. package/lib/src/brand-page/utils/migration/migration-20.d.ts +0 -2
  129. package/lib/src/brand-page/utils/migration/migration-20.js +0 -111
  130. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +0 -22
  131. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +0 -22
  132. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.d.ts +0 -14
  133. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.js +0 -39
  134. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  135. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +0 -90
  136. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -41
  137. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -33
  138. package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +0 -6
  139. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +0 -158
  140. package/src/brand-page/utils/migration/migration-20.server.test.ts +0 -121
  141. package/src/brand-page/utils/migration/migration-20.test.ts +0 -72
  142. package/src/brand-page/utils/migration/migration-20.ts +0 -152
  143. package/src/brand-page/utils/text.util.test.ts +0 -47
  144. package/src/brand-page/utils/view-model.pageid-rte.test.ts +0 -104
  145. package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +0 -23
  146. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +0 -52
  147. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.ts +0 -42
  148. package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +0 -137
  149. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +0 -202
  150. package/src/brand-page-maker/utils/rte-features.test.ts +0 -351
  151. package/src/brand-page-maker/utils/rte-render-parity.test.ts +0 -157
  152. package/src/brand-page-maker/utils/rte-render.util.ts +0 -68
  153. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +0 -158
  154. package/src/brand-page-maker/utils/rte-sanitize.util.ts +0 -195
  155. package/src/brand-page-maker/validators/field.validator.test.ts +0 -55
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "275",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "251",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "250",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-QPQAbiCG.js";
2
+ import { _ as t } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-QPQAbiCG.js";
2
+ import { _ as e } from "./lib-BVHFYSLL.js";
3
3
  const M = {}, Z = {
4
4
  width: "242",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-QPQAbiCG.js";
2
+ import { _ as e } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, M = {
4
4
  width: "231",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-QPQAbiCG.js";
2
+ import { _ as e } from "./lib-BVHFYSLL.js";
3
3
  const M = {}, Z = {
4
4
  width: "230",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-QPQAbiCG.js";
2
+ import { _ as e } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-QPQAbiCG.js";
2
+ import { _ as e } from "./lib-BVHFYSLL.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-QPQAbiCG.js";
2
+ import { _ as M } from "./lib-BVHFYSLL.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-QPQAbiCG.js";
2
+ import { _ as M } from "./lib-BVHFYSLL.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -6,7 +6,7 @@ import brandPageClient from '../../clients/brand-page.client';
6
6
  import { isEmail } from '../../../utils/validator.util';
7
7
  import { ALIGN_CARD_CENTER, ALIGN_CARD_CENTER_IMAGE, ALIGN_CENTERED, ALIGN_LEFT_FULL_IMAGE, ALIGN_RIGHT_FULL_IMAGE, DISPLAY_STYLE_COLLAPSED, RECAPTCHA_ACTION_CONTACT_FORM, TEXT_ONLY, } from '../../constants';
8
8
  import { getRenderText, contentPaddingStyle as toContentPaddingStyle, mutedTextForBackground, backgroundColorFromStyle, } from '@brand-page/utils';
9
- import { hasRTEContent, getPlainTextFromRTE } from '@brand-page-maker/utils';
9
+ import { hasRTEContent } from '@brand-page-maker/utils';
10
10
  import { useReCaptcha } from '../../composables/recaptcha.composable';
11
11
  export default defineComponent({
12
12
  props: {
@@ -120,10 +120,7 @@ export default defineComponent({
120
120
  isEmail(this.viewModel.responseEmail));
121
121
  },
122
122
  title() {
123
- // BP-5787: title may be RTE JSON (not a string), so `.trim()` would
124
- // throw — read the visible text via getPlainTextFromRTE to decide
125
- // whether to fall back to the default.
126
- return getPlainTextFromRTE(this.viewModel.title)
123
+ return this.viewModel.title && this.viewModel.title.trim() !== ''
127
124
  ? this.viewModel.title
128
125
  : 'Contact Us';
129
126
  },
@@ -7,14 +7,6 @@ import { TextStyles } from './styles.model';
7
7
  import { LogoStyles } from './logo.model';
8
8
  import type { LogoImageModel, LogoTemplateImageModel } from './logo.model';
9
9
  import type { BrandPagePaymentConfig } from './payment.model';
10
- import type { JSONContent } from '@tiptap/vue-3';
11
- /**
12
- * BP-5787 — a rich-text field is either a legacy inline-HTML string or a
13
- * Tiptap JSON document. Typing RTE content fields as RichTextValue (instead of
14
- * `string`) forces every consumer to handle both forms — surfacing at compile
15
- * time any code that assumes a plain string (e.g. `.replace`, `.length`).
16
- */
17
- export type RichTextValue = string | JSONContent;
18
10
  export * from './brand-page-context.model';
19
11
  export * from './payment.model';
20
12
  export * from './content.model';
@@ -156,7 +148,7 @@ export interface TextContent extends Content {
156
148
  /**
157
149
  * For BrandPage/BrandContact only
158
150
  */
159
- text: RichTextValue;
151
+ text: string;
160
152
  /**
161
153
  * For BrandSite
162
154
  */
@@ -179,9 +171,9 @@ export interface TextContent extends Content {
179
171
  }
180
172
  export interface ProfileContent extends Content {
181
173
  avatarImageUrl: string;
182
- name: RichTextValue;
183
- title: RichTextValue;
184
- description: RichTextValue;
174
+ name: string;
175
+ title: string;
176
+ description: string;
185
177
  backgroundColor: BrandPageCssStyle;
186
178
  colorReplacements: ColorReplacement[];
187
179
  mediaType?: string;
@@ -199,7 +191,7 @@ export interface MapContent extends Content {
199
191
  }
200
192
  export interface MailingListContent extends Content {
201
193
  acceptedFields?: 'emailOnly' | 'nameAndEmail';
202
- title: RichTextValue;
194
+ title: string;
203
195
  buttonText: string;
204
196
  titleStyle: TextStyleDeclaration;
205
197
  buttonTextStyle: TextStyleDeclaration;
@@ -251,10 +243,10 @@ export interface FormField {
251
243
  export interface ContactFormContent extends Content {
252
244
  type: 'contact-form';
253
245
  displayStyle: string;
254
- title: RichTextValue;
255
- description: RichTextValue;
246
+ title: string;
247
+ description: string;
256
248
  buttonText: string;
257
- successMessage: RichTextValue;
249
+ successMessage: string;
258
250
  fields: FormField[];
259
251
  responseEmail: string;
260
252
  imageUrl?: string;
@@ -273,8 +265,8 @@ export interface ContactFormContent extends Content {
273
265
  export interface BannerSectionContent extends Content {
274
266
  type: 'banner-section';
275
267
  imageUrl: string;
276
- title: RichTextValue;
277
- description: RichTextValue;
268
+ title: string;
269
+ description: string;
278
270
  buttonText: string | false;
279
271
  url: string;
280
272
  email?: string;
@@ -301,8 +293,8 @@ export declare const MEDIA_TYPES: {
301
293
  };
302
294
  export type MediaType = keyof typeof MEDIA_TYPES;
303
295
  export interface TextMediaItem extends ImageItem {
304
- title: RichTextValue;
305
- paragraph: RichTextValue;
296
+ title: string;
297
+ paragraph: string;
306
298
  itemsId: number;
307
299
  buttonText?: string | false;
308
300
  buttonPageId?: string;
@@ -321,8 +313,8 @@ export interface TextShapeItem extends TextMediaItem {
321
313
  export interface ShapeItem extends ImageItem {
322
314
  colorReplacements: ColorReplacement[];
323
315
  mediaType: MediaType;
324
- title?: RichTextValue;
325
- paragraph?: RichTextValue;
316
+ title?: string;
317
+ paragraph?: string;
326
318
  titleOverride?: string;
327
319
  paragraphOverride?: string;
328
320
  }
@@ -330,9 +322,9 @@ export interface TestimonialItems {
330
322
  /** Stable per-item identifier. See ImageItem.id. */
331
323
  id: string;
332
324
  imageUrl: string;
333
- name: RichTextValue;
334
- position: RichTextValue;
335
- testimonials: RichTextValue;
325
+ name: string;
326
+ position: string;
327
+ testimonials: string;
336
328
  colorReplacements: ColorReplacement[];
337
329
  mediaType: string;
338
330
  size?: string;
@@ -345,7 +337,7 @@ export interface TestimonialItems {
345
337
  export interface TextItem {
346
338
  /** Stable per-item identifier. See ImageItem.id. */
347
339
  id: string;
348
- text: RichTextValue;
340
+ text: string;
349
341
  textStyle: TextStyleDeclaration;
350
342
  textOverride?: string;
351
343
  }
@@ -362,8 +354,8 @@ export interface ImagesSectionContent extends Content, MediaSection {
362
354
  enablePopup: boolean;
363
355
  }
364
356
  export interface MediaSection extends Content {
365
- title: RichTextValue;
366
- description: RichTextValue;
357
+ title: string;
358
+ description: string;
367
359
  displayStyle: ImagesSectionContentDisplayStyle;
368
360
  items: TextShapeItem[] | TextMediaItem[];
369
361
  titleStyle: TextStyleDeclaration;
@@ -380,7 +372,7 @@ export interface ColorReplacement {
380
372
  }
381
373
  export interface TestimonialSectionContent extends Content {
382
374
  type: 'testimonial-section';
383
- title: RichTextValue;
375
+ title: string;
384
376
  displayStyle: string;
385
377
  items: TestimonialItems[];
386
378
  titleStyle: TextStyleDeclaration;
@@ -394,8 +386,8 @@ export interface TestimonialSectionContent extends Content {
394
386
  export interface AboutSectionContent extends Content {
395
387
  type: 'about-section';
396
388
  imageUrl: string;
397
- title: RichTextValue;
398
- paragraph: RichTextValue;
389
+ title: string;
390
+ paragraph: string;
399
391
  displayStyle: string;
400
392
  titleStyle: TextStyleDeclaration;
401
393
  paragraphStyle: TextStyleDeclaration;
@@ -419,7 +411,7 @@ export declare const SOCIAL_LINKS_ICON_DISPLAY_STYLES: {
419
411
  export type SocialLinksIconDisplayStyle = keyof typeof SOCIAL_LINKS_ICON_DISPLAY_STYLES;
420
412
  export interface SocialLinksContent extends Content {
421
413
  type: 'social-links';
422
- title: RichTextValue;
414
+ title: string;
423
415
  links: LinksItem[];
424
416
  iconDisplayStyle: SocialLinksIconDisplayStyle;
425
417
  iconFillStyles: BrandPageCssStyle;
@@ -442,8 +434,8 @@ export interface DividerSectionContent extends Content {
442
434
  }
443
435
  export interface BookingSectionContent extends Content {
444
436
  type: 'booking-section';
445
- title: RichTextValue;
446
- description: RichTextValue;
437
+ title: string;
438
+ description: string;
447
439
  buttonText: string;
448
440
  url: string;
449
441
  email?: string;
@@ -22,7 +22,6 @@ import { migration16 } from './migration/migration-16';
22
22
  import { migration17 } from './migration/migration-17';
23
23
  import { migration18 } from './migration/migration-18';
24
24
  import { migration19 } from './migration/migration-19';
25
- import { migration20 } from './migration/migration-20';
26
25
  const MIGRATION_TABLE = [
27
26
  {
28
27
  version: 1,
@@ -150,16 +149,6 @@ const MIGRATION_TABLE = [
150
149
  runAlways: true,
151
150
  description: 'BP-5800: seed the button fill colour as each block’s own container colour so it is independent of the site button (existing sites render unchanged) — backgroundStyle for mailing-list, request-payment and support-me (all types); cardStyle for the BP/BC contact form (skipped on brand-site)',
152
151
  },
153
- {
154
- version: 20,
155
- migrateFn: migration20,
156
- // One-time versioned migration (NOT runAlways): legacy sites (v < 20)
157
- // convert on their first load in any environment — the maker (browser DOM)
158
- // and web-renderer SSR (migration-20 installs a jsdom window). It no longer
159
- // needs to re-run every load because the AI section builders now emit Tiptap
160
- // JSON directly, so there is no recurring post-load source of HTML to catch.
161
- description: 'BP-5787: convert inline-HTML RTE content to Tiptap JSON on first load (client or server); AI builders emit JSON directly, so this runs once per site',
162
- },
163
152
  ];
164
153
  export const GetLatestModelVersion = () => Math.max(...MIGRATION_TABLE.map((x) => x.version));
165
154
  export const migrateBrandPageModel = async (brandPageModel, options) => {
@@ -1,5 +1,5 @@
1
1
  export declare const getRenderText: (text: string) => string;
2
- export declare const escapeContentText: (text: unknown) => string | undefined;
2
+ export declare const escapeContentText: (text: string | undefined) => string | undefined;
3
3
  export declare const decodeHtmlEntities: (text: string) => string;
4
4
  export declare const unescapeContentText: (text: string) => string;
5
5
  export declare const encodeContentText: (text: string | undefined) => string | undefined;
@@ -1,43 +1,11 @@
1
1
  import { ESCAPED_NEWLINE_CHARACTER } from '../../constants/ui';
2
- /**
3
- * BP-5787 — a Tiptap JSON document is an object with `type: 'doc'`.
4
- * Inlined here (rather than importing from brand-page-maker) to avoid a
5
- * circular import: rich-text-editor.util imports getRenderText from this file.
6
- */
7
- const isTiptapDoc = (value) => typeof value === 'object' &&
8
- value !== null &&
9
- value.type === 'doc';
10
- const jsonDocPlainText = (doc) => {
11
- const parts = [];
12
- const walk = (node) => {
13
- if (typeof node?.text === 'string')
14
- parts.push(node.text);
15
- node?.content?.forEach(walk);
16
- };
17
- walk(doc);
18
- return parts.join(' ').replace(/\s+/g, ' ').trim();
19
- };
20
2
  export const getRenderText = (text) => {
21
- // BP-5787: RTE fields may now be Tiptap JSON objects. Non-strings pass
22
- // through untouched so the renderer (TextWrapper) handles them via its
23
- // JSON-aware path, instead of throwing on `.replace`.
24
- if (typeof text !== 'string') {
25
- return text;
26
- }
27
3
  return text.replace(new RegExp(`(${ESCAPED_NEWLINE_CHARACTER}|\\n)`, 'g'), '<br/>');
28
4
  };
29
- // Accepts a legacy inline-HTML string or a Tiptap JSON document (BP-5787):
30
- // for JSON it returns the concatenated visible text; for HTML it strips tags.
31
5
  export const escapeContentText = (text) => {
32
6
  if (!text) {
33
7
  return text;
34
8
  }
35
- if (isTiptapDoc(text)) {
36
- return jsonDocPlainText(text);
37
- }
38
- if (typeof text !== 'string') {
39
- return undefined;
40
- }
41
9
  return text
42
10
  .replace(/(<([^>]+)>)/gi, '')
43
11
  .replace(/(\r\n|\r|\n)/g, ESCAPED_NEWLINE_CHARACTER);
@@ -150,9 +150,9 @@ const processSocialLinks = (socialLinksContent, vcardLines, addedEntries) => {
150
150
  });
151
151
  };
152
152
  const addProfileInfo = (profile, vcardLines) => {
153
- const name = sanitizeForVCard(getPlainTextFromRTE(profile.name) || '');
154
- const title = sanitizeForVCard(getPlainTextFromRTE(profile.title) || '');
155
- const description = sanitizeForVCard(getPlainTextFromRTE(profile.description) || '');
153
+ const name = sanitizeForVCard(profile.name || '');
154
+ const title = sanitizeForVCard(profile.title || '');
155
+ const description = sanitizeForVCard(profile.description || '');
156
156
  if (name) {
157
157
  const nameParts = name.trim().split(/\s+/);
158
158
  const lastName = nameParts.length > 1 ? nameParts.pop() || '' : '';
@@ -205,6 +205,6 @@ const downloadVCard = (vcard, filename) => {
205
205
  export const saveContact = (brandPageData) => {
206
206
  const vcard = generateVCard(brandPageData);
207
207
  const profile = findProfileContent(brandPageData);
208
- const filename = generateVCardFilename(getPlainTextFromRTE(profile?.name));
208
+ const filename = generateVCardFilename(profile?.name);
209
209
  downloadVCard(vcard, filename);
210
210
  };
@@ -28,7 +28,6 @@ interface ViewModelMappingOptions {
28
28
  setVideoUrlsWithToken?: (token: string, videoUrl: string, previewImageUrl: string, assetId: string) => void;
29
29
  }
30
30
  export declare const getBrandPageViewModelFromBrandPageModel: (model: BrandPageModel, brandPageToken: string | undefined, showBrandCrowdLogo: boolean | undefined, options: ViewModelMappingOptions) => BrandPageViewModel;
31
- export declare const resolvePageIdsInRteJson: (doc: unknown, nav: NavViewModel, options: ViewModelMappingOptions) => unknown;
32
31
  export declare const isLogoViewModel: (viewModel: ContentViewModel) => viewModel is LogoViewModel;
33
32
  /** for service.brand-page website preview by logo draft token */
34
33
  export declare const applyLogoImageToBrandPageViewModel: (viewModel: BrandPageViewModel, logoImage: LogoImageModel) => BrandPageViewModel;
@@ -10,7 +10,7 @@ import { isValidSvgUrl } from './image.util';
10
10
  import { isLogoContent } from './model.util';
11
11
  import { getBoxShadowValue } from './button.util';
12
12
  import { findNavItemByPageId, getRouteNameByPageIndex, getRouteParamsByPage, } from './route.util';
13
- import { hasRTEContent, isTiptapDocument } from '../../brand-page-maker/utils';
13
+ import { hasRTEContent } from '../../brand-page-maker/utils';
14
14
  import { getPageIdFromHref, isHrefPageId, } from '../../brand-page-maker/composables/rich-text-editor/hyperlink';
15
15
  const BUTTON_BORDER_RADIUS = '9999px';
16
16
  const CONTENT_BORDER_RADIUS = '48px';
@@ -864,75 +864,13 @@ const mapPageIdReferencesToRelativePaths = (pages, nav, options) => {
864
864
  });
865
865
  });
866
866
  };
867
- // Resolve a `pageid:<id>` internal-link href to the published relative path.
868
- // Returns the resolved href, or null when `href` is not an internal pageid link
869
- // (external/absolute links are left untouched). Falls back to the site root when
870
- // the pageid can't be matched to a nav route.
871
- const resolvePageIdHref = (href, nav, options) => {
872
- // Only process internal links (no protocol, doesn't start with /)
873
- if (!href || href.match(/^(https?:\/\/|\/)/) || !isHrefPageId(href)) {
874
- return null;
875
- }
876
- const pageId = getPageIdFromHref(href);
877
- const route = findNavItemByPageId(nav.navItems, pageId);
878
- const brandPageSlugRoute = options.brandPageSlug
879
- ? `/${options.brandPageSlug}`
880
- : '/';
881
- if (route) {
882
- if (route.isRoot) {
883
- return brandPageSlugRoute;
884
- }
885
- return `${brandPageSlugRoute}${brandPageSlugRoute === '/' ? '' : '/'}${route.relativePath}`;
886
- }
887
- // fallback to root if pageid cannot be resolved.
888
- return brandPageSlugRoute;
889
- };
890
- // BP-5847: walk a Tiptap JSON doc and rewrite every link mark whose href is a
891
- // `pageid:` reference into its published relative path. Returns a NEW doc when
892
- // something changed (so the shared model doc is never mutated), else the same
893
- // reference.
894
- export const resolvePageIdsInRteJson = (doc, nav, options) => {
895
- let changed = false;
896
- const walk = (node) => {
897
- if (!node || typeof node !== 'object') {
898
- return node;
899
- }
900
- let next = node;
901
- if (Array.isArray(node.marks)) {
902
- const marks = node.marks.map((mark) => {
903
- if (mark?.type === 'link' && typeof mark.attrs?.href === 'string') {
904
- const resolved = resolvePageIdHref(mark.attrs.href, nav, options);
905
- if (resolved !== null) {
906
- changed = true;
907
- return { ...mark, attrs: { ...mark.attrs, href: resolved } };
908
- }
909
- }
910
- return mark;
911
- });
912
- next = { ...next, marks };
913
- }
914
- if (Array.isArray(node.content)) {
915
- next = { ...next, content: node.content.map(walk) };
916
- }
917
- return next;
918
- };
919
- const result = walk(doc);
920
- return changed ? result : doc;
921
- };
922
867
  const dynamicallyMapPageIdInHyperlinksToRelativePaths = (content, nav, options) => {
923
868
  Object.keys(content).forEach((key) => {
924
869
  const value = content[key];
925
870
  if (value === undefined || value === null) {
926
871
  return;
927
872
  }
928
- if (isTiptapDocument(value)) {
929
- // BP-5847: RTE fields may now be Tiptap JSON. Resolve pageid link marks
930
- // here too, or internal links render as raw `pageid:` and don't navigate.
931
- content[key] =
932
- resolvePageIdsInRteJson(value, nav, options);
933
- }
934
- else if (typeof value === 'object' &&
935
- (key === 'items' || key === 'textItems')) {
873
+ if (typeof value === 'object' && (key === 'items' || key === 'textItems')) {
936
874
  if (Array.isArray(value)) {
937
875
  value.forEach((item) => {
938
876
  dynamicallyMapPageIdInHyperlinksToRelativePaths(item, nav, options);
@@ -944,10 +882,24 @@ const dynamicallyMapPageIdInHyperlinksToRelativePaths = (content, nav, options)
944
882
  }
945
883
  else if (typeof value === 'string' && hasRTEContent(value)) {
946
884
  content[key] = value.replace(/<a\s+([^>]*?)href="([^"]*?)"([^>]*?)>/gi, (match, existingAttrsStart, href, existingAttrsEnd) => {
947
- const resolved = resolvePageIdHref(href, nav, options);
948
- return resolved === null
949
- ? match
950
- : `<a ${existingAttrsStart}href="${resolved}"${existingAttrsEnd}>`;
885
+ // Only process internal links (no protocol, doesn't start with /)
886
+ if (href && !href.match(/^(https?:\/\/|\/)/) && isHrefPageId(href)) {
887
+ const pageId = getPageIdFromHref(href);
888
+ const route = findNavItemByPageId(nav.navItems, pageId);
889
+ const brandPageSlugRoute = options.brandPageSlug
890
+ ? `/${options.brandPageSlug}`
891
+ : '/';
892
+ if (route) {
893
+ let href = `${brandPageSlugRoute}`;
894
+ if (!route.isRoot) {
895
+ href = `${brandPageSlugRoute}${brandPageSlugRoute === '/' ? '' : '/'}${route.relativePath}`;
896
+ }
897
+ return `<a ${existingAttrsStart}href="${href}"${existingAttrsEnd}>`;
898
+ }
899
+ // fallback to root if pageid cannot be resolved.
900
+ return `<a ${existingAttrsStart}href="${brandPageSlugRoute}"${existingAttrsEnd}>`;
901
+ }
902
+ return match;
951
903
  });
952
904
  }
953
905
  });
@@ -1,4 +1,4 @@
1
- import type { ButtonWithModalContent, ProfileContent, TextContent, VideoContent, ImageContent, ContentType, ButtonStyles, LogoStyles, MapContent, ImageGalleryContent, GalleryStyles, MailingListContent, RequestPaymentContent, ShopContent, SupportMeContent, ContactFormContent, BannerSectionContent, BrandPageType, SocialLinksContent, TestimonialSectionContent, AboutSectionContent, DividerSectionContent, ShapesSectionContent, ButtonLinkType, PageHeaderMobile, PageHeaderDesktop, PageFooterMobile, PageFooterDesktop, TextMediaItem, TextShapeItem, TextStyleDeclaration, AspectRatio, LogoImageModel, LogoTemplateImageModel, CookieOptions, BookingSectionContent, MediaTypes, TextStyles, BackgroundStyle, BackgroundShape, PersonalisationRole, SaveContactOptions, RichTextValue } from './models';
1
+ import type { ButtonWithModalContent, ProfileContent, TextContent, VideoContent, ImageContent, ContentType, ButtonStyles, LogoStyles, MapContent, ImageGalleryContent, GalleryStyles, MailingListContent, RequestPaymentContent, ShopContent, SupportMeContent, ContactFormContent, BannerSectionContent, BrandPageType, SocialLinksContent, TestimonialSectionContent, AboutSectionContent, DividerSectionContent, ShapesSectionContent, ButtonLinkType, PageHeaderMobile, PageHeaderDesktop, PageFooterMobile, PageFooterDesktop, TextMediaItem, TextShapeItem, TextStyleDeclaration, AspectRatio, LogoImageModel, LogoTemplateImageModel, CookieOptions, BookingSectionContent, MediaTypes, TextStyles, BackgroundStyle, BackgroundShape, PersonalisationRole, SaveContactOptions } from './models';
2
2
  import type { ImagesSectionContentDisplayStyle } from './constants';
3
3
  export type ViewModelType = 'button' | 'image' | 'image-gallery' | 'logo' | 'map' | 'mailing-list' | 'profile' | 'support-me' | 'request-payment' | 'text' | 'video' | 'contact-form' | 'banner-section' | 'images-section' | 'about-section' | 'divider-section' | 'testimonial-section' | 'social-links' | 'shapes-section' | 'shop-section' | 'booking-section';
4
4
  export interface ContentViewModel {
@@ -94,8 +94,8 @@ export interface TextImageSectionViewModel {
94
94
  id: string;
95
95
  type: 'images-section';
96
96
  role: ContentType;
97
- title: RichTextValue;
98
- description: RichTextValue;
97
+ title: string;
98
+ description: string;
99
99
  displayStyle: ImagesSectionContentDisplayStyle;
100
100
  aspectRatio: AspectRatio;
101
101
  areImagesFullWidth: boolean;
@@ -21,6 +21,7 @@ export interface AiMetadataBuilderResult {
21
21
  }
22
22
  export declare function useAiMetadataBuilder(logger: Logger): {
23
23
  applyAiToolCallsAsync: (model: BrandPageModel, aiAssistantToolCall: AiAssistantToolCall[], options?: {
24
+ maxCharacters?: number;
24
25
  /**
25
26
  * Invoked by the UndoBuilder to resolve the pre-prompt snapshot.
26
27
  * Required when the response includes an `undo` tool call.
@@ -5,8 +5,15 @@ export declare const useBubbleMenu: (editor: Editor, isHyperlinkPopupOpen?: Ref<
5
5
  editor: any;
6
6
  state: any;
7
7
  }) => any;
8
- bubbleMenuOptions: {
8
+ tippyOptions: {
9
+ duration: number;
9
10
  placement: "bottom";
10
- offset: number;
11
+ interactive: boolean;
12
+ appendTo: "parent";
13
+ hideOnClick: boolean;
14
+ arrow: boolean;
15
+ offset: [number, number];
16
+ trigger: "manual";
17
+ zIndex: number;
11
18
  };
12
19
  };
@@ -13,15 +13,19 @@ export const useBubbleMenu = (editor, isHyperlinkPopupOpen) => {
13
13
  }
14
14
  return false;
15
15
  };
16
- // v3 BubbleMenu uses Floating UI (was tippy.js in v2). Only placement + offset
17
- // carry over; the rest of the old tippy config (trigger/interactive/hideOnClick/
18
- // zIndex) is either the v3 default or handled in CSS.
19
- const bubbleMenuOptions = {
16
+ const tippyOptions = {
17
+ duration: 100,
20
18
  placement: 'bottom',
21
- offset: 10,
19
+ interactive: true,
20
+ appendTo: 'parent',
21
+ hideOnClick: false,
22
+ arrow: false,
23
+ offset: [0, 10],
24
+ trigger: 'manual',
25
+ zIndex: 10,
22
26
  };
23
27
  return {
24
28
  shouldShow,
25
- bubbleMenuOptions,
29
+ tippyOptions,
26
30
  };
27
31
  };
@@ -0,0 +1,20 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import '@tiptap/extension-text-style';
3
+ export type FontSizeOptions = {
4
+ types: string[];
5
+ };
6
+ declare module '@tiptap/core' {
7
+ interface Commands<ReturnType> {
8
+ fontSize: {
9
+ /**
10
+ * Set the font size
11
+ */
12
+ setFontSize: (fontSize: string) => ReturnType;
13
+ /**
14
+ * Unset the font size
15
+ */
16
+ unsetFontSize: () => ReturnType;
17
+ };
18
+ }
19
+ }
20
+ export declare const FontSize: Extension<FontSizeOptions, any>;