@designcrowd/library.brand-page 6.2.11 → 6.2.12

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 (576) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DDcraD5S.js → CreatedOnBrandCrowd-de-de-BtVKllNQ.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DtOeaisf.js → CreatedOnBrandCrowd-en-us-CX5V0v8u.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BZpmJPew.js → CreatedOnBrandCrowd-es-es-CbA02PCL.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CqRwC4e7.js → CreatedOnBrandCrowd-fr-ca-BQAKruBF.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CqRwC4e7.js → CreatedOnBrandCrowd-fr-fr-BQAKruBF.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DId9Dfjh.js → CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DId9Dfjh.js → CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BTDfmOcm.js → CreatedOnDcom-de-de-DJZQbPSD.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CeAu9Ayx.js → CreatedOnDcom-en-us-BJvNAa4l.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-WCv0K41H.js → CreatedOnDcom-es-es-CUwB1FRY.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BlfevQDY.js → CreatedOnDcom-fr-ca-CK54U4oh.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-Cvt7MHPZ.js → CreatedOnDcom-fr-fr-DuUNBGrM.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-DipZuylv.js → CreatedOnDcom-pt-br-BfODpFNV.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BCw4lcKN.js → CreatedOnDcom-pt-pt-Cf6u2GCg.js} +1 -1
  15. package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.d.ts +16 -0
  16. package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.js +35 -0
  17. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +3 -0
  18. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +19 -13
  19. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.d.ts +3 -1
  20. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +17 -2
  21. package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.d.ts +11 -3
  22. package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.js +35 -1
  23. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +8 -2
  24. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +27 -3
  25. package/lib/src/brand-page/components/page/Page.mixin.d.ts +5 -2
  26. package/lib/src/brand-page/components/page/Page.mixin.js +33 -27
  27. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +7 -2
  28. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +21 -1
  29. package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +5 -2
  30. package/lib/src/brand-page/components/payment/Payment.mixin.js +22 -2
  31. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.d.ts +6 -2
  32. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.js +32 -1
  33. package/lib/src/brand-page/components/social-links/SocialLinks.stories.js +0 -3
  34. package/lib/src/brand-page/components/testimonial-section/__fixtures__/data.js +0 -3
  35. package/lib/src/brand-page/components/text/Text.stories.js +0 -17
  36. package/lib/src/brand-page/constants/font.constants.d.ts +62 -0
  37. package/lib/src/brand-page/constants/font.constants.js +35 -0
  38. package/lib/src/brand-page/models/index.d.ts +23 -24
  39. package/lib/src/brand-page/models/index.js +20 -7
  40. package/lib/src/brand-page/models/navigation-styles.model.d.ts +1 -1
  41. package/lib/src/brand-page/models/navigation-styles.model.js +17 -8
  42. package/lib/src/brand-page/models/payment.model.d.ts +11 -6
  43. package/lib/src/brand-page/models/styles.model.d.ts +53 -7
  44. package/lib/src/brand-page/models/styles.model.js +115 -27
  45. package/lib/src/brand-page/utils/color-palette.util.d.ts +43 -23
  46. package/lib/src/brand-page/utils/color-palette.util.js +65 -27
  47. package/lib/src/brand-page/utils/color.util.d.ts +13 -9
  48. package/lib/src/brand-page/utils/color.util.js +56 -15
  49. package/lib/src/brand-page/utils/container-text-color.util.d.ts +46 -13
  50. package/lib/src/brand-page/utils/container-text-color.util.js +321 -41
  51. package/lib/src/brand-page/utils/index.d.ts +1 -0
  52. package/lib/src/brand-page/utils/index.js +1 -0
  53. package/lib/src/brand-page/utils/migration/migration-20.js +6 -2
  54. package/lib/src/brand-page/utils/migration/migration-21.js +34 -6
  55. package/lib/src/brand-page/utils/migration/migration-22.d.ts +99 -0
  56. package/lib/src/brand-page/utils/migration/migration-22.js +909 -0
  57. package/lib/src/brand-page/utils/migration.util.js +17 -0
  58. package/lib/src/brand-page/utils/model.util.d.ts +4 -0
  59. package/lib/src/brand-page/utils/model.util.js +4 -0
  60. package/lib/src/brand-page/utils/personalisation.util.js +9 -1
  61. package/lib/src/brand-page/utils/rte-role-lift.util.d.ts +72 -0
  62. package/lib/src/brand-page/utils/rte-role-lift.util.js +275 -0
  63. package/lib/src/brand-page/utils/style.util.d.ts +5 -1
  64. package/lib/src/brand-page/utils/style.util.js +34 -11
  65. package/lib/src/brand-page/utils/text-role-css.util.d.ts +19 -0
  66. package/lib/src/brand-page/utils/text-role-css.util.js +186 -0
  67. package/lib/src/brand-page/utils/text-role-reconnect.util.d.ts +90 -0
  68. package/lib/src/brand-page/utils/text-role-reconnect.util.js +434 -0
  69. package/lib/src/brand-page/utils/text-style.util.d.ts +53 -23
  70. package/lib/src/brand-page/utils/text-style.util.js +122 -22
  71. package/lib/src/brand-page/utils/view-model.util.d.ts +9 -1
  72. package/lib/src/brand-page/utils/view-model.util.js +124 -111
  73. package/lib/src/brand-page/view-models.d.ts +1 -0
  74. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +4 -1
  75. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -2
  76. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +4 -4
  77. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +4 -1
  78. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -10
  79. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +0 -1
  80. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +23 -138
  81. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +0 -28
  82. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +4 -1
  83. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +1 -1
  84. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +5 -2
  85. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +4 -1
  86. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +4 -1
  87. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +4 -1
  88. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
  89. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  90. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +1 -0
  91. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.d.ts +16 -0
  92. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.js +61 -0
  93. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.d.ts +11 -0
  94. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.js +236 -0
  95. package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +2 -1
  96. package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +25 -6
  97. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +17 -4
  98. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +204 -17
  99. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +1 -1
  100. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +29 -31
  101. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.d.ts +20 -0
  102. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.js +60 -0
  103. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +2 -1
  104. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +22 -6
  105. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +10 -4
  106. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +319 -275
  107. package/lib/src/brand-page-maker/constants/config-settings-constant.js +1 -5
  108. package/lib/src/brand-page-maker/convertors/text-css-style-options.convertor.js +6 -2
  109. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.d.ts +1 -1
  110. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  111. package/lib/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.js +7 -14
  112. package/lib/src/brand-page-maker/default-getters/text-color.default-getter.js +6 -13
  113. package/lib/src/brand-page-maker/models/content-settings.d.ts +8 -0
  114. package/lib/src/brand-page-maker/models/content-settings.js +112 -81
  115. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.d.ts +2 -2
  116. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.js +5 -2
  117. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.js +4 -3
  118. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +1257 -117
  119. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +6 -1
  120. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +17 -9
  121. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +59 -5
  122. package/lib/src/brand-page-maker/stores/history/history-store.js +22 -2
  123. package/lib/src/brand-page-maker/utils/apply-color-strategy.js +26 -8
  124. package/lib/src/brand-page-maker/utils/index.d.ts +2 -1
  125. package/lib/src/brand-page-maker/utils/index.js +2 -1
  126. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +117 -15
  127. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +435 -281
  128. package/lib/src/brand-page-maker/utils/rte-authoring.util.d.ts +4 -0
  129. package/lib/src/brand-page-maker/utils/rte-authoring.util.js +101 -0
  130. package/lib/src/brand-page-maker/utils/rte-clipboard.util.d.ts +126 -0
  131. package/lib/src/brand-page-maker/utils/rte-clipboard.util.js +307 -0
  132. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +13 -3
  133. package/lib/src/{bundled-translations-zfiA5Tsw.js → bundled-translations-yGrvPE5i.js} +17 -17
  134. package/lib/src/{bundled-translations.de-DE-ChsdSyAP.js → bundled-translations.de-DE-L4Znf8Hs.js} +17 -17
  135. package/lib/src/{bundled-translations.es-ES-DflsWQK0.js → bundled-translations.es-ES-D6iticrK.js} +15 -15
  136. package/lib/src/{bundled-translations.fr-CA-fpDRuZ52.js → bundled-translations.fr-CA-BgAVE-9k.js} +25 -25
  137. package/lib/src/{bundled-translations.fr-FR-Bub73Zt-.js → bundled-translations.fr-FR-B8GbyqxQ.js} +17 -17
  138. package/lib/src/{bundled-translations.pt-BR-BlnWE9TB.js → bundled-translations.pt-BR-DjPU3Db7.js} +25 -25
  139. package/lib/src/{bundled-translations.pt-PT-DmzXlnaS.js → bundled-translations.pt-PT-BaepaDpr.js} +23 -23
  140. package/lib/src/bundles/bundled-translations.de-DE.json +21 -2
  141. package/lib/src/bundles/bundled-translations.es-ES.json +21 -2
  142. package/lib/src/bundles/bundled-translations.fr-CA.json +21 -2
  143. package/lib/src/bundles/bundled-translations.fr-FR.json +21 -2
  144. package/lib/src/bundles/bundled-translations.json +21 -2
  145. package/lib/src/bundles/bundled-translations.pt-BR.json +21 -2
  146. package/lib/src/bundles/bundled-translations.pt-PT.json +21 -2
  147. package/lib/src/clients/ai-assistant-client.d.ts +1 -0
  148. package/lib/src/composables/useTranslate.d.ts +1 -1
  149. package/lib/src/composables/useTranslate.js +1 -1
  150. package/lib/src/css/library.brand-page-brandCrowd.min.css +303 -207
  151. package/lib/src/css/library.brand-page-brandPage.min.css +303 -207
  152. package/lib/src/css/library.brand-page-designCom.min.css +303 -207
  153. package/lib/src/css/library.brand-page-preview.min.css +303 -207
  154. package/lib/src/index.d.ts +2 -1
  155. package/lib/src/index.mjs +195 -191
  156. package/lib/src/{lib-1AqtEmvQ.js → lib-kGRlD3_P.js} +36855 -33893
  157. package/lib/src/lib.js +2 -1
  158. package/lib/src/metadata-builder/builders/footer-builder.js +4 -5
  159. package/lib/src/metadata-builder/builders/global-role-propagation.d.ts +58 -0
  160. package/lib/src/metadata-builder/builders/global-role-propagation.js +246 -0
  161. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +1 -0
  162. package/lib/src/metadata-builder/builders/global-styles-builder.js +116 -45
  163. package/lib/src/metadata-builder/builders/header-builder.js +13 -4
  164. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -3
  165. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -3
  166. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -3
  167. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -4
  168. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -3
  169. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -2
  170. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -2
  171. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -4
  172. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -3
  173. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +8 -2
  174. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -2
  175. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +60 -29
  176. package/lib/src/metadata-builder/builders/section-field-maps.js +1 -0
  177. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +48 -19
  178. package/lib/src/metadata-builder/builders/section-field-utils.js +128 -52
  179. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +4 -2
  180. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +28 -12
  181. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +5 -1
  182. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
  183. package/lib/src/metadata-builder/helpers/rte.helpers.js +97 -40
  184. package/lib/src/metadata-builder/metadata-executor.js +23 -1
  185. package/lib/src/metadata-builder/models.d.ts +2 -0
  186. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +18 -19
  187. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +18 -1
  188. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +1 -1
  189. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +0 -1
  190. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +5 -8
  191. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +7 -16
  192. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +95 -22
  193. package/lib/src/shared/color-palette/section-color-matches.js +9 -25
  194. package/lib/src/shared/color-strategies/color-strategies.d.ts +15 -0
  195. package/lib/src/shared/color-strategies/color-strategies.js +31 -0
  196. package/lib/src/shared/color-strategies/rte-color.d.ts +8 -0
  197. package/lib/src/shared/color-strategies/rte-color.js +16 -0
  198. package/lib/src/shared/color-strategies/rte-field-pairs.d.ts +23 -0
  199. package/lib/src/shared/color-strategies/rte-field-pairs.js +28 -0
  200. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +9 -135
  201. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +1 -27
  202. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +12 -2
  203. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +7 -0
  204. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +75 -6
  205. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +18 -7
  206. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +6 -1
  207. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +0 -7
  208. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +1 -0
  209. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +8 -4
  210. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1255 -26
  211. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +203 -59
  212. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +6 -0
  213. package/lib/src/shared/content-settings/store/content-settings-store.js +105 -8
  214. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +5 -1
  215. package/lib/src/shared/navigation-style-settings/store/index.d.ts +7 -3
  216. package/lib/src/shared/navigation-style-settings/store/index.js +40 -15
  217. package/lib/src/shared/page-settings/components/delete-page-modal/DeletePageModal.mixin.d.ts +1 -1
  218. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +1 -0
  219. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +17 -5
  220. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +70 -13
  221. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +10 -2
  222. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +2 -1
  223. package/lib/src/shared/page-settings/store/page-settings-store.js +17 -0
  224. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +4 -1
  225. package/lib/src/shared/rte-extensions/AutoLink.d.ts +17 -0
  226. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.js +67 -51
  227. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.js +4 -1
  228. package/lib/src/shared/rte-extensions/TextEffects.d.ts +28 -0
  229. package/lib/src/shared/rte-extensions/TextEffects.js +96 -0
  230. package/lib/src/shared/rte-extensions/ViewDomParser.d.ts +2 -0
  231. package/lib/src/shared/rte-extensions/ViewDomParser.js +21 -0
  232. package/lib/src/shared/rte-extensions.util.d.ts +25 -0
  233. package/lib/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.js → shared/rte-extensions.util.js} +62 -7
  234. package/lib/src/shared/rte-link.util.d.ts +1 -0
  235. package/lib/src/shared/rte-link.util.js +1 -0
  236. package/lib/src/shared/rte-render.util.d.ts +112 -0
  237. package/lib/src/shared/rte-render.util.js +255 -0
  238. package/lib/src/shared/rte-shape.util.d.ts +6 -0
  239. package/lib/src/shared/rte-shape.util.js +18 -0
  240. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +2 -1
  241. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
  242. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +2 -0
  243. package/lib/src/shared/side-bar/store/side-bar-store.js +9 -0
  244. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +155 -15
  245. package/lib/src/shared/style-settings/components/StyleSettings.mixin.js +7 -1
  246. package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -9
  247. package/lib/src/shared/style-settings/store/style-settings-store.js +3 -33
  248. package/lib/src/shared/style-settings/text-style-size-order.d.ts +2 -0
  249. package/lib/src/shared/style-settings/text-style-size-order.js +13 -0
  250. package/lib/src/shared/text-role-typography.util.d.ts +64 -0
  251. package/lib/src/shared/text-role-typography.util.js +183 -0
  252. package/lib/src/utils/minify-brand-page-metadata.d.ts +16 -1
  253. package/lib/src/utils/minify-brand-page-metadata.js +31 -9
  254. package/package.json +1 -1
  255. package/src/brand-page/__fixtures__/migration-22-v21/edited-brandsite-sections.v21.json +982 -0
  256. package/src/brand-page/__fixtures__/migration-22-v21/new-brandcontact-every-section.v21.json +1231 -0
  257. package/src/brand-page/__fixtures__/migration-22-v21/new-brandpage-every-section.v21.json +1231 -0
  258. package/src/brand-page/__fixtures__/migration-22-v21/new-brandsite-every-section.v21.json +1243 -0
  259. package/src/brand-page/__fixtures__/migration-22-v21/real-brandcontact.v21.json +755 -0
  260. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-general-link.v21.json +527 -0
  261. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-links.v21.json +755 -0
  262. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-social-links.v21.json +514 -0
  263. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-about.v21.json +459 -0
  264. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-footer.v21.json +469 -0
  265. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-header-banner.v21.json +481 -0
  266. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-sections.v21.json +800 -0
  267. package/src/brand-page/__fixtures__/production-text-style-resolver.fixture.ts +52 -0
  268. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +0 -10
  269. package/src/brand-page/components/contact-form/ContactForm.mixin.test.ts +127 -0
  270. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +31 -14
  271. package/src/brand-page/components/contact-form/ContactForm.vue +26 -12
  272. package/src/brand-page/components/contact-form/ContactForm.vue.test.ts +60 -0
  273. package/src/brand-page/components/mailing-list/MailingList.mixin.test.ts +92 -0
  274. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +28 -3
  275. package/src/brand-page/components/mailing-list/MailingList.vue +9 -4
  276. package/src/brand-page/components/mailing-list/MailingList.vue.test.ts +63 -0
  277. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.ts +51 -1
  278. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.test.ts +114 -0
  279. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.vue +8 -2
  280. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.test.ts +182 -0
  281. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +59 -12
  282. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +40 -3
  283. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue +15 -7
  284. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue.test.ts +133 -3
  285. package/src/brand-page/components/page/Page.mixin.ts +41 -34
  286. package/src/brand-page/components/page/Page.vue +17 -6
  287. package/src/brand-page/components/page/Page.vue.test.ts +91 -1
  288. package/src/brand-page/components/page-footer/PageFooter.mixin.ts +32 -2
  289. package/src/brand-page/components/page-footer/PageFooter.test.ts +79 -0
  290. package/src/brand-page/components/page-footer/PageFooter.vue +12 -4
  291. package/src/brand-page/components/payment/Payment.mixin.ts +34 -2
  292. package/src/brand-page/components/payment/Payment.test.ts +188 -0
  293. package/src/brand-page/components/payment/Payment.vue +12 -5
  294. package/src/brand-page/components/payment/RequestPaymentStripe.vue +1 -0
  295. package/src/brand-page/components/payment/support-me/SupportMe.mixin.ts +49 -2
  296. package/src/brand-page/components/payment/support-me/SupportMe.test.ts +100 -0
  297. package/src/brand-page/components/payment/support-me/SupportMe.vue +7 -1
  298. package/src/brand-page/components/payment/support-me/SupportMe.vue.test.ts +66 -0
  299. package/src/brand-page/components/save-contact/SaveContactWidget.test.ts +100 -0
  300. package/src/brand-page/components/save-contact/SaveContactWidget.vue +6 -3
  301. package/src/brand-page/components/shop/PaymentModal.vue +2 -6
  302. package/src/brand-page/components/shop/PaymentShippingAddress.vue +6 -0
  303. package/src/brand-page/components/shop/Shop.vue +15 -2
  304. package/src/brand-page/components/shop/Shop.vue.test.ts +74 -2
  305. package/src/brand-page/components/social-links/SocialLinks.stories.ts +0 -3
  306. package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +0 -3
  307. package/src/brand-page/components/testimonial-section/__fixtures__/data.ts +0 -3
  308. package/src/brand-page/components/text/Text.stories.ts +0 -17
  309. package/src/brand-page/components/text-wrapper/TextWrapper.parity.test.ts +136 -0
  310. package/src/brand-page/components/text-wrapper/TextWrapper.test.ts +358 -0
  311. package/src/brand-page/components/text-wrapper/TextWrapper.vue +82 -22
  312. package/src/brand-page/constants/font.constants.ts +37 -0
  313. package/src/brand-page/models/footer-icon-color.test.ts +22 -0
  314. package/src/brand-page/models/index.ts +50 -28
  315. package/src/brand-page/models/navigation-styles.model.test.ts +77 -1
  316. package/src/brand-page/models/navigation-styles.model.ts +26 -9
  317. package/src/brand-page/models/payment.model.ts +15 -6
  318. package/src/brand-page/models/styles.model.test.ts +104 -0
  319. package/src/brand-page/models/styles.model.ts +181 -47
  320. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +619 -115
  321. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +150 -9
  322. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +300 -18
  323. package/src/brand-page/utils/color-palette.util.test.ts +126 -1
  324. package/src/brand-page/utils/color-palette.util.ts +92 -26
  325. package/src/brand-page/utils/color.util.test.ts +62 -29
  326. package/src/brand-page/utils/color.util.ts +77 -14
  327. package/src/brand-page/utils/container-text-color.util.test.ts +672 -26
  328. package/src/brand-page/utils/container-text-color.util.ts +472 -46
  329. package/src/brand-page/utils/index.ts +1 -0
  330. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/edited-brandsite-sections.v22.json +1191 -0
  331. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandcontact-every-section.v22.json +2026 -0
  332. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandpage-every-section.v22.json +2017 -0
  333. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandsite-every-section.v22.json +2031 -0
  334. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandcontact.v22.json +1145 -0
  335. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-general-link.v22.json +645 -0
  336. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-links.v22.json +1136 -0
  337. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-social-links.v22.json +662 -0
  338. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-about.v22.json +638 -0
  339. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-footer.v22.json +610 -0
  340. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-header-banner.v22.json +660 -0
  341. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-sections.v22.json +1132 -0
  342. package/src/brand-page/utils/migration/migration-01.ts +293 -237
  343. package/src/brand-page/utils/migration/migration-02.ts +8 -1
  344. package/src/brand-page/utils/migration/migration-20.ts +6 -3
  345. package/src/brand-page/utils/migration/migration-20_5.test.ts +5 -2
  346. package/src/brand-page/utils/migration/migration-21.test.ts +34 -0
  347. package/src/brand-page/utils/migration/migration-21.ts +46 -10
  348. package/src/brand-page/utils/migration/migration-22.fixed-input.test.ts +43 -0
  349. package/src/brand-page/utils/migration/migration-22.test.ts +4103 -0
  350. package/src/brand-page/utils/migration/migration-22.text-font-family.test.ts +72 -0
  351. package/src/brand-page/utils/migration/migration-22.ts +1336 -0
  352. package/src/brand-page/utils/migration.util.test.ts +146 -32
  353. package/src/brand-page/utils/migration.util.ts +18 -0
  354. package/src/brand-page/utils/model.util.ts +4 -0
  355. package/src/brand-page/utils/personalisation.util.test.ts +148 -3
  356. package/src/brand-page/utils/personalisation.util.ts +9 -1
  357. package/src/brand-page/utils/rte-role-lift.util.ts +409 -0
  358. package/src/brand-page/utils/style.util.test.ts +35 -2
  359. package/src/brand-page/utils/style.util.ts +45 -11
  360. package/src/brand-page/utils/text-role-css.util.test.ts +525 -0
  361. package/src/brand-page/utils/text-role-css.util.ts +321 -0
  362. package/src/brand-page/utils/text-role-reconnect.util.test.ts +604 -0
  363. package/src/brand-page/utils/text-role-reconnect.util.ts +727 -0
  364. package/src/brand-page/utils/text-style.util.test.ts +305 -0
  365. package/src/brand-page/utils/text-style.util.ts +198 -24
  366. package/src/brand-page/utils/view-model.page-data.test.ts +232 -0
  367. package/src/brand-page/utils/view-model.util.test.ts +954 -133
  368. package/src/brand-page/utils/view-model.util.ts +187 -139
  369. package/src/brand-page/view-models.ts +4 -0
  370. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.blank-site.test.ts +57 -0
  371. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +9 -5
  372. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -10
  373. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +0 -1
  374. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +0 -44
  375. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +253 -200
  376. package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -0
  377. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +1 -0
  378. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +2 -0
  379. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +1 -0
  380. package/src/brand-page-maker/composables/rich-text-editor/block-typography.test.ts +519 -0
  381. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +1 -1
  382. package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +26 -1
  383. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.test.ts +110 -0
  384. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.ts +99 -0
  385. package/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.ts +397 -0
  386. package/src/brand-page-maker/composables/rich-text-editor/extensions/ViewDomParser.test.ts +139 -0
  387. package/src/brand-page-maker/composables/rich-text-editor/font.ts +36 -5
  388. package/src/brand-page-maker/composables/rich-text-editor/formatting.test.ts +375 -1
  389. package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +301 -17
  390. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.test.ts +82 -1
  391. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +28 -34
  392. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.test.ts +80 -0
  393. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.ts +75 -0
  394. package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +31 -6
  395. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.test.ts +2485 -0
  396. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +435 -337
  397. package/src/brand-page-maker/constants/config-settings-constant.ts +0 -6
  398. package/src/brand-page-maker/convertors/text-css-style-options.convertor.test.ts +43 -0
  399. package/src/brand-page-maker/convertors/text-css-style-options.convertor.ts +6 -2
  400. package/src/brand-page-maker/convertors/text-size-value.convertor.test.ts +24 -0
  401. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +17 -13
  402. package/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.ts +7 -22
  403. package/src/brand-page-maker/default-getters/text-color.default-getter.ts +5 -21
  404. package/src/brand-page-maker/models/content-settings.test.ts +708 -0
  405. package/src/brand-page-maker/models/content-settings.ts +133 -82
  406. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.test.ts +63 -1
  407. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.ts +16 -3
  408. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.test.ts +34 -0
  409. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +4 -2
  410. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +185 -1
  411. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +22 -34
  412. package/src/brand-page-maker/stores/history/history-store.ts +35 -2
  413. package/src/brand-page-maker/utils/__snapshots__/apply-color-strategy.golden.test.ts.snap +528 -0
  414. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +12 -0
  415. package/src/brand-page-maker/utils/apply-color-strategy.golden.test.ts +2 -0
  416. package/src/brand-page-maker/utils/apply-color-strategy.test.ts +181 -3
  417. package/src/brand-page-maker/utils/apply-color-strategy.ts +36 -4
  418. package/src/brand-page-maker/utils/index.ts +2 -1
  419. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +447 -410
  420. package/src/brand-page-maker/utils/rich-text-editor.util.ts +610 -506
  421. package/src/brand-page-maker/utils/rte-authoring.util.test.ts +244 -0
  422. package/src/brand-page-maker/utils/rte-authoring.util.ts +175 -0
  423. package/src/brand-page-maker/utils/rte-clipboard.util.test.ts +558 -0
  424. package/src/brand-page-maker/utils/rte-clipboard.util.ts +473 -0
  425. package/src/brand-page-maker/utils/rte-features.test.ts +99 -3
  426. package/src/brand-page-maker/utils/rte-render-parity.test.ts +1 -1
  427. package/src/brand-page-maker/utils/rte-render.util.test.ts +230 -0
  428. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +1 -1
  429. package/src/brand-page-maker/utils/rte-sanitize.util.ts +14 -3
  430. package/src/brand-page-maker/utils/rte-schema-version.test.ts +102 -0
  431. package/src/bundles/bundled-translations.de-DE.json +21 -2
  432. package/src/bundles/bundled-translations.es-ES.json +21 -2
  433. package/src/bundles/bundled-translations.fr-CA.json +21 -2
  434. package/src/bundles/bundled-translations.fr-FR.json +21 -2
  435. package/src/bundles/bundled-translations.json +21 -2
  436. package/src/bundles/bundled-translations.pt-BR.json +21 -2
  437. package/src/bundles/bundled-translations.pt-PT.json +21 -2
  438. package/src/clients/ai-assistant-client.ts +1 -0
  439. package/src/composables/useTranslate.ts +2 -1
  440. package/src/lib.ts +2 -2
  441. package/src/metadata-builder/builders/footer-builder.test.ts +70 -45
  442. package/src/metadata-builder/builders/footer-builder.ts +4 -8
  443. package/src/metadata-builder/builders/global-role-propagation.test.ts +907 -0
  444. package/src/metadata-builder/builders/global-role-propagation.ts +430 -0
  445. package/src/metadata-builder/builders/global-styles-builder.test.ts +1020 -0
  446. package/src/metadata-builder/builders/global-styles-builder.ts +194 -48
  447. package/src/metadata-builder/builders/header-builder.test.ts +112 -40
  448. package/src/metadata-builder/builders/header-builder.ts +18 -8
  449. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +5 -3
  450. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +5 -3
  451. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -3
  452. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +7 -4
  453. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +5 -3
  454. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +3 -2
  455. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +3 -2
  456. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +7 -7
  457. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +5 -3
  458. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +2 -2
  459. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +21 -10
  460. package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +10 -0
  461. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +3 -2
  462. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +111 -61
  463. package/src/metadata-builder/builders/section-field-maps.ts +1 -0
  464. package/src/metadata-builder/builders/section-field-utils.test.ts +545 -2
  465. package/src/metadata-builder/builders/section-field-utils.ts +202 -69
  466. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +38 -13
  467. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +5 -0
  468. package/src/metadata-builder/helpers/rte.helpers.test.ts +101 -0
  469. package/src/metadata-builder/helpers/rte.helpers.ts +129 -43
  470. package/src/metadata-builder/metadata-executor.test.ts +167 -0
  471. package/src/metadata-builder/metadata-executor.ts +34 -1
  472. package/src/metadata-builder/models.ts +2 -0
  473. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +23 -7
  474. package/src/metadata-builder/parsers/section-tool-arguments.ts +21 -1
  475. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +215 -0
  476. package/src/metadata-builder/sanitizers/rte-schema-check.ts +1 -1
  477. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +4 -8
  478. package/src/metadata-builder/sanitizers/section-args-validator.ts +136 -53
  479. package/src/shared/color-palette/section-color-matches.test.ts +15 -11
  480. package/src/shared/color-palette/section-color-matches.ts +9 -28
  481. package/src/shared/color-strategies/color-strategies.ts +35 -0
  482. package/src/shared/color-strategies/rte-color.test.ts +1 -1
  483. package/src/shared/color-strategies/rte-color.ts +19 -0
  484. package/src/shared/color-strategies/rte-field-pairs.test.ts +26 -5
  485. package/src/shared/color-strategies/rte-field-pairs.ts +33 -0
  486. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.test.ts +43 -66
  487. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.vue +7 -1
  488. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -48
  489. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +33 -7
  490. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.test.ts +128 -1
  491. package/src/shared/content-settings/components/draggable-item-list/DraggableItemList.vue +1 -0
  492. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +0 -6
  493. package/src/shared/content-settings/components/logo-selection-field/LogoSelection.vue +3 -0
  494. package/src/shared/content-settings/components/logo-size-field/LogoSizeSlider.vue +3 -0
  495. package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -0
  496. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +1 -0
  497. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.test.ts +56 -3
  498. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +11 -4
  499. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.test.ts +335 -25
  500. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +248 -70
  501. package/src/shared/content-settings/components/text-style-field/TextStyleField.vue +113 -25
  502. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.de-DE.json +17 -10
  503. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.es-ES.json +17 -10
  504. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-CA.json +17 -10
  505. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-FR.json +17 -10
  506. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.json +8 -1
  507. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-BR.json +17 -10
  508. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-PT.json +17 -10
  509. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.test.ts +141 -0
  510. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.vue +136 -0
  511. package/src/shared/content-settings/store/content-settings-store.test.ts +491 -6
  512. package/src/shared/content-settings/store/content-settings-store.ts +159 -17
  513. package/src/shared/logo-settings/components/EditLogoSettings.vue +1 -0
  514. package/src/shared/logo-settings/components/LogoVariations.vue +1 -0
  515. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -0
  516. package/src/shared/navigation-style-settings/store/index.test.ts +295 -0
  517. package/src/shared/navigation-style-settings/store/index.ts +65 -15
  518. package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.vue +2 -0
  519. package/src/shared/page-settings/components/page-settings/PageElement.vue +1 -0
  520. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.test.ts +44 -4
  521. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.vue +13 -4
  522. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.navigation.test.ts +89 -0
  523. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.text-style.test.ts +91 -0
  524. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +14 -2
  525. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.vue +2 -0
  526. package/src/shared/page-settings/store/page-settings-store.text-style.test.ts +84 -0
  527. package/src/shared/page-settings/store/page-settings-store.ts +30 -1
  528. package/src/shared/rte-extensions/AutoLink.test.ts +98 -0
  529. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.ts +87 -58
  530. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.ts +4 -1
  531. package/src/shared/rte-extensions/TextEffects.ts +151 -0
  532. package/src/shared/rte-extensions/ViewDomParser.ts +27 -0
  533. package/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.ts → shared/rte-extensions.util.ts} +66 -9
  534. package/src/shared/rte-link.util.ts +2 -0
  535. package/src/shared/rte-render.util.ts +385 -0
  536. package/src/shared/rte-shape.util.ts +29 -0
  537. package/src/shared/side-bar/store/side-bar-store.test.ts +27 -1
  538. package/src/shared/side-bar/store/side-bar-store.ts +11 -0
  539. package/src/shared/style-settings/components/StyleSettings.mixin.ts +7 -3
  540. package/src/shared/style-settings/components/StyleSettings.test.ts +116 -0
  541. package/src/shared/style-settings/components/StyleSettings.vue +75 -25
  542. package/src/shared/style-settings/components/i18n/style-settings.de-DE.json +32 -20
  543. package/src/shared/style-settings/components/i18n/style-settings.es-ES.json +32 -20
  544. package/src/shared/style-settings/components/i18n/style-settings.fr-CA.json +32 -20
  545. package/src/shared/style-settings/components/i18n/style-settings.fr-FR.json +32 -20
  546. package/src/shared/style-settings/components/i18n/style-settings.json +13 -3
  547. package/src/shared/style-settings/components/i18n/style-settings.pt-BR.json +32 -20
  548. package/src/shared/style-settings/components/i18n/style-settings.pt-PT.json +32 -20
  549. package/src/shared/style-settings/components/text-style-options-settings-with-state/TextStyleOptionsSettingsWithState.vue +14 -34
  550. package/src/shared/style-settings/store/style-settings-store.ts +3 -49
  551. package/src/shared/style-settings/text-style-size-order.test.ts +76 -0
  552. package/src/shared/style-settings/text-style-size-order.ts +28 -0
  553. package/src/shared/template-settings/components/TemplatesSettings.vue +4 -0
  554. package/src/shared/text-role-typography.util.ts +277 -0
  555. package/src/utils/minify-brand-page-metadata.test.ts +102 -7
  556. package/src/utils/minify-brand-page-metadata.ts +62 -8
  557. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +0 -2
  558. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  559. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
  560. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -106
  561. package/lib/src/brand-page-maker/utils/rte-shape.d.ts +0 -18
  562. package/lib/src/brand-page-maker/utils/rte-shape.js +0 -21
  563. package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +0 -41
  564. package/lib/src/metadata-builder/builders/global-font-propagation.js +0 -146
  565. package/src/brand-page-maker/utils/rte-render.util.ts +0 -179
  566. package/src/brand-page-maker/utils/rte-shape.ts +0 -29
  567. package/src/metadata-builder/builders/global-font-propagation.test.ts +0 -401
  568. package/src/metadata-builder/builders/global-font-propagation.ts +0 -238
  569. package/src/shared/style-settings/components/StyleSettingsSection.vue +0 -8
  570. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.d.ts +0 -0
  571. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.js +0 -0
  572. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.d.ts +0 -0
  573. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.js +0 -0
  574. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.d.ts +0 -0
  575. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.ts +0 -0
  576. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.ts +0 -0
