@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,61 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
3
+ import { Decoration, DecorationSet } from 'prosemirror-view';
4
+ import { runTypography } from '@brand-page-maker/utils/rich-text-editor.util';
5
+ import { roleVarRef, runTypographyFillValue, composeTextDecoration, } from '@shared/text-role-typography.util';
6
+ // The box's CSS pins family, size, spacing and line height, so only these show through.
7
+ const FILLED_ATTRS = [
8
+ ['fontWeight', 'font-weight'],
9
+ ['fontStyle', 'font-style'],
10
+ ['textDecoration', 'text-decoration'],
11
+ ];
12
+ /**
13
+ * Draws the editor box the way the canvas does: a run with no weight / style / decoration of its
14
+ * own shows the value `fillRteRunTypography` would fill. Decorations are view-only, so the stored
15
+ * doc is untouched.
16
+ */
17
+ export const RoleTypographyFill = Extension.create({
18
+ name: 'roleTypographyFill',
19
+ addOptions() {
20
+ return { getFillSource: () => undefined };
21
+ },
22
+ addProseMirrorPlugins() {
23
+ const { getFillSource } = this.options;
24
+ return [
25
+ new Plugin({
26
+ key: new PluginKey('roleTypographyFill'),
27
+ props: {
28
+ decorations(state) {
29
+ const source = getFillSource();
30
+ if (!source)
31
+ return DecorationSet.empty;
32
+ const decorations = [];
33
+ state.doc.descendants((node, pos) => {
34
+ if (!node.isText)
35
+ return;
36
+ const run = runTypography(node);
37
+ const style = FILLED_ATTRS.flatMap(([attr, cssProp]) => {
38
+ if (attr === 'textDecoration') {
39
+ const blockValue = runTypographyFillValue(attr, source.role, source.block);
40
+ const localValue = run.textDecoration === roleVarRef(attr) &&
41
+ blockValue !== roleVarRef(attr)
42
+ ? blockValue
43
+ : (run.textDecoration ?? blockValue);
44
+ const value = composeTextDecoration(source.role.textDecoration ?? 'none', localValue);
45
+ return value ? [`${cssProp}: ${value}`] : [];
46
+ }
47
+ if (run[attr] !== undefined)
48
+ return [];
49
+ const value = runTypographyFillValue(attr, source.role, source.block);
50
+ return value ? [`${cssProp}: ${value}`] : [];
51
+ }).join('; ');
52
+ if (style)
53
+ decorations.push(Decoration.inline(pos, pos + node.nodeSize, { style }));
54
+ });
55
+ return DecorationSet.create(state.doc, decorations);
56
+ },
57
+ },
58
+ }),
59
+ ];
60
+ },
61
+ });
@@ -0,0 +1,11 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import type { EditorState } from 'prosemirror-state';
3
+ import { type Mark } from 'prosemirror-model';
4
+ import { type RteClipboardContext } from '@brand-page-maker/utils/rte-clipboard.util';
5
+ export interface RteClipboardOptions {
6
+ /** The field's role, style object and site palette, read at event time. */
7
+ getContext: () => RteClipboardContext;
8
+ /** The first-type seed a text-only paste into an empty field takes, same as typing. */
9
+ getFirstInputMarks: (state: EditorState) => Mark[];
10
+ }
11
+ export declare const RteClipboard: Extension<RteClipboardOptions, any>;
@@ -0,0 +1,236 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { closeHistory } from '@tiptap/pm/history';
3
+ import { Plugin, PluginKey } from 'prosemirror-state';
4
+ import { Slice } from 'prosemirror-model';
5
+ import { sanitizeRteJson } from '@brand-page-maker/utils';
6
+ import { alignPastedParagraphs, parseOwnRteClipboardPayload, plainTextToParagraphSlice, relinkColorToPalette, relinkRunTypographyToRole, resolveRunColorForCopy, resolveRunStyleForCopy, resolveRunStyleForExternal, RTE_CLIPBOARD_MIME_TYPE, RTE_CLIPBOARD_VERSION, } from '@brand-page-maker/utils/rte-clipboard.util';
7
+ import { AUTO_LINK_SKIP_STYLING_META, linkDetachMarksAt, } from '@shared/rte-extensions/AutoLink';
8
+ // `hardBreak` is left out: it carries no text of its own, so resolving it would give every
9
+ // break a full `textStyle` mark the source run never had (R1).
10
+ const INLINE_NODE_TYPES = new Set(['text']);
11
+ /** Replace a run's `textStyle`/`highlight` marks with their resolved forms; every other mark
12
+ * (link, a legacy bold/italic/underline/strike) rides through untouched (R1). */
13
+ const resolveRunMarks = (node, context, resolveRun) => {
14
+ const style = resolveRun(node, context);
15
+ delete style.href; // a link mark's own href, not a textStyle attr
16
+ const marks = (node.marks ?? [])
17
+ .filter((mark) => mark.type !== 'textStyle')
18
+ .map((mark) => {
19
+ if (mark.type !== 'highlight' || mark.attrs?.color == null)
20
+ return mark;
21
+ return {
22
+ type: 'highlight',
23
+ attrs: {
24
+ color: resolveRunColorForCopy(mark.attrs.color, context.colors) ?? mark.attrs.color,
25
+ },
26
+ };
27
+ });
28
+ if (Object.keys(style).length)
29
+ marks.push({ type: 'textStyle', attrs: style });
30
+ return { ...node, marks };
31
+ };
32
+ const resolveContentForCopy = (content, context, resolveRun) => content.map((node) => {
33
+ if (INLINE_NODE_TYPES.has(node.type ?? ''))
34
+ return resolveRunMarks(node, context, resolveRun);
35
+ return node.content
36
+ ? {
37
+ ...node,
38
+ content: resolveContentForCopy(node.content, context, resolveRun),
39
+ }
40
+ : node;
41
+ });
42
+ const buildInternalSlice = (content, openStart, openEnd, context) => {
43
+ const resolved = resolveContentForCopy(content, context, resolveRunStyleForCopy);
44
+ const sanitized = sanitizeRteJson({ type: 'doc', content: resolved });
45
+ return {
46
+ content: sanitized.content ?? [],
47
+ ...(openStart ? { openStart } : {}),
48
+ ...(openEnd ? { openEnd } : {}),
49
+ };
50
+ };
51
+ /** Every text/link mark relinked to the destination (A5 steps 2–3): typography that equals the
52
+ * destination role (or its neutral) becomes the role var, and a colour equal to a palette entry
53
+ * links to it; everything else — including an unresolvable value — stays exactly as copied. */
54
+ const relinkContentToDestination = (content, context) => content.map((node) => {
55
+ if (!INLINE_NODE_TYPES.has(node.type ?? ''))
56
+ return node.content
57
+ ? {
58
+ ...node,
59
+ content: relinkContentToDestination(node.content, context),
60
+ }
61
+ : node;
62
+ const isLinkRun = (node.marks ?? []).some((mark) => mark.type === 'link');
63
+ const marks = (node.marks ?? []).map((mark) => {
64
+ if (mark.type === 'textStyle') {
65
+ const relinked = relinkRunTypographyToRole((mark.attrs ?? {}), context.role);
66
+ if (relinked.color !== undefined)
67
+ relinked.color = relinkColorToPalette(relinked.color, context.colors, isLinkRun);
68
+ return { type: 'textStyle', attrs: relinked };
69
+ }
70
+ if (mark.type === 'highlight' && mark.attrs?.color != null) {
71
+ return {
72
+ type: 'highlight',
73
+ attrs: {
74
+ color: relinkColorToPalette(mark.attrs.color, context.colors),
75
+ },
76
+ };
77
+ }
78
+ return mark;
79
+ });
80
+ return { ...node, marks };
81
+ });
82
+ /** The destination alignment every pasted paragraph takes (Reading 14): the field's own alignment,
83
+ * else the alignment of the paragraph the cursor sits in. */
84
+ const resolveDestinationAlign = (state, context) => {
85
+ if (context.block?.textAlign)
86
+ return context.block.textAlign;
87
+ const { textAlign } = state.doc.resolve(state.selection.from).parent
88
+ .attrs;
89
+ return textAlign;
90
+ };
91
+ /** The marks a text-only paste's runs take — the marks typing would take at that spot (Approach
92
+ * step 4): the first-type seed in an empty field; else, over an empty selection, the stored/
93
+ * cursor marks with AutoLink's end-of-link detach applied exactly as it applies to typed text;
94
+ * over a range, ProseMirror's own `insertText` rule (`$from.marksAcross($to)`), since replacing
95
+ * a selection is never a link's end-of-line position. */
96
+ const resolvePlainPasteMarks = (state, getFirstInputMarks) => {
97
+ if (state.doc.textContent === '')
98
+ return getFirstInputMarks(state).map((mark) => mark.toJSON());
99
+ const { from, to } = state.selection;
100
+ if (from !== to) {
101
+ // `marksAcross` is null when nothing inline follows `from` within its own parent —
102
+ // a selection starting at a paragraph's end, or on an empty line. Real typing at
103
+ // that exact spot would get no marks; paste falls back to the marks AT `from`
104
+ // instead, so a routine "select to end of line, paste" doesn't lose the line's look.
105
+ // When `from` sits right at a link's end, AutoLink's own end-of-link detach applies
106
+ // first — the same one typing gets there — so the paste doesn't extend the link.
107
+ const marks = state.storedMarks ??
108
+ state.doc.resolve(from).marksAcross(state.doc.resolve(to)) ??
109
+ linkDetachMarksAt(state, from) ??
110
+ state.doc.resolve(from).marks();
111
+ return marks.map((mark) => mark.toJSON());
112
+ }
113
+ const detached = linkDetachMarksAt(state, from);
114
+ const marks = detached ?? state.storedMarks ?? state.doc.resolve(from).marks();
115
+ return marks.map((mark) => mark.toJSON());
116
+ };
117
+ /** Copy and cut share this: build every clipboard form the canvas's own look supports (A4), never
118
+ * mutating the doc. Returns false (no-op, browser default) for an empty selection or an unusable
119
+ * clipboard object. */
120
+ const writeClipboardData = (view, event, context) => {
121
+ const { state } = view;
122
+ if (state.selection.empty)
123
+ return false;
124
+ const data = event.clipboardData;
125
+ if (!data)
126
+ return false;
127
+ const liveSlice = state.selection.content();
128
+ const sliceJson = liveSlice.toJSON();
129
+ if (!sliceJson)
130
+ return false;
131
+ event.preventDefault();
132
+ const { openStart = 0, openEnd = 0 } = liveSlice;
133
+ const payload = {
134
+ v: RTE_CLIPBOARD_VERSION,
135
+ slice: buildInternalSlice(sliceJson.content, openStart, openEnd, context),
136
+ };
137
+ const externalContent = resolveContentForCopy(sliceJson.content, context, resolveRunStyleForExternal);
138
+ const externalSlice = Slice.fromJSON(state.schema, {
139
+ content: externalContent,
140
+ ...(openStart ? { openStart } : {}),
141
+ ...(openEnd ? { openEnd } : {}),
142
+ });
143
+ const { dom, text } = view.serializeForClipboard(externalSlice);
144
+ data.clearData();
145
+ data.setData('text/plain', text);
146
+ data.setData('text/html', dom.innerHTML);
147
+ data.setData(RTE_CLIPBOARD_MIME_TYPE, JSON.stringify(payload));
148
+ return true;
149
+ };
150
+ export const RteClipboard = Extension.create({
151
+ name: 'rteClipboard',
152
+ addOptions() {
153
+ return {
154
+ getContext: () => ({ role: undefined, block: undefined, colors: [] }),
155
+ getFirstInputMarks: () => [],
156
+ };
157
+ },
158
+ addProseMirrorPlugins() {
159
+ const { getContext, getFirstInputMarks } = this.options;
160
+ return [
161
+ new Plugin({
162
+ key: new PluginKey('rteClipboard'),
163
+ props: {
164
+ handleDOMEvents: {
165
+ copy(view, event) {
166
+ return writeClipboardData(view, event, getContext());
167
+ },
168
+ cut(view, event) {
169
+ if (!view.editable)
170
+ return false;
171
+ if (!writeClipboardData(view, event, getContext()))
172
+ return false;
173
+ const tr = view.state.tr.deleteSelection();
174
+ tr.scrollIntoView();
175
+ tr.setMeta('uiEvent', 'cut');
176
+ view.dispatch(tr);
177
+ return true;
178
+ },
179
+ paste(view, event) {
180
+ if (!view.editable)
181
+ return false;
182
+ const data = event.clipboardData;
183
+ if (!data)
184
+ return false;
185
+ event.preventDefault();
186
+ const { state } = view;
187
+ const context = getContext();
188
+ const destinationAlign = resolveDestinationAlign(state, context);
189
+ const ownRaw = data.getData(RTE_CLIPBOARD_MIME_TYPE);
190
+ const ownPayload = ownRaw
191
+ ? parseOwnRteClipboardPayload(ownRaw)
192
+ : null;
193
+ let pasteSliceJson = null;
194
+ if (ownPayload) {
195
+ pasteSliceJson = {
196
+ content: alignPastedParagraphs(relinkContentToDestination(ownPayload.slice.content, context), destinationAlign),
197
+ ...(ownPayload.slice.openStart
198
+ ? { openStart: ownPayload.slice.openStart }
199
+ : {}),
200
+ ...(ownPayload.slice.openEnd
201
+ ? { openEnd: ownPayload.slice.openEnd }
202
+ : {}),
203
+ };
204
+ }
205
+ else {
206
+ const plainText = data.getData('text/plain') || '';
207
+ if (plainText) {
208
+ pasteSliceJson = plainTextToParagraphSlice(plainText, resolvePlainPasteMarks(state, getFirstInputMarks), destinationAlign);
209
+ }
210
+ }
211
+ if (!pasteSliceJson)
212
+ return true; // R10 — nothing to paste
213
+ let slice = Slice.fromJSON(state.schema, pasteSliceJson);
214
+ const isPlainTextPaste = !ownPayload;
215
+ view.someProp('transformPasted', (transform) => {
216
+ slice = transform(slice, view, isPlainTextPaste);
217
+ });
218
+ if (!slice.size)
219
+ return true; // R8 — nothing fits
220
+ const tr = view.state.tr.replaceSelection(slice);
221
+ tr.setMeta('preventAutolink', true);
222
+ tr.setMeta(AUTO_LINK_SKIP_STYLING_META, true);
223
+ closeHistory(tr);
224
+ tr.scrollIntoView();
225
+ view.dispatch(tr);
226
+ // Seals the paste off as its own undo step (R12): typing right after opens a new
227
+ // group instead of merging into it (prosemirror-history groups within 500 ms).
228
+ view.dispatch(closeHistory(view.state.tr));
229
+ return true;
230
+ },
231
+ },
232
+ },
233
+ }),
234
+ ];
235
+ },
236
+ });
@@ -1,5 +1,6 @@
1
1
  import { type Ref } from 'vue';
