@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
@@ -1,7 +1,11 @@
1
1
  import { BUTTON_LINK_TYPE } from '../../brand-page/models';
2
+ import { normalizeTextStyleAgainstRole, omitTypography, } from '../../brand-page/utils/text-style.util';
3
+ import { computeLegacyTargets, contentFieldReconnectSpec, isCanonicalTextStyleType, reconnectTextStyle, } from '../../brand-page/utils/text-role-reconnect.util';
2
4
  import { isTiptapDocument, } from '../parsers/section-tool-arguments';
3
5
  import { hasRTEContent } from '../../brand-page-maker/utils';
4
6
  import { useExternalRichTextEditor } from '../../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
7
+ import { relinkDocToRole } from '../../brand-page-maker/utils/rich-text-editor.util';
8
+ import { docHasColourableRun, setRteTextColor, } from '../../shared/color-strategies/rte-color';
5
9
  import { applyStyleToRTEText } from '../helpers/rte.helpers';
6
10
  import { getSectionFieldMap, getStyleFieldMap } from './section-field-maps';
7
11
  const isUrlField = (aiKey) => aiKey.endsWith('_url');
@@ -58,6 +62,13 @@ export const applyScalarFields = (content, args, sectionType) => {
58
62
  /**
59
63
  * Convert AI-sent style value to the format expected by the model.
60
64
  * - letterSpacing: unitless 0-100 → em string (e.g., 50 → '0.5em')
65
+ * - lineHeight: coerced to a plain numeric string, UNSNAPPED — snapping here would shift a
66
+ * value that's actually equal to its role (e.g. 1.25) off that equality before
67
+ * `applyAiStyle` gets a chance to drop it as a role-equal non-override (R2). Only a value
68
+ * that survives the role-equal check is snapped (`snapLineHeight`, in `applyAiStyle`), and the
69
+ * drop runs AGAIN after snapping: a role can itself hold a non-grid value (e.g. heading3's
70
+ * native 1.25), so comparing before snapping catches an exact match at full precision, and
71
+ * re-comparing after catches a snap that LANDS the override exactly on the role's value.
61
72
  * - null → '' (explicitly clear/reset the property)
62
73
  * - everything else passes through as-is
63
74
  */
@@ -70,56 +81,116 @@ export const normalizeStyleValue = (key, value) => {
70
81
  return `${value / 100}em`;
71
82
  }
72
83
  if (key === 'lineHeight') {
73
- // Snap to 0.1 increments to match the UI slider step
74
84
  const num = typeof value === 'number' ? value : parseFloat(String(value));
75
85
  if (!isNaN(num))
76
- return String(Math.floor(num * 10) / 10);
86
+ return String(num);
77
87
  }
78
88
  return value;
79
89
  };