@@ -0,0 +1,385 @@
1
+ import { getSchema } from '@tiptap/core';
2
+ import {
3
+ DOMParser as ProseMirrorDOMParser,
4
+ Node as ProseMirrorNode,
5
+ type Mark as ProseMirrorMark,
6
+ } from '@tiptap/pm/model';
7
+ import type { JSONContent } from '@tiptap/vue-3';
8
+ import { renderToHTMLString } from '@tiptap/static-renderer/pm/html-string';
9
+ import { getRteExtensions, rteSchemaGeneration } from './rte-extensions.util';
10
+ import { isTiptapDocument, getRteJsonPlainText } from './rte-shape.util';
11
+ import { ESCAPED_NEWLINE_CHARACTER } from '@src/constants/ui';
12
+
13
+ export { isTiptapDocument, getRteJsonPlainText };
14
+
15
+ /**
16
+ * BP-5787 — the boundary plumbing for storing RTE as Tiptap JSON.
17
+ *
18
+ * An RTE field is either a legacy inline-HTML string (pre-migration, or a
19
+ * not-yet-migrated published site) or a Tiptap JSON document (post-migration).
20
+ * These helpers let every consumer treat the two uniformly:
21
+ *
22
+ * - isTiptapDocument — the canonical discriminator (object with type 'doc').
23
+ * - renderRteToHtml — render either form to final HTML for display.
24
+ * - toRteJson — normalise either form to JSON for storage.
25
+ *
26
+ * The schema-driven core of both directions is Tiptap/ProseMirror, fed by the
27
+ * single-source-of-truth extension set (getRteExtensions) — so the mapping lives
28
+ * in the extensions' schema, not a hand-maintained copy that drifts:
29
+ *
30
+ * - renderRteToHtml uses @tiptap/static-renderer (renderToHTMLString). It is
31
+ * DOM-less, so it runs on the server (SSR/publish/preview), not just the
32
+ * browser, and needs no Editor instance.
33
+ * - toRteJson turns an HTML string into a DOM node with an INJECTED parser and
34
+ * feeds it to ProseMirror's schema-driven DOMParser. The HTML→DOM step needs
35
+ * a DOM parser; rather than read the global `window.DOMParser` (as Tiptap's
36
+ * `generateJSON` does — unusable on a pure-node server and fragile across SSR
37
+ * execution contexts), the parser is supplied by the caller: the native
38
+ * `DOMParser` in the browser, a jsdom `DOMParser` *instance* on the server
39
+ * (see resolveHtmlParser). No global is ever mutated, so the conversion is
40
+ * fully isomorphic regardless of how the SSR host bundles/executes this code.
41
+ */
42
+ export type RichTextValue = string | JSONContent;
43
+
44
+ // One extension set shared by both directions (render + parse). Schema knowledge
45
+ // lives here, once — Tiptap/extension upgrades propagate to both automatically.
46
+ const RTE_EXTENSIONS = getRteExtensions();
47
+ const RTE_EXTENSIONS_WITH_DECORATION_CLASSES = getRteExtensions({
48
+ renderTextDecorationClasses: true,
49
+ });
50
+
51
+ // ProseMirror schema derived once from the shared extension set. This is the
52
+ // schema-driven heart of HTML→JSON (no drift); only the HTML→DOM step is injected.
53
+ const RTE_SCHEMA = getSchema(RTE_EXTENSIONS);
54
+
55
+ // One ProseMirror schema per schema GENERATION, built once each. `rteSchemaGeneration` collapses a
56
+ // requested version to its range, so every version in a range shares one built schema (5 and 20 both
57
+ // use the base; 22 and the latest share the newest). A migration passes its own model version so its
58
+ // HTML→JSON parse reproduces that range's schema and can't drift when the live schema gains an
59
+ // extension; runtime (renderer, factories) omits it and uses the latest. RTE_SCHEMA is the latest,
60
+ // so it seeds the newest generation and isn't rebuilt.
61
+ const schemaByGeneration = new Map<number, ReturnType<typeof getSchema>>([
62
+ [rteSchemaGeneration(undefined), RTE_SCHEMA],
63
+ ]);
64
+
65
+ const rteSchemaForVersion = (
66
+ schemaVersion?: number,
67
+ ): ReturnType<typeof getSchema> => {
68
+ const generation = rteSchemaGeneration(schemaVersion);
69
+ let schema = schemaByGeneration.get(generation);
70
+
71
+ if (!schema) {
72
+ schema = getSchema(getRteExtensions({ schemaVersion }));
73
+ schemaByGeneration.set(generation, schema);
74
+ }
75
+
76
+ return schema;
77
+ };
78
+
79
+ /**
80
+ * A `DOMParser`-compatible object: turns an HTML string into a Document whose
81
+ * `body` is a DOM node ProseMirror can parse. The browser's native `DOMParser`
82
+ * and jsdom's `DOMParser` both satisfy this, so the DOM dependency is injected
83
+ * rather than read from a global.
84
+ */
85
+ export interface HtmlParser {
86
+ parseFromString(html: string, type: 'text/html'): Document;
87
+ }
88
+
89
+ /**
90
+ * Render an RTE value to final HTML. Legacy HTML strings pass through untouched
91
+ * (they are already HTML); Tiptap JSON is serialised by @tiptap/static-renderer
92
+ * from the extension schema — no editor, no DOM — so it works on the server
93
+ * (SSR/publish), not just the browser.
94
+ *
95
+ * MIGRATION-22 SNAPSHOT DEPENDENCY: B1 uses this module's plain-text conversion and parser seam.
96
+ * Pin that v22 conversion before changing it after migration-22 releases.
97
+ */
98
+ export const renderRteToHtml = (
99
+ value: RichTextValue | null | undefined,
100
+ options: { textDecorationClasses?: boolean } = {},
101
+ ): string => {
102
+ if (value == null || value === '') return '';
103
+
104
+ if (typeof value === 'string') return value;
105
+
106
+ try {
107
+ return renderToHTMLString({
108
+ content: value,
109
+ extensions: options.textDecorationClasses
110
+ ? RTE_EXTENSIONS_WITH_DECORATION_CLASSES
111
+ : RTE_EXTENSIONS,
112
+ });
113
+ } catch (error) {
114
+ // renderToHTMLString throws on a node/mark type this renderer's schema
115
+ // doesn't know. The realistic trigger is version skew — the library ships to
116
+ // multiple apps, so a maker on a newer schema can persist a node an older
117
+ // deployed renderer can't render. Degrade to visible text rather than let
118
+ // one field throw out of its (unguarded) computed and 500 the whole page.
119
+ console.error(
120
+ 'renderRteToHtml: unrenderable doc, falling back to plain text',
121
+ error,
122
+ );
123
+
124
+ return getRteJsonPlainText(value);
125
+ }
126
+ };
127
+
128
+ // Tiptap's elementFromString strips whitespace-only text nodes (pretty-print
129
+ // indentation between tags) before parsing; replicate it so injected-parser
130
+ // output stays identical to the previous generateJSON-based conversion.
131
+ const stripIndentationTextNodes = (node: Node): Node => {
132
+ const children = node.childNodes;
133
+
134
+ for (let i = children.length - 1; i >= 0; i -= 1) {
135
+ const child = children[i];
136
+
137
+ if (
138
+ child.nodeType === 3 &&
139
+ child.nodeValue &&
140
+ /^(\n\s\s|\n)$/.test(child.nodeValue)
141
+ ) {
142
+ node.removeChild(child);
143
+ } else if (child.nodeType === 1) {
144
+ stripIndentationTextNodes(child);
145
+ }
146
+ }
147
+
148
+ return node;
149
+ };
150
+
151
+ const htmlToRteJson = (
152
+ html: string,
153
+ parser: HtmlParser,
154
+ schemaVersion?: number,
155
+ ): JSONContent => {
156
+ const body = parser.parseFromString(`<body>${html}</body>`, 'text/html').body;
157
+ const dom = stripIndentationTextNodes(body);
158
+
159
+ return ProseMirrorDOMParser.fromSchema(rteSchemaForVersion(schemaVersion))
160
+ .parse(dom)
161
+ .toJSON();
162
+ };
163
+
164
+ let serverParserPromise: Promise<HtmlParser> | null = null;
165
+
166
+ /**
167
+ * Resolve an HtmlParser for the current runtime: the native `DOMParser` in the
168
+ * browser (and jsdom-based test envs), or a jsdom `DOMParser` INSTANCE on a
169
+ * pure-node server — created and returned directly, never assigned to a global,
170
+ * so it is immune to SSR execution-context differences. The jsdom specifier is
171
+ * assembled at runtime so no bundler follows it into a browser build. Memoised
172
+ * on the server (JSDOM construction is relatively expensive).
173
+ */
174
+ export const resolveHtmlParser = async (): Promise<HtmlParser> => {
175
+ if (typeof DOMParser !== 'undefined') return new DOMParser();
176
+
177
+ if (!serverParserPromise) {
178
+ const jsdomModuleId = ['js', 'dom'].join('');
179
+
180
+ serverParserPromise = import(/* @vite-ignore */ jsdomModuleId)
181
+ .then((mod) => {
182
+ const { JSDOM } = mod as {
183
+ JSDOM: new (html?: string) => {
184
+ window: { DOMParser: new () => HtmlParser };
185
+ };
186
+ };
187
+ const { DOMParser: JsdomDOMParser } = new JSDOM('').window;
188
+
189
+ return new JsdomDOMParser();
190
+ })
191
+ .catch((error) => {
192
+ // Don't cache the failure — let a later call retry the import.
193
+ serverParserPromise = null;
194
+
195
+ throw error;
196
+ });
197
+ }
198
+
199
+ return serverParserPromise;
200
+ };
201
+
202
+ const getDefaultParser = (): HtmlParser => {
203
+ if (typeof DOMParser !== 'undefined') return new DOMParser();
204
+
205
+ throw new Error(
206
+ 'toRteJson: no global DOMParser in this environment. On the server, pass an ' +
207
+ 'explicit parser as the second argument (see resolveHtmlParser).',
208
+ );
209
+ };
210
+
211
+ /**
212
+ * Normalise an RTE value to a Tiptap JSON document. HTML strings are parsed with
213
+ * `parser` (defaults to the browser's native DOMParser); JSON documents pass
214
+ * through unchanged. Returns undefined for empty/blank input so callers can omit
215
+ * empty fields. `schemaVersion` pins the parse schema — a migration passes its own
216
+ * version so its output can't drift when the live schema gains an extension;
217
+ * everything else omits it and parses with the latest.
218
+ */
219
+ export const toRteJson = (
220
+ value: RichTextValue | null | undefined,
221
+ parser?: HtmlParser,
222
+ schemaVersion?: number,
223
+ ): JSONContent | undefined => {
224
+ if (value == null || value === '') return undefined;
225
+
226
+ if (isTiptapDocument(value)) return value;
227
+
228
+ return htmlToRteJson(value, parser ?? getDefaultParser(), schemaVersion);
229
+ };
230
+
231
+ // Twin of getRenderText (brand-page/utils/text.util) — the plain-text renderer's
232
+ // newline shim, applied on the way INTO the parser instead of at display time.
233
+ const NEWLINE_TO_BR = new RegExp(`(${ESCAPED_NEWLINE_CHARACTER}|\\n)`, 'g');
234
+
235
+ /**
236
+ * Convert a PLAIN-TEXT field to a Tiptap JSON document. Plain-text fields persist
237
+ * newlines percent-encoded (`ESCAPED_NEWLINE_CHARACTER`, `%0A`); fed straight to the
238
+ * HTML parser those survive as a literal `"%0A"` run with the line structure lost, so
239
+ * we first turn them (and any raw `\n`) into `<br>` — the same shim the retired runtime
240
+ * rewrap applied via getRenderText before `setContent`. Guarded on `%0A` so a legacy
241
+ * RTE-HTML string (whose pretty-print `\n` must stay insignificant whitespace, stripped
242
+ * by `stripIndentationTextNodes`) is passed through untouched. JSON docs pass through.
243
+ */
244
+ export const plainTextToRteJson = (
245
+ value: RichTextValue | null | undefined,
246
+ parser?: HtmlParser,
247
+ schemaVersion?: number,
248
+ ): JSONContent | undefined => {
249
+ const prepared =
250
+ typeof value === 'string' && value.includes(ESCAPED_NEWLINE_CHARACTER)
251
+ ? value.replace(NEWLINE_TO_BR, '<br/>')
252
+ : value;
253
+
254
+ return toRteJson(prepared, parser, schemaVersion);
255
+ };
256
+
257
+ // The canonical empty document (a single empty paragraph), built from the schema — no DOM, SSR-safe.
258
+ const emptyRteDoc = (): JSONContent =>
259
+ RTE_SCHEMA.topNodeType.createAndFill()!.toJSON() as JSONContent;
260
+
261
+ /**
262
+ * BP-5969 — build the Tiptap doc a factory stores for an RTE field: the RTE-JSON **source** that
263
+ * replaces the plain-string-then-convert seam. STRUCTURE only (paragraph + text + `textAlign`) —
264
+ * colour and role typography are baked afterwards by the init step (`applyTextContrast` +
265
+ * `authorContentRteFields`), since colour is contrast-derived and must not be duplicated per factory.
266
+ * Schema-built (never a hand-written literal), so it stays valid and matches migration output.
267
+ *
268
+ * Empty text → an empty paragraph (still a doc, never a string). A ProseMirror text node cannot be
269
+ * empty, so an empty field has no run: its colour then lives on the style object until the user types,
270
+ * when `buildInitialMarks` seeds the first run from it.
271
+ */
272
+ export const rteDoc = (
273
+ text: string,
274
+ textAlign?: string,
275
+ parser?: HtmlParser,
276
+ ): JSONContent => {
277
+ const doc =
278
+ typeof text === 'string' && text.length > 0
279
+ ? (plainTextToRteJson(text, parser) ?? emptyRteDoc())
280
+ : emptyRteDoc();
281
+
282
+ if (textAlign) {
283
+ for (const block of doc.content ?? []) {
284
+ block.attrs = { ...(block.attrs ?? {}), textAlign };
285
+ }
286
+ }
287
+
288
+ return doc;
289
+ };
290
+
291
+ // A plain-text field's line breaks: the escaped-newline token (`%0A`) or a real newline. Non-capturing
292
+ // so `split` yields only the lines. `plainTextToRteJson` turns the same breaks into `<br>`; the reflow
293
+ // makes each line its own paragraph instead.
294
+ const REFLOW_LINE_BREAK = new RegExp(`${ESCAPED_NEWLINE_CHARACTER}|\\r?\\n`);
295
+
296
+ // The mark carrying a run's colour + role-var typography (family/size/weight/…). It is the ONLY mark
297
+ // the reflow carries onto new text — per-word marks (link/highlight) can't meaningfully apply to
298
+ // different copy, so they are dropped.
299
+ const TEXT_STYLE_MARK_NAME = 'textStyle';
300
+
301
+ /**
302
+ * Build a schema-valid doc from plain text: ONE paragraph, its lines joined by `hardBreak`s, every run
303
+ * stamped with `styleMarks` and the block with `textAlign`. A hard break (not a paragraph per line)
304
+ * matches how `plainTextToRteJson` — and so the template's own authoring — turns `%0A` into a `<br>`,
305
+ * so the reflow introduces no inter-paragraph spacing the template never had. `schema.text` throws on
306
+ * an empty string, so an empty line contributes only its break; empty text yields an empty paragraph.
307
+ * The library owns validity — `schema.text` / `NodeType.create`, never a JSON literal — so no DOM parser.
308
+ */
309
+ const buildStyledDoc = (
310
+ text: string,
311
+ styleMarks: readonly ProseMirrorMark[],
312
+ textAlign?: unknown,
313
+ ): JSONContent => {
314
+ const { paragraph, hardBreak } = RTE_SCHEMA.nodes;
315
+ const attrs = textAlign ? { textAlign } : null;
316
+
317
+ const inline: ProseMirrorNode[] = [];
318
+
319
+ text.split(REFLOW_LINE_BREAK).forEach((line, index) => {
320
+ if (index > 0) inline.push(hardBreak.create());
321
+
322
+ if (line) inline.push(RTE_SCHEMA.text(line, styleMarks));
323
+ });
324
+
325
+ return RTE_SCHEMA.topNodeType
326
+ .create(null, paragraph.create(attrs, inline))
327
+ .toJSON() as JSONContent;
328
+ };
329
+
330
+ /**
331
+ * BP-5969 — inject `newText` into a template RTE doc while KEEPING the template's embedded style.
332
+ * Personalisation supplies only plain text; writing it raw drops the doc and its style (colour +
333
+ * typography live in the run marks). This lifts the template's **style skeleton** — the FIRST text
334
+ * run's `textStyle` mark (colour + role-var refs + any literal override) and the first block's
335
+ * alignment — and reflows the new text through it: a single paragraph whose lines join with hard
336
+ * breaks (matching how plain text is authored), every run carrying that mark. Per-word variation (a
337
+ * coloured word, an inline link) collapses to the base style — an accepted, documented loss; a
338
+ * uniformly-styled field comes out identical.
339
+ *
340
+ * The library owns schema handling: `Node.fromJSON` validates the template and hydrates real marks,
341
+ * `schema.text` applies them. No hand-written JSON and no `DOMParser`, so it is isomorphic — it runs
342
+ * on the server draft path where an editor or an HTML parse could not. The linked role lives on the
343
+ * sibling style object (`textStyleType`), untouched here, so the reflowed block still repaints on a
344
+ * role edit.
345
+ *
346
+ * A template that cannot be parsed, or that has no styled run, degrades to unstyled reflow rather than
347
+ * throwing — one bad field must not abort a whole personalisation pass.
348
+ */
349
+ export const reflowRteDoc = (
350
+ templateDoc: JSONContent,
351
+ newText: string,
352
+ ): JSONContent => {
353
+ try {
354
+ const doc = ProseMirrorNode.fromJSON(RTE_SCHEMA, templateDoc);
355
+
356
+ // The FIRST text run is the base style. `descendants` has no early-abort (returning false skips a
357
+ // node's children but still visits siblings), so a flag stops us overwriting from later runs.
358
+ let styleMarks: readonly ProseMirrorMark[] = [];
359
+ let found = false;
360
+
361
+ doc.descendants((node) => {
362
+ if (found) return false;
363
+
364
+ if (node.isText) {
365
+ styleMarks = node.marks.filter(
366
+ (mark) => mark.type.name === TEXT_STYLE_MARK_NAME,
367
+ );
368
+ found = true;
369
+
370
+ return false;
371
+ }
372
+
373
+ return true;
374
+ });
375
+
376
+ return buildStyledDoc(newText, styleMarks, doc.firstChild?.attrs.textAlign);
377
+ } catch (error) {
378
+ console.error(
379
+ 'reflowRteDoc: unusable template doc, reflowing without style',
380
+ error,
381
+ );
382
+
383
+ return buildStyledDoc(newText, []);
384
+ }
385
+ };
@@ -0,0 +1,29 @@
1
+ import type { JSONContent } from '@tiptap/vue-3';
2
+
3
+ /** Canonical discriminator for the JSON RTE model. */
4
+ export const isTiptapDocument = (value: unknown): value is JSONContent =>
5
+ typeof value === 'object' &&
6
+ value !== null &&
7
+ (value as JSONContent).type === 'doc';
8
+
9
+ /** A legacy inline-HTML RTE string, rather than arbitrary text containing angle brackets. */
10
+ export const isRteHtmlString = (value: unknown): value is string =>
11
+ typeof value === 'string' &&
12
+ value.length > 0 &&
13
+ /^<[A-Za-z][A-Za-z0-9-]*\b[^>]*>[\s\S]*<\/[A-Za-z][A-Za-z0-9-]*>$/.test(
14
+ value.trim(),
15
+ );
16
+
17
+ export const getRteJsonPlainText = (doc: JSONContent): string => {
18
+ const parts: string[] = [];
19
+
20
+ const walk = (node: JSONContent): void => {
21
+ if (typeof node.text === 'string') parts.push(node.text);
22
+
23
+ node.content?.forEach(walk);
24
+ };
25
+
26
+ walk(doc);
27
+
28
+ return parts.join(' ').replace(/\s+/g, ' ').trim();
29
+ };
@@ -1,6 +1,9 @@
1
1
  import { describe, test, expect, beforeEach } from 'vitest';