2
2
  import type { Editor } from '@tiptap/vue-3';
3
+ import type { TextStyleDeclaration } from '@brand-page';
3
4
  interface DropdownRef {
4
5
  hideMenu: () => void;
5
6
  }
@@ -7,7 +8,7 @@ export declare const useFont: (editor: Editor, fontSettings: {
7
8
  selectedFont: string;
8
9
  selectedFontSize: string;
9
10
  selectedFontSizePx: number;
10
- }, dropdownRef: Ref<DropdownRef | undefined>) => {
11
+ }, dropdownRef: Ref<DropdownRef | undefined>, getRoleStyle?: () => TextStyleDeclaration | undefined) => {
11
12
  selectedFont: Ref<string, string>;
12
13
  toggleFont: (font: string) => void;
13
14
  toggleFontAll: (fontName: string) => void;
@@ -1,32 +1,51 @@
1
1
  import { ref } from 'vue';
2
- import { emToPx, pxToEm, skipStyleDetection } from '@brand-page-maker/utils';
2
+ import { emToPx, pxToEm, skipStyleDetection, roleVarOrLiteral, } from '@brand-page-maker/utils';
3
+ import { roleVarRef } from '@shared/text-role-typography.util';
3
4
  import debounce from 'lodash/debounce';
4
- export const useFont = (editor, fontSettings, dropdownRef) => {
5
+ export const useFont = (editor, fontSettings, dropdownRef,
6
+ // The linked role's style when the block is canonical-linked, else undefined (legacy/unlinked).
7
+ // Drives the var-or-literal write: a pick equal to the role stores the role var, not a literal.
8
+ getRoleStyle = () => undefined) => {
5
9
  const selectedFont = ref(fontSettings.selectedFont ?? 'Lato');
6
10
  const toggleFont = (font) => {
7
11
  dropdownRef.value?.hideMenu?.();
8
12
  selectedFont.value = font;
9
13
  fontSettings.selectedFont = font;
10
- editor.chain().focus().setFontFamily(font).run();
14
+ editor
15
+ .chain()
16
+ .focus()
17
+ .setFontFamily(roleVarOrLiteral('fontFamily', font, getRoleStyle()))
18
+ .run();
11
19
  };
20
+ // Role application (role switch): write the role-agnostic var ref so the run follows the
21
+ // (new) container class — no literal to pin it.
12
22
  const toggleFontAll = (fontName) => {
13
23
  selectedFont.value = fontName;
14
24
  fontSettings.selectedFont = fontName;
15
- skipStyleDetection(editor.chain().selectAll().setFontFamily(fontName)).run();
25
+ skipStyleDetection(editor
26
+ .chain()
27
+ .selectAll()
28
+ .setFontFamily(roleVarRef('fontFamily') ?? fontName)).run();
16
29
  };
17
30
  const toggleFontSize = debounce((size) => {
18
31
  fontSettings.selectedFontSize = size.includes('em') ? size : pxToEm(size);
19
32
  fontSettings.selectedFontSizePx = size.includes('em')
20
33
  ? parseInt(emToPx(size))
21
34
  : parseInt(size);
22
- editor.chain().setFontSize(fontSettings.selectedFontSize).run();
35
+ editor
36
+ .chain()
37
+ .setFontSize(roleVarOrLiteral('fontSize', fontSettings.selectedFontSize, getRoleStyle()))
38
+ .run();
23
39
  }, 150);
24
40
  const toggleFontSizeAll = (size) => {
25
41
  fontSettings.selectedFontSize = size.includes('em') ? size : pxToEm(size);
26
42
  fontSettings.selectedFontSizePx = size.includes('em')
27
43
  ? parseInt(emToPx(size))
28
44
  : parseInt(size);
29
- skipStyleDetection(editor.chain().selectAll().setFontSize(fontSettings.selectedFontSize)).run();
45
+ skipStyleDetection(editor
46
+ .chain()
47
+ .selectAll()
48
+ .setFontSize(roleVarRef('fontSize') ?? fontSettings.selectedFontSize)).run();
30
49
  };
31
50
  return {
32
51
  selectedFont,
@@ -1,9 +1,19 @@
1
1
  import type { Editor } from '@tiptap/vue-3';
2
- export declare const createFormattingActions: (editor: Editor) => {
2
+ import type { TextStyleDeclaration } from '@brand-page';
3
+ /**
4
+ * BP-5969 (Phase A) — bold / italic / underline / strike are written as `textStyle` mark ATTRIBUTES
5
+ * (font-weight / font-style / text-decoration), not Tiptap semantic marks, so they sit in the same
6
+ * var-or-literal system as family/size: a pick equal to the role stores the role var (follows role
7
+ * edits), else a literal override. Each toggle ALSO unsets the legacy semantic mark, so a legacy
8
+ * `<strong>`/`<u>` run becomes attr-driven the moment the user toggles it (migrate-on-edit). Reading
9
+ * still honours both forms (see the active-state resolution in `selectionUpdate`), and the semantic
10
+ * extensions remain registered for rendering un-migrated docs + paste (Phase B removes them).
11
+ */
12
+ export declare const createFormattingActions: (editor: Editor, getRoleStyle?: () => TextStyleDeclaration | undefined, getBlockStyle?: () => TextStyleDeclaration | undefined) => {
3
13
  toggleBold: () => boolean;
4
14
  toggleItalic: () => boolean;
5
- toggleUnderline: () => boolean;
6
- toggleStrike: () => boolean;
15
+ toggleUnderline: () => void;
16
+ toggleStrike: () => void;
7
17
  toggleTextColor: (color: string) => boolean;
8
18
  toggleBackgroundColor: (color: string) => boolean;
9
19
  toggleBoldAll: () => void;
@@ -11,5 +21,8 @@ export declare const createFormattingActions: (editor: Editor) => {
11
21
  toggleUnderlineAll: () => void;
12
22
  toggleStrikeAll: () => void;
13
23
  toggleTextColorAll: (color: string) => void;
14
- unsetAllMarks: () => void;
24
+ boldActive: () => boolean;
25
+ italicActive: () => boolean;
26
+ underlineActive: () => boolean;
27
+ strikeActive: () => boolean;
15
28
  };
@@ -1,33 +1,220 @@
1
- import { skipStyleDetection } from '@brand-page-maker/utils';
2
- export const createFormattingActions = (editor) => {
1
+ import { skipStyleDetection, roleVarOrLiteral, isRoleVarRef, restoreLinkUnderlines, } from '@brand-page-maker/utils';
2
+ import { composeTextDecoration, roleVarRef, textDecorationClearsRole, textDecorationFlags, } from '@shared/text-role-typography.util';
3
+ // text-decoration is a single, combinable property (underline + line-through). Compose/decompose the
4
+ // two flags in a stable order so a role-equality compare (roleVarOrLiteral) is deterministic.
5
+ const DECORATION_FLAGS = ['underline', 'line-through', 'overline'];
6
+ const isBoldWeight = (value) => value === 'bold' || (value != null && Number.parseInt(value, 10) >= 600);
7
+ const decorationSet = (value) => new Set((value ?? '').split(/\s+/).filter((flag) => flag && flag !== 'none'));
8
+ const composeDecoration = (flags) => DECORATION_FLAGS.filter((flag) => flags.has(flag)).join(' ') || 'none';
9
+ /**
10
+ * BP-5969 (Phase A) — bold / italic / underline / strike are written as `textStyle` mark ATTRIBUTES
11
+ * (font-weight / font-style / text-decoration), not Tiptap semantic marks, so they sit in the same
12
+ * var-or-literal system as family/size: a pick equal to the role stores the role var (follows role
13
+ * edits), else a literal override. Each toggle ALSO unsets the legacy semantic mark, so a legacy
14
+ * `<strong>`/`<u>` run becomes attr-driven the moment the user toggles it (migrate-on-edit). Reading
15
+ * still honours both forms (see the active-state resolution in `selectionUpdate`), and the semantic
16
+ * extensions remain registered for rendering un-migrated docs + paste (Phase B removes them).
17
+ */
18
+ export const createFormattingActions = (editor,
19
+ // The linked role's style (canonical-linked block), else undefined (legacy/unlinked → literals).
20
+ getRoleStyle = () => undefined,
21
+ // Render fill gives an absent run this whole-block style before the role, so toolbar state and
22
+ // mutations must use the same source instead of treating the run as role-only.
23
+ getBlockStyle = () => undefined) => {
24
+ // An absent attr receives the block fill, but an explicit role reference keeps following the role.
25
+ const effectiveValue = (attr, mark) => {
26
+ if (typeof mark === 'string' && mark !== '') {
27
+ if (!isRoleVarRef(mark))
28
+ return mark;
29
+ return getRoleStyle()?.[attr];
30
+ }
31
+ return (getBlockStyle()?.[attr] ||
32
+ getRoleStyle()?.[attr]);
33
+ };
34
+ const effective = (attr) => effectiveValue(attr, editor.getAttributes('textStyle')?.[attr]);
35
+ // A run is bold/italic/underlined via EITHER the new attr OR a legacy semantic mark — check both.
36
+ const boldActive = () => editor.isActive('bold') || isBoldWeight(effective('fontWeight'));
37
+ const italicActive = () => editor.isActive('italic') || effective('fontStyle') === 'italic';
38
+ // The text runs a decoration toggle acts on: the cursor's marks when nothing is selected (stored
39
+ // marks win, as typing applies them), else each text node clipped to the selection.
40
+ const selectedRuns = () => {
41
+ const { selection, storedMarks, doc } = editor.state;
42
+ if (selection.empty) {
43
+ return [
44
+ {
45
+ from: selection.from,
46
+ to: selection.to,
47
+ marks: storedMarks ?? selection.$from.marks(),
48
+ },
49
+ ];
50
+ }
51
+ const runs = [];
52
+ selection.ranges.forEach(({ $from, $to }) => {
53
+ doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
54
+ if (!node.isText)
55
+ return;
56
+ runs.push({
57
+ from: Math.max(pos, $from.pos),
58
+ to: Math.min(pos + node.nodeSize, $to.pos),
59
+ marks: node.marks,
60
+ });
61
+ });
62
+ });
63
+ return runs;
64
+ };
65
+ const runDecoration = (marks) => {
66
+ const attrs = marks.find((mark) => mark.type.name === 'textStyle')?.attrs;
67
+ const markValue = attrs?.textDecoration;
68
+ const localValue = markValue && !isRoleVarRef(markValue)
69
+ ? markValue
70
+ : getBlockStyle()?.textDecoration;
71
+ const flags = decorationSet(composeTextDecoration(getRoleStyle()?.textDecoration, localValue, textDecorationClearsRole(markValue, attrs?.textDecorationReset === true)));
72
+ if (marks.some((mark) => mark.type.name === 'underline')) {
73
+ flags.add('underline');
74
+ }
75
+ if (marks.some((mark) => mark.type.name === 'strike')) {
76
+ flags.add('line-through');
77
+ }
78
+ return flags;
79
+ };
80
+ // Active only when every selected run has the flag, so toggling a mixed selection turns it on.
81
+ const decorationActive = (flag) => {
82
+ const runs = selectedRuns();
83
+ return (runs.length > 0 &&
84
+ runs.every(({ marks }) => runDecoration(marks).has(flag)));
85
+ };
86
+ // text-decoration holds both flags in one value, so each run gets its own composed value: one
87
+ // uniform write would drop the other flag from runs that carry it.
88
+ const toggleDecoration = (flag) => {
89
+ const turnOn = !decorationActive(flag);
90
+ const runs = selectedRuns();
91
+ const decorationFor = (marks) => {
92
+ const current = runDecoration(marks);
93
+ if (turnOn)
94
+ current.add(flag);
95
+ else
96
+ current.delete(flag);
97
+ const fallback = decorationSet(composeTextDecoration(getRoleStyle()?.textDecoration, getBlockStyle()?.textDecoration));
98
+ const roleFlags = textDecorationFlags(getRoleStyle()?.textDecoration);
99
+ // The role ref lets render-fill continue applying a whole-block override. Keep it only when
100
+ // the toggle returns to that exact fallback; every other literal must describe the complete
101
+ // desired result because it deliberately bypasses the block fill.
102
+ if (current.size === fallback.size &&
103
+ [...current].every((currentFlag) => fallback.has(currentFlag))) {
104
+ return getRoleStyle()
105
+ ? {
106
+ textDecoration: roleVarRef('textDecoration'),
107
+ textDecorationReset: null,
108
+ }
109
+ : {
110
+ textDecoration: composeDecoration(current),
111
+ textDecorationReset: null,
112
+ };
113
+ }
114
+ if ([...roleFlags].some((roleFlag) => !current.has(roleFlag))) {
115
+ return {
116
+ textDecoration: composeDecoration(current),
117
+ textDecorationReset: true,
118
+ };
119
+ }
120
+ return {
121
+ textDecoration: composeDecoration(current),
122
+ textDecorationReset: null,
123
+ };
124
+ };
125
+ // Unset both legacy decoration marks so the composed attr is the single source of truth.
126
+ if (editor.state.selection.empty) {
127
+ editor
128
+ .chain()
129
+ .focus()
130
+ .unsetUnderline()
131
+ .unsetStrike()
132
+ .setMark('textStyle', decorationFor(runs[0].marks))
133
+ .run();
134
+ return;
135
+ }
136
+ editor
137
+ .chain()
138
+ .focus()
139
+ .command(({ tr }) => {
140
+ const { textStyle, underline, strike } = tr.doc.type.schema.marks;
141
+ runs.forEach(({ from, to, marks }) => {
142
+ tr.removeMark(from, to, underline)
143
+ .removeMark(from, to, strike)
144
+ .addMark(from, to, textStyle.create({
145
+ ...marks.find((mark) => mark.type === textStyle)?.attrs,
146
+ ...decorationFor(marks),
147
+ }));
148
+ });
149
+ return true;
150
+ })
151
+ .run();
152
+ };
3
153
  return {
4
- toggleBold: () => editor.chain().focus().toggleBold().run(),
5
- toggleItalic: () => editor.chain().focus().toggleItalic().run(),
6
- toggleUnderline: () => editor.chain().focus().toggleUnderline().run(),
7
- toggleStrike: () => editor.chain().focus().toggleStrike().run(),
8
- // Colour is an element-first override that must NOT detach the element from its
9
- // global text style (unlike typography edits, which do). `skipStyleDetection`
10
- // marks the transaction so the detach handler leaves `textStyleType` intact —
11
- // same reason `toggleTextColorAll` below skips it.
154
+ toggleBold: () => editor
155
+ .chain()
156
+ .focus()
157
+ .unsetBold()
158
+ .setMark('textStyle', {
159
+ fontWeight: roleVarOrLiteral('fontWeight', boldActive() ? 'normal' : 'bold', getRoleStyle()),
160
+ })
161
+ .run(),
162
+ toggleItalic: () => editor
163
+ .chain()
164
+ .focus()
165
+ .unsetItalic()
166
+ .setMark('textStyle', {
167
+ fontStyle: roleVarOrLiteral('fontStyle', italicActive() ? 'normal' : 'italic', getRoleStyle()),
168
+ })
169
+ .run(),
170
+ toggleUnderline: () => toggleDecoration('underline'),
171
+ toggleStrike: () => toggleDecoration('line-through'),
172
+ // Colour is an element-first override that must NOT detach the element from its global text style
173
+ // (unlike typography edits, which do). `skipStyleDetection` marks the transaction so the detach
174
+ // handler leaves `textStyleType` intact — same reason `toggleTextColorAll` below skips it.
12
175
  toggleTextColor: (color) => skipStyleDetection(editor.chain().focus().setMark('textStyle', { color })).run(),
13
176
  toggleBackgroundColor: (color) => editor.chain().focus().setHighlight({ color }).run(),
177
+ // *All (role application): write the role var ref to every run so it follows the container class,
178
+ // clearing any legacy semantic mark that would otherwise pin it.
14
179
  toggleBoldAll: () => {
15
- skipStyleDetection(editor.chain().selectAll().toggleBold()).run();
180
+ skipStyleDetection(editor
181
+ .chain()
182
+ .selectAll()
183
+ .unsetBold()
184
+ .setMark('textStyle', { fontWeight: roleVarRef('fontWeight') })).run();
16
185
  },
17
186
  toggleItalicAll: () => {
18
- skipStyleDetection(editor.chain().selectAll().toggleItalic()).run();
187
+ skipStyleDetection(editor
188
+ .chain()
189
+ .selectAll()
190
+ .unsetItalic()
191
+ .setMark('textStyle', { fontStyle: roleVarRef('fontStyle') })).run();
19
192
  },
20
193
  toggleUnderlineAll: () => {
21
- skipStyleDetection(editor.chain().selectAll().toggleUnderline()).run();
194
+ skipStyleDetection(editor
195
+ .chain()
196
+ .selectAll()
197
+ .unsetUnderline()
198
+ .unsetStrike()
199
+ .setTextDecoration(roleVarRef('textDecoration'))
200
+ .command(restoreLinkUnderlines(editor))).run();
22
201
  },
23
202
  toggleStrikeAll: () => {
24
- skipStyleDetection(editor.chain().selectAll().toggleStrike()).run();
203
+ skipStyleDetection(editor
204
+ .chain()
205
+ .selectAll()
206
+ .unsetUnderline()
207
+ .unsetStrike()
208
+ .setTextDecoration(roleVarRef('textDecoration'))
209
+ .command(restoreLinkUnderlines(editor))).run();
25
210
  },
26
211
  toggleTextColorAll: (color) => {
27
212
  skipStyleDetection(editor.chain().selectAll().setMark('textStyle', { color })).run();
28
213
  },
29
- unsetAllMarks: () => {
30
- skipStyleDetection(editor.chain().selectAll().unsetAllMarks()).run();
31
- },
214
+ // Effective active-state (attr OR legacy mark) for the toolbar buttons.
215
+ boldActive,
216
+ italicActive,
217
+ underlineActive: () => decorationActive('underline'),
218
+ strikeActive: () => decorationActive('line-through'),
32
219
  };
33
220
  };
@@ -1,5 +1,5 @@
1
1
  import type { Editor } from '@tiptap/vue-3';
2
- export declare const isHrefPageId: (href: string) => boolean;
2
+ export { isHrefPageId } from '@shared/rte-link.util';
3
3
  export declare const getPageIdFromHref: (href: string) => string;
4
4
  export declare const getHrefForPage: (pageId: string) => string;
5
5
  export declare const useHyperlink: (editor: Editor) => {