90
+ /** Snap a line-height value to the UI slider's 0.1 step. Pure — returns a new object. */
91
+ const snapLineHeight = (style) => {
92
+ const { lineHeight } = style;
93
+ if (typeof lineHeight !== 'string')
94
+ return style;
95
+ const num = parseFloat(lineHeight);
96
+ if (isNaN(num))
97
+ return style;
98
+ return { ...style, lineHeight: String(Math.floor(num * 10) / 10) };
99
+ };
100
+ /**
101
+ * Whether this call is a REAL canonical switch (R19): both the stored and the INCOMING role (the
102
+ * raw value the call sent, before any reconnect fallback) are canonical, and differ. Decided once
103
+ * from `incoming.textStyleType` and shared by `applyAiStyle` (which resets the style object) and
104
+ * the caller of `applyStoredDocStyleConsequences` (which resets the stored doc), so both agree: a
105
+ * retired-key call reconnects in `applyAiStyle` (not a switch — it keeps the look as overrides) but
106
+ * can still land on a canonical role that differs from the stored one, which deriving it from the
107
+ * RESULT instead would misread as a switch and relink a doc whose overrides were meant to survive.
108
+ */
109
+ export const isRealCanonicalSwitch = (existingRole, incomingRole) => isCanonicalTextStyleType(existingRole) &&
110
+ isCanonicalTextStyleType(incomingRole) &&
111
+ incomingRole !== existingRole;
80
112
  /**
81
- * When an executor is about to mark a content-level text style "custom" by
82
- * clearing `textStyleType`, the resolved preset values (font, size, spacing,
83
- * etc.) must first be copied onto the style — otherwise the renderer falls
84
- * back to browser defaults because `textStyleType` no longer points at a
85
- * preset.
113
+ * Apply an AI-sent style to a field, honouring the role model under partial-update semantics
114
+ * (a property present = update; absent = no change).
86
115
  *
87
- * The category is read from the existing `style.textStyleType`, which is the
88
- * authoritative per-section + per-field reference set by the content factory.
89
- * Existing style values win over preset defaults (the content may already
90
- * carry user overrides on top of the preset).
116
+ * The role is the EFFECTIVE one — `incoming.textStyleType ?? existing.textStyleType` — so a sparse
117
+ * update that omits the role KEEPS the element's current role. When that role is canonical, keep
118
+ * the link and store a sparse override: incoming props layer on and `normalizeTextStyleAgainstRole`
119
+ * drops any prop equal to the role, so the page-scoped role CSS drives it and a later global edit
120
+ * repaints the block.
121
+ *
122
+ * A REAL canonical switch (both the old and the new role are canonical, and differ — R19) is a
123
+ * reset, not a patch: it starts from `omitTypography(existing)` before layering this call's own
124
+ * style on top, so a stale override from the old role doesn't survive as a bogus override of the
125
+ * new one. Colour, background, alignment and `applyAutoScale` aren't typography, so they carry
126
+ * over untouched; the call's own text and overrides win (they're applied after the reset).
127
+ *
128
+ * Any other role — a retired key the pipeline still emits, `none`, or no role at all — reconnects
129
+ * the way the upgrade does (`reconnectTextStyle`, with the field's `spec`): its starting role, else
130
+ * the retired role's successor, else the role nearest its size, keeping its look as overrides.
91
131
  */