2
2
  import { createPinia, setActivePinia } from 'pinia';
3
- import { useUiSideBarStore } from './side-bar-store';
3
+ import {
4
+ TEXT_STYLES_SETTINGS_SECTION,
5
+ useUiSideBarStore,
6
+ } from './side-bar-store';
4
7
  import {
5
8
  PAGE_SETTINGS_SECTIONS,
6
9
  useUiPageSettingsStore,
@@ -122,3 +125,26 @@ describe('side-bar store — tab switches clear a leftover content-settings mode
122
125
  );
123
126
  });
124
127
  });
128
+
129
+ describe('side-bar store — openTextStyles', () => {
130
+ beforeEach(() => {
131
+ setActivePinia(createPinia());
132
+ });
133
+
134
+ test('openTextStyles opens the Style tab at the Text Styles section', () => {
135
+ const sideBarStore = useUiSideBarStore();
136
+
137
+ sideBarStore.setSelectedTabName({
138
+ tabName: SIDE_BAR_TAB_NAMES.CONTENT_SETTINGS,
139
+ });
140
+
141
+ sideBarStore.openTextStyles();
142
+
143
+ expect(sideBarStore.selectedTabName).toBe(
144
+ SIDE_BAR_TAB_NAMES.STYLE_SETTINGS,
145
+ );
146
+ expect(sideBarStore.selectedSettingsSection).toBe(
147
+ TEXT_STYLES_SETTINGS_SECTION,
148
+ );
149
+ });
150
+ });
@@ -11,6 +11,9 @@ import {
11
11
  } from '../../page-settings/store';