92
- export const resolveGlobalPresetIntoStyle = (style, textStyleOptions) => {
93
- const base = { ...(style ?? {}) };
94
- const currentTextStyleType = base.textStyleType;
95
- if (!currentTextStyleType || !textStyleOptions?.[currentTextStyleType]) {
96
- base.textStyleType = undefined;
97
- return base;
98
- }
99
- const presetStyle = textStyleOptions[currentTextStyleType].style;
100
- const presetDefaults = {};
101
- for (const [k, v] of Object.entries(presetStyle)) {
102
- if (k === 'textStyleType' || v === undefined)
103
- continue;
104
- presetDefaults[k] = v;
132
+ export const applyAiStyle = (existing, incoming, textStyleOptions, spec = {}) => {
133
+ const existingRole = existing
134
+ ?.textStyleType;
135
+ const role = incoming.textStyleType ?? existingRole;
136
+ const base = isRealCanonicalSwitch(existingRole, incoming.textStyleType)
137
+ ? omitTypography(existing ?? {})
138
+ : (existing ?? {});
139
+ const merged = { ...base, ...incoming, textStyleType: role };
140
+ if (isCanonicalTextStyleType(role)) {
141
+ const normalized = normalizeTextStyleAgainstRole(merged, textStyleOptions);
142
+ // Snap and re-check only a lineHeight that is BOTH this call's own (not one inherited
143
+ // untouched from the stored style — an unrelated patch must not silently rewrite it) AND
144
+ // survived the first role-equal pass as a genuine override.
145
+ if ('lineHeight' in incoming && 'lineHeight' in normalized) {
146
+ return normalizeTextStyleAgainstRole(snapLineHeight(normalized), textStyleOptions);
147
+ }
148
+ return normalized;
105
149
  }
106
- return { ...presetDefaults, ...base, textStyleType: undefined };
150
+ return reconnectTextStyle(merged, computeLegacyTargets(textStyleOptions), textStyleOptions, spec);
107
151
  };
108
152
  /**
109
- * Applies per-element style overrides while detaching the element from any
110
- * global text-style preset. When a style is bound to a `textStyleType` preset,
111
- * the renderer (`getCopyrightTextStyle` / `getTextStyleByContentTextStyle`)
112
- * replaces the whole style with that preset and discards per-element values such
113
- * as `fontFamily`. Resolving the preset in and clearing `textStyleType` makes the
114
- * override stick — the same disconnect rule section content follows.
153
+ * BP-5969 (R18, R19) — what a style-only patch (no new text in the same call) does to an already-
154
+ * stored RTE doc. A real role switch relinks every run to the new role (the document-level half of
155
+ * the reset `applyAiStyle` already gave the style object above), keeping any typography the call's
156
+ * own `nextStyle` still overrides via `relinkDocToRole`'s `styleOverrides` arg. A colour-only patch,
157
+ * OR a colour riding along with a switch in the same call (James Joung, 2026-10-01: a role switch
158
+ * and a recolour with no text both apply), recolours every run and clears the now-redundant style
159
+ * colour (kept only when the doc has no run to hold it — an empty field's colour waits for the
160
+ * maker's first keystroke, `buildInitialMarks`). Both consequences can apply to one call: the
161
+ * switch's relink runs first, then the colour branch recolours the relinked doc.
115
162
  *
116
- * Idempotent: once `textStyleType` is cleared, subsequent calls just merge the
117
- * updates without re-resolving a preset.
163
+ * No-op for anything but a stored Tiptap document — a legacy HTML string is handled by the caller's
164
+ * own `ApplyColorToRTE` rewrite instead.
118
165
  */
119
- export const applyDetachedStyleOverride = (current, updates, textStyleOptions) => ({
120
- ...resolveGlobalPresetIntoStyle(current, textStyleOptions),
121
- ...updates,
122
- });
166
+ export const applyStoredDocStyleConsequences = (existingText, existingRole, nextStyle, incomingStyle, textStyleOptions) => {
167
+ if (!isTiptapDocument(existingText))
168
+ return existingText;
169
+ // Decided from the call's own RAW textStyleType (via isRealCanonicalSwitch), the same test
170
+ // applyAiStyle already made for the style object, not re-derived from nextStyle.textStyleType:
171
+ // a retired-key call reconnects (not a switch) in applyAiStyle but can still land on a canonical
172
+ // role that differs from the stored one, which re-deriving from the RESULT would misread as a
173
+ // switch. When it IS a real switch, nextStyle.textStyleType equals incomingStyle.textStyleType.
174
+ const isRealSwitch = isRealCanonicalSwitch(existingRole, incomingStyle.textStyleType);
175
+ const nextRole = nextStyle.textStyleType;
176
+ let text = existingText;
177
+ if (isRealSwitch) {
178
+ const roleStyle = textStyleOptions?.[nextRole]
179
+ ?.style;
180
+ text = relinkDocToRole(text, roleStyle, nextStyle);
181
+ }
182
+ const newColor = incomingStyle.color;
183
+ if (typeof newColor === 'string' &&
184
+ newColor &&
185
+ docHasColourableRun(text)) {
186
+ const recoloured = setRteTextColor(text, newColor);
187
+ if (recoloured) {
188
+ delete nextStyle.color;
189
+ return recoloured;
190
+ }
191
+ }
192
+ return text;
193
+ };
123
194
  export const applyStyleFields = (content, args, sectionType, textStyleOptions, applyColor) => {
124
195
  const styleMap = getStyleFieldMap(sectionType);
125
196
  if (!styleMap)
@@ -144,27 +215,32 @@ export const applyStyleFields = (content, args, sectionType, textStyleOptions, a
144
215
  if (normalized !== undefined)
145
216
  filtered[k] = normalized;
146
217
  }
147
- const resolved = resolveGlobalPresetIntoStyle(content[modelKey], textStyleOptions);
148
- record[modelKey] = { ...resolved, ...filtered, textStyleType: undefined };
149
- // A colour patch without new text leaves the field's EXISTING inline
150
- // textStyle marks in place — and inline marks override every style layer
151
- // at render, so the old colour survives on a recoloured band (invisible
152
- // text, AI QA 2026-07-05 rerun). Propagate the new colour into the
153
- // stored HTML, mirroring global-font-propagation for font families.
218
+ const existingStyle = content[modelKey];
219
+ const existingRole = existingStyle?.textStyleType;
220
+ record[modelKey] = applyAiStyle(existingStyle, filtered, textStyleOptions, contentFieldReconnectSpec(sectionType, modelKey));
221
+ // A style-only patch (no new text in this call) leaves the field's EXISTING inline
222
+ // textStyle marks in place — and inline marks override every style layer at render, so the
223
+ // old look survives a recoloured band (invisible text, AI QA 2026-07-05 rerun) or a role
224
+ // switch (the overrides reset above, but the stored doc's runs don't follow on their own).
225
+ // Propagate the consequence into the stored text, mirroring global-role-propagation.
154
226
  const textKey = modelKey.endsWith('Style')
155
227
  ? modelKey.slice(0, -'Style'.length)
156
228
  : undefined;
157
229
  const textAiKey = aiKey.endsWith('_style')
158
230
  ? aiKey.slice(0, -'_style'.length)
159
231
  : undefined;
160
- const newColor = filtered.color;
161
- if (textKey &&
162
- typeof newColor === 'string' &&
163
- newColor &&
164
- !(textAiKey && textAiKey in args) &&
165
- typeof record[textKey] === 'string' &&
166
- hasRTEContent(record[textKey])) {
167
- record[textKey] = applyColorToHtml(record[textKey], newColor);
232
+ const textSentThisCall = !!(textAiKey && textAiKey in args);
233
+ if (textKey && !textSentThisCall) {
234
+ const existingText = record[textKey];
235
+ if (isTiptapDocument(existingText)) {
236
+ record[textKey] = applyStoredDocStyleConsequences(existingText, existingRole, record[modelKey], filtered, textStyleOptions);
237
+ }
238
+ else if (typeof filtered.color === 'string' &&
239
+ filtered.color &&
240
+ typeof existingText === 'string' &&
241
+ hasRTEContent(existingText)) {
242
+ record[textKey] = applyColorToHtml(existingText, filtered.color);
243
+ }
168
244
  }
169
245
  }
170
246
  }
@@ -1,6 +1,8 @@
1
- import type { UpdateGlobalStylesArguments } from '../../parsers/ai-toolcall-parser';
2
- import type { TextStyleType } from '../../../brand-page/models/styles.model';
1
+ import type { UpdateGlobalStylesArguments, TextStyleOptionStyle } from '../../parsers/ai-toolcall-parser';
2
+ import { type TextStyleType } from '../../../brand-page/models/styles.model';
3
3
  export declare const TEXT_STYLE_OPTION_KEYS: TextStyleType[];
4
+ /** Role definitions accept numeric wire values but store their canonical string representation. */
5
+ export declare const normalizeGlobalTextStyleOption: (style: TextStyleOptionStyle) => TextStyleOptionStyle;
4
6
  type GlobalStyleCheck = (args: UpdateGlobalStylesArguments) => string | null;
5
7
  export declare const GLOBAL_STYLE_CHECKS: GlobalStyleCheck[];
6
8
  export {};
@@ -1,26 +1,42 @@
1
- import { STYLE_RULES } from '../../sanitizers/sanitizer-rules';
1
+ import { CANONICAL_TEXT_STYLE_TYPES, LEGACY_TEXT_STYLE_TYPES, } from '../../../brand-page/models/styles.model';
2
2
  import { validateStringStyleAttrs } from '../../sanitizers/section-args-validator';
3
3
  export const TEXT_STYLE_OPTION_KEYS = [
4
- 'titles',
5
- 'headings',
6
- 'paragraphs',
7
- 'buttons',
4
+ ...CANONICAL_TEXT_STYLE_TYPES,
5
+ ...LEGACY_TEXT_STYLE_TYPES,
8
6
  ];
7
+ /** Role definitions accept numeric wire values but store their canonical string representation. */
8
+ export const normalizeGlobalTextStyleOption = (style) => {
9
+ const normalized = { ...style };
10
+ const lineHeight = style.lineHeight;
11
+ const fontWeight = style.fontWeight;
12
+ if (typeof lineHeight === 'number' && !isNaN(lineHeight)) {
13
+ normalized.lineHeight = String(lineHeight);
14
+ }
15
+ else if (lineHeight != null) {
16
+ const value = parseFloat(String(lineHeight).trim());
17
+ if (!isNaN(value) && String(lineHeight).trim() !== String(value)) {
18
+ normalized.lineHeight = String(value);
19
+ }
20
+ }
21
+ if (typeof fontWeight === 'number' && !isNaN(fontWeight)) {
22
+ normalized.fontWeight = String(fontWeight);
23
+ }
24
+ return normalized;
25
+ };
9
26
  export const GLOBAL_STYLE_CHECKS = [
10
- // textFontFamily: must be a recognized camelCase font key (e.g. 'playfairDisplay')
11
27
  (args) => {
12
- const font = args.textStyles?.textFontFamily;
13
- if (font == null)
28
+ const keepRuns = args.textStyles?.keepRuns;
29
+ if (keepRuns == null)
14
30
  return null;
15
- return !STYLE_RULES.fontFamilyKeys.has(font)
16
- ? `"textFontFamily" "${font}" is not a recognized font family key`
31
+ return !Array.isArray(keepRuns) ||
32
+ keepRuns.some((run) => typeof run !== 'string')
33
+ ? `"textStyles.keepRuns" must be an array of strings`
17
34
  : null;
18
35
  },
19
- // textStyleOptions[category].style — fontSize, fontFamily, lineHeight, letterSpacing
20
36
  ...TEXT_STYLE_OPTION_KEYS.map((category) => (args) => {
21
37
  const style = args.textStyles?.textStyleOptions?.[category]?.style;
22
38
  if (!style)
23
39
  return null;
24
- return validateStringStyleAttrs(`textStyleOptions.${category}.style`, style);
40
+ return validateStringStyleAttrs(`textStyleOptions.${category}.style`, normalizeGlobalTextStyleOption(style));
25
41
  }),
26
42
  ];
@@ -1,7 +1,11 @@
1
1
  import { SOCIAL_LINKS_ICON_DISPLAY_STYLES } from '../../../brand-page/models';
2
- import { enumCheck, itemCapCheck, runChecks, } from '../../sanitizers/section-args-validator';
2
+ import { MAX_TITLE_LENGTH } from '../../../brand-page/constants/font.constants';
3
+ import { enumCheck, itemCapCheck, runChecks, styleCheck, } from '../../sanitizers/section-args-validator';
4
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
3
5
  const CHECKS = [
6
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
4
7
  enumCheck('icon_style', Object.keys(SOCIAL_LINKS_ICON_DISPLAY_STYLES), 'social-links'),
8
+ styleCheck('title_style'),
5
9
  itemCapCheck({ brandSite: 4, brandPage: 4, arrayField: 'links' }, 'social-links'),
6
10
  ];
7
11
  export function validateSocialLinks(args, ctx) {
@@ -6,7 +6,7 @@ import type { Editor } from '@tiptap/vue-3';
6
6
  * chains. DOM-bound — client-only callers (font propagation, section style
7
7
  * fields).
8
8
  */
9
- export declare const applyStyleToRTEText: (externalEditor: Editor, contentText: string, newContentStyle: TextStyleDeclaration) => string;
9
+ export declare const applyStyleToRTEText: (externalEditor: Editor, contentText: string, newContentStyle: TextStyleDeclaration, keepRuns?: readonly string[]) => string;
10
10
  /**
11
11
  * Converts a Tiptap JSON document (ProseMirror document model) to an HTML
12
12
  * string via Tiptap's schema-driven static renderer (renderRteToHtml →
@@ -1,14 +1,17 @@
1
- import { renderRteToHtml, getRTEColor } from '../../brand-page-maker/utils';
1
+ import { renderRteToHtml } from '@shared/rte-render.util';
2
+ import { getRTEColor, isRoleVarRef, restoreLinkUnderlines, } from '../../brand-page-maker/utils';
2
3
  import { getRenderText } from '../../brand-page/utils';
3
4
  import { ESCAPED_NEWLINE_CHARACTER } from '../../constants/ui';
4
5
  import { isTiptapDocument } from '../parsers/section-tool-arguments';
6
+ // A kept phrase matches whole words only: "Taste" must not keep the start of "Tasteful".
7
+ const isWordChar = (char) => char !== undefined && /[\p{L}\p{N}_]/u.test(char);
5
8
  /**
6
9
  * Applies a TextStyleDeclaration to RTE HTML by loading it into the given
7
10
  * (external/headless) Tiptap editor and rewriting inline marks via command
8
11
  * chains. DOM-bound — client-only callers (font propagation, section style
9
12
  * fields).
10
13
  */
11
- export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle) => {
14
+ export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle, keepRuns) => {
12
15
  if (!contentText) {
13
16
  return contentText;
14
17
  }
@@ -16,47 +19,101 @@ export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle
16
19
  ? getRenderText(contentText)
17
20
  : contentText;
18
21
  externalEditor.commands.setContent(content);
19
- let chain = externalEditor.chain().selectAll();
20
- if (newContentStyle?.fontFamily) {
21
- chain = chain.setFontFamily(newContentStyle.fontFamily);
22
+ const kept = new Set(keepRuns?.map((text) => text.trim().toLowerCase()).filter(Boolean));
23
+ const apply = (from, to) => {
24
+ let chain = from === 0
25
+ ? externalEditor.chain().selectAll()
26
+ : externalEditor.chain().setTextSelection({ from, to });
27
+ if (newContentStyle?.fontFamily) {
28
+ chain = chain.setFontFamily(newContentStyle.fontFamily);
29
+ }
30
+ if (newContentStyle?.fontSize) {
31
+ chain = chain.setFontSize(newContentStyle.fontSize);
32
+ }
33
+ if (newContentStyle?.letterSpacing) {
34
+ chain = chain.setLetterSpacing(newContentStyle.letterSpacing);
35
+ }
36
+ if (newContentStyle?.lineHeight) {
37
+ chain = chain.setLineHeight(newContentStyle.lineHeight);
38
+ }
39
+ if (newContentStyle?.color) {
40
+ chain = chain.setMark('textStyle', {
41
+ color: getRTEColor(newContentStyle.color, 'text'),
42
+ });
43
+ }
44
+ if ('backgroundColor' in (newContentStyle || {})) {
45
+ chain = newContentStyle.backgroundColor
46
+ ? chain.setMark('highlight', {
47
+ color: getRTEColor(newContentStyle.backgroundColor, 'background'),
48
+ })
49
+ : chain.unsetHighlight();
50
+ }
51
+ if (newContentStyle?.textAlign) {
52
+ chain = chain.setTextAlign(newContentStyle.textAlign);
53
+ }
54
+ // Emphasis is touched only when the style names it: a colour-only rewrite keeps every
55
+ // <strong>/<em>/<u>/<s>. A role ref replaces the competing marks, as the JSON relink does.
56
+ const { fontWeight, fontStyle, textDecoration } = newContentStyle ?? {};
57
+ if (newContentStyle && 'textDecoration' in newContentStyle) {
58
+ chain = textDecoration?.includes('line-through')
59
+ ? chain.setStrike()
60
+ : chain.unsetStrike();
61
+ chain = textDecoration?.includes('underline')
62
+ ? chain.setUnderline()
63
+ : chain.unsetUnderline();
64
+ if (isRoleVarRef(textDecoration))
65
+ chain = chain.setTextDecoration(textDecoration);
66
+ }
67
+ if (newContentStyle && 'fontWeight' in newContentStyle) {
68
+ chain = fontWeight === 'bold' ? chain.setBold() : chain.unsetBold();
69
+ if (isRoleVarRef(fontWeight))
70
+ chain = chain.setFontWeight(fontWeight);
71
+ }
72
+ if (newContentStyle && 'fontStyle' in newContentStyle) {
73
+ chain = fontStyle === 'italic' ? chain.setItalic() : chain.unsetItalic();
74
+ if (isRoleVarRef(fontStyle))
75
+ chain = chain.setFontStyle(fontStyle);
76
+ }
77
+ chain.command(restoreLinkUnderlines(externalEditor)).run();
78
+ };
79
+ if (!kept.size) {
80
+ apply(0, externalEditor.state.doc.content.size);
81
+ return externalEditor.getHTML();
22
82
  }
23
- if (newContentStyle?.fontSize) {
24
- chain = chain.setFontSize(newContentStyle.fontSize);
25
- }
26
- if (newContentStyle?.letterSpacing) {
27
- chain = chain.setLetterSpacing(newContentStyle.letterSpacing);
28
- }
29
- if (newContentStyle?.lineHeight) {
30
- chain = chain.setLineHeight(newContentStyle.lineHeight);
31
- }
32
- if (newContentStyle?.color) {
33
- chain = chain.setMark('textStyle', {
34
- color: getRTEColor(newContentStyle.color, 'text'),
83
+ const nodes = [];
84
+ externalEditor.state.doc.descendants((node, pos) => {
85
+ if (!node.isText || !node.text)
86
+ return;
87
+ nodes.push({
88
+ from: pos,
89
+ text: node.text,
35
90
  });
91
+ });
92
+ for (const node of nodes) {
93
+ const text = node.text.toLowerCase();
94
+ const ranges = [];
95
+ kept.forEach((keptText) => {
96
+ let start = text.indexOf(keptText);
97
+ while (start !== -1) {
98
+ const end = start + keptText.length;
99
+ const isWholeWords = !isWordChar(text[start - 1]) && !isWordChar(text[end]);
100
+ if (isWholeWords)
101
+ ranges.push([start, end]);
102
+ start = text.indexOf(keptText, isWholeWords ? end : start + 1);
103
+ }
104
+ });
105
+ ranges.sort(([left], [right]) => left - right);
106
+ let offset = 0;
107
+ for (const [start, end] of ranges) {
108
+ if (offset < start) {
109
+ apply(node.from + offset, node.from + start);
110
+ }
111
+ offset = Math.max(offset, end);
112
+ }
113
+ if (offset < node.text.length) {
114
+ apply(node.from + offset, node.from + node.text.length);
115
+ }
36
116
  }
37
- if ('backgroundColor' in (newContentStyle || {})) {
38
- chain = newContentStyle.backgroundColor
39
- ? chain.setMark('highlight', {
40
- color: getRTEColor(newContentStyle.backgroundColor, 'background'),
41
- })
42
- : chain.unsetHighlight();
43
- }
44
- if (newContentStyle?.textAlign) {
45
- chain = chain.setTextAlign(newContentStyle.textAlign);
46
- }
47
- const hasStrike = newContentStyle?.textDecoration?.includes('line-through');
48
- const hasUnderline = newContentStyle?.textDecoration?.includes('underline');
49
- chain = hasStrike ? chain.setStrike() : chain.unsetStrike();
50
- chain = hasUnderline ? chain.setUnderline() : chain.unsetUnderline();
51
- chain =
52
- newContentStyle?.fontWeight === 'bold'
53
- ? chain.setBold()
54
- : chain.unsetBold();
55
- chain =
56
- newContentStyle?.fontStyle === 'italic'
57
- ? chain.setItalic()
58
- : chain.unsetItalic();
59
- chain.run();
60
117
  return externalEditor.getHTML();
61
118
  };
62
119
  /**
@@ -1,6 +1,7 @@
1
1
  import cloneDeep from 'lodash.clonedeep';
2
2
  import {} from '../brand-page/models';
3
3
  import { referencifyModelColors } from '../brand-page/utils/color-palette-referencify.util';
4
+ import { applyTextContrast } from '../brand-page/utils/container-text-color.util';
4
5
  import { BUILDER_TYPES, } from './models';
5
6
  import { BannerSectionBuilder, BookingSectionBuilder, SupportMeBuilder, AboutSectionBuilder, ContactFormBuilder, DividerSectionBuilder, TextSectionBuilder, TestimonialSectionBuilder, ImagesSectionBuilder, ShapesSectionBuilder, SocialLinksBuilder, ImageGalleryBuilder, ProfileSectionBuilder, MailingListSectionBuilder, ButtonSectionBuilder, DeleteSectionBuilder, MoveSectionBuilder, } from './builders/section-builders';
6
7
  import { AddPageBuilder } from './builders/add-page-builder';
@@ -12,6 +13,26 @@ import { FooterBuilder } from './builders/footer-builder';
12
13
  import { GlobalStylesBuilder } from './builders/global-styles-builder';
13
14
  import { HeaderBuilder } from './builders/header-builder';
14
15
  import { UndoBuilder } from './builders/undo-builder';
16
+ /**
17
+ * BP-5969 (ADR-0020): bake a birth-time contrast colour into an uncoloured section's text so
18
+ * the AI path matches the maker's Add path (which bakes via `applyTextContrast` in
19
+ * `addItemByType`). Runs AFTER referencify, so section surfaces are palette refs the
20
+ * contrast resolver can read. Limited to `touchedContentIds` (the sections this call's own
21
+ * requests created or updated, via each result's `contentId`) — sweeping every section on every
22
+ * apply follows the prompt for sections it never touched too, recolouring content the call
23
+ * didn't ask about and re-writing RTE style objects a migration had already stripped. Mutates
24
+ * `model` in place and returns it.
25
+ */
26
+ const bakeContrastAcrossModel = (model, touchedContentIds) => {
27
+ model.pages?.forEach((page) => {
28
+ page.contents?.forEach((content) => {
29
+ if (content.id && touchedContentIds.has(content.id)) {
30
+ applyTextContrast(content, model.styles, model.brandPageType);
31
+ }
32
+ });
33
+ });
34
+ return model;
35
+ };
15
36
  // Lazy initialization to avoid circular dependency issues
16
37
  const getBuilderRegistry = () => ({
17
38
  // Section builders (create)
@@ -127,6 +148,7 @@ export class MetadataExecutor {
127
148
  results.push(result);
128
149
  model = result.model;
129
150
  }
151
+ const touchedContentIds = new Set(results.flatMap((result) => (result.contentId ? [result.contentId] : [])));
130
152
  return {
131
153
  // The inbound half of the AI colour bridge. The AI answers in literals (it
132
154
  // was sent literals — see `minifyBrandPageMetadata`) and migration-21 is
@@ -134,7 +156,7 @@ export class MetadataExecutor {
134
156
  // half hex, and editing a palette role silently skips every section the AI
135
157
  // touched. Mutates `model` in place — minting into `model.styles.colors` — and
136
158
  // returns it; touches no store.
137
- model: referencifyModelColors(model),
159
+ model: bakeContrastAcrossModel(referencifyModelColors(model), touchedContentIds),
138
160
  results,
139
161
  };
140
162
  }
@@ -84,6 +84,8 @@ export interface BuilderResult {
84
84
  request: MetadataBuilderRequest;
85
85
  model: BrandPageModel;
86
86
  errors?: string[];
87
+ /** Non-failing feedback for an accepted tool call that dropped unsupported input. */
88
+ warnings?: string[];
87
89
  /**
88
90
  * Set by the UndoBuilder to signal that the caller should restore the
89
91
  * website to the snapshot taken before the most recent change-producing
@@ -1,6 +1,7 @@
1
1
  import type { AiAssistantToolCall } from '../../clients/ai-assistant-client';
2
2
  import type { FooterDisplayStyle, HeaderDisplayStyle, NavigationDisplayType } from '../../brand-page/constants';
3
3
  import type { SectionType, TextStyleArguments } from './section-tool-arguments';
4
+ import type { TextStyleType } from '../../brand-page/models';
4
5
  export declare const AI_ASSISTANT_TOOL_NAMES: {
5
6
  readonly BUILD_PROFILE_SECTION: "build_profile_section";
6
7
  readonly BUILD_TEXT_SECTION: "build_text_section";
@@ -135,6 +136,11 @@ export interface UpdateFooterArguments {
135
136
  /** Mobile-only styling (display_style, background_color, icon_color, is_logo_visible, logo sizes). */
136
137
  mobile?: ViewportFooterOverrides;
137
138
  }
139
+ /**
140
+ * A role's typography patch. A sent `fontWeight` / `fontStyle` / `textDecoration` relinks the
141
+ * role's existing content even when it equals the stored role (the pipeline sends them only when
142
+ * the user asked); the other properties relink only when they change (`global-role-propagation`).
143
+ */
138
144
  export interface TextStyleOptionStyle {
139
145
  fontFamily?: string;
140
146
  fontSize?: string;
@@ -164,25 +170,18 @@ export interface UpdateGlobalStylesArguments {
164
170
  style?: {
165
171
  color?: string;
166
172
  };
167
- textFontFamily?: string;
168
- textStyleOptions?: {
169
- titles?: {
170
- style?: TextStyleOptionStyle;
171
- isModified?: boolean;
172
- };
173
- headings?: {
174
- style?: TextStyleOptionStyle;
175
- isModified?: boolean;
176
- };
177
- paragraphs?: {
178
- style?: TextStyleOptionStyle;
179
- isModified?: boolean;
180
- };
181
- buttons?: {
182
- style?: TextStyleOptionStyle;
183
- isModified?: boolean;
184
- };
185
- };
173
+ /** Retired — accepted from the pipeline but ignored (`0036-retire-text-font-family.md`). */
174
+ textFontFamily?: unknown;
175
+ textStyleOptions?: Partial<Record<TextStyleType, {
176
+ style?: TextStyleOptionStyle;
177
+ isModified?: boolean;
178
+ }>>;
179
+ /**
180
+ * BP-5969 (R16) — the run texts the user explicitly asked to keep during this site-wide
181
+ * change. The library skips relinking a run or a plain field whose trimmed text matches one
182
+ * of these, case-insensitively; every other run of the changed role/property still relinks.
183
+ */
184
+ keepRuns?: string[];
186
185
  };
187
186
  buttonStyles?: {
188
187
  style?: {