12
12
  import { useUiContentSettingsStore } from '../../content-settings/store';
13
13
 
14
+ // The Style tab's Text Styles panel, which "Edit Text Styles" in a role dropdown opens.
15
+ export const TEXT_STYLES_SETTINGS_SECTION = 'textStyles';
16
+
14
17
  export interface SideBarState {
15
18
  tabs: SideBarTab[];
16
19
  selectedTabName: string;
@@ -77,5 +80,13 @@ export const useUiSideBarStore = defineStore('uiSideBar', {
77
80
  setSelectedSettingsSection(payload: { sectionName?: string }) {
78
81
  this.selectedSettingsSection = payload.sectionName;
79
82
  },
83
+
84
+ // The section is set first: the Style tab mounts on the switch and scrolls to it.
85
+ openTextStyles(): void {
86
+ this.setSelectedSettingsSection({
87
+ sectionName: TEXT_STYLES_SETTINGS_SECTION,
88
+ });
89
+ this.setSelectedTabName({ tabName: SIDE_BAR_TAB_NAMES.STYLE_SETTINGS });
90
+ },
80
91
  },
81
92
  });
@@ -18,6 +18,7 @@ import {
18
18
  useEventTracker,
19
19
  } from '@brand-page-maker/composables/useEventTracker';
20
20
  import { styleSettingsTr } from '@src/composables/useTranslate';
21
+ import { hasTextStyleSizeOrderIssue } from '../text-style-size-order';
21
22
  import { WEBSITE_UPGRADE_CONTEXT_TYPES } from '@designcrowd/fe-shared-lib';
22
23
 
23
24
  export default defineComponent({
@@ -47,9 +48,6 @@ export default defineComponent({
47
48
  selectedButtonStyleConfig: computed(
48
49
  () => styleSettingsStore.selectedButtonStyleConfig,
49
50
  ),
50
- selectedTextFontFamily: computed(
51
- () => styleSettingsStore.selectedTextFontFamily,
52
- ),
53
51
  isAdminMaker: computed(() => brandPageContainerStore.isAdminMaker),
54
52
  brandPageType: computed(() => brandPageMakerStore.brandPageType),
55
53
  showBrandCrowdLogo: computed(
@@ -113,6 +111,12 @@ export default defineComponent({
113
111
  ? styleSettingsTr(`hideDesignLogo`)
114
112
  : styleSettingsTr(`hideBrandCrowdLogo`);
115
113
  },
114
+ // The panel's subtitle, so the warning still shows while the panel is collapsed.
115
+ textStyleSizeOrderWarning(): string {
116
+ return hasTextStyleSizeOrderIssue(this.textStyles.textStyleOptions)
117
+ ? styleSettingsTr('sizeOrderWarning')
118
+ : '';
119
+ },
116
120
  },
117
121
  methods: {
118
122
  onColorPickerSelected(value: boolean) {
@@ -0,0 +1,116 @@
1
+ import { nextTick } from 'vue';
2
+ import { readdirSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { mount } from '@vue/test-utils';
5
+ import { createPinia, setActivePinia } from 'pinia';
6
+ import StyleSettings from './StyleSettings.vue';
7
+ import { useUiStyleSettingsStore } from '../store';
8
+ import { setLocaleAsync } from '@src/composables/useTranslate';
9
+ import type { CanonicalTextStyleType } from '@brand-page';
10
+
11
+ const WARNING =
12
+ "Some text sizes are out of order. A heading or paragraph shouldn't be larger than the one above it.";
13
+
14
+ const mountStyleSettings = () =>
15
+ mount(StyleSettings, {
16
+ global: {
17
+ stubs: {
18
+ TextStyleOptionsSettingsWithState: {
19
+ template: '<div data-test-role-cards-stub />',
20
+ },
21
+ ColorPaletteSettingsWithState: true,
22
+ ColorField: true,
23
+ },
24
+ },
25
+ });
26
+
27
+ const textStylesPanel = (wrapper: ReturnType<typeof mountStyleSettings>) =>
28
+ wrapper.findComponent({ ref: 'textStylesPanel' });
29
+
30
+ const setRoleSize = (type: CanonicalTextStyleType, fontSize: string): void => {
31
+ const store = useUiStyleSettingsStore();
32
+
33
+ store.setTextStyleOption({
34
+ type,
35
+ style: { ...store.textStyles.textStyleOptions[type].style, fontSize },
36
+ });
37
+ };
38
+
39
+ describe('StyleSettings — text size order warning', () => {
40
+ beforeAll(async () => {
41
+ await setLocaleAsync('en-US');
42
+ });
43
+
44
+ beforeEach(() => {
45
+ setActivePinia(createPinia());
46
+ });
47
+
48
+ test('no warning shows at the default role sizes', () => {
49
+ expect(textStylesPanel(mountStyleSettings()).text()).not.toContain(WARNING);
50
+ });
51
+
52
+ test('a heading larger than the one above it shows the warning under the panel title', () => {
53
+ // Heading 3 at 90px, above Heading 2's default 84px.
54
+ setRoleSize('heading3', '5.625em');
55
+
56
+ expect(textStylesPanel(mountStyleSettings()).props('subtitle')).toBe(
57
+ WARNING,
58
+ );
59
+ });
60
+
61
+ test('a paragraph larger than the one above it shows the same warning', () => {
62
+ // Paragraph 2 at 64px, above Paragraph 1's default 22px.
63
+ setRoleSize('paragraph2', '4em');
64
+
65
+ expect(textStylesPanel(mountStyleSettings()).props('subtitle')).toBe(
66
+ WARNING,
67
+ );
68
+ });
69
+
70
+ test('the warning stays visible while the panel is collapsed', async () => {
71
+ setRoleSize('heading3', '5.625em');
72
+
73
+ const panel = textStylesPanel(mountStyleSettings());
74
+
75
+ (panel.vm as unknown as { toggleCollapsed: () => void }).toggleCollapsed();
76
+ await nextTick();
77
+
78
+ expect(panel.find('[data-test-role-cards-stub]').exists()).toBe(false);
79
+ expect(panel.text()).toContain(WARNING);
80
+ });
81
+
82
+ // StyleSettings.vue boxes the warning with a selector on CollapsiblePanel's own markup.
83
+ test('the warning sits in the element the warning box styles', () => {
84
+ setRoleSize('heading3', '5.625em');
85
+
86
+ expect(
87
+ mountStyleSettings()
88
+ .find('.c-text-style-panel .tw-grow > div + div')
89
+ .text(),
90
+ ).toBe(WARNING);
91
+ });
92
+
93
+ test('the warning clears once the order is fixed', async () => {
94
+ setRoleSize('heading3', '5.625em');
95
+
96
+ const wrapper = mountStyleSettings();
97
+
98
+ setRoleSize('heading3', '3.1875em');
99
+ await nextTick();
100
+
101
+ expect(textStylesPanel(wrapper).text()).not.toContain(WARNING);
102
+ });
103
+
104
+ test('every maker locale has the warning text', () => {
105
+ const dir = join(__dirname, 'i18n');
106
+ const files = readdirSync(dir).filter((file) => file.endsWith('.json'));
107
+
108
+ expect(files).toHaveLength(7);
109
+
110
+ for (const file of files) {
111
+ const json = JSON.parse(readFileSync(join(dir, file), 'utf-8'));
112
+
113
+ expect(json.styleSettingsSection.sizeOrderWarning, file).toBeTruthy();
114
+ }
115
+ });
116
+ });