@designcrowd/library.brand-page 6.0.5 → 6.0.6-ast-bugs

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 (395) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DhzvKlTS.js → CreatedOnBrandCrowd-de-de-SHCspMwS.js} +3 -3
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DKH4lmNV.js → CreatedOnBrandCrowd-en-us-C6lITAAT.js} +3 -3
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-RloPCLuV.js → CreatedOnBrandCrowd-es-es-Uh69c4vZ.js} +3 -3
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-Cu9e2H0K.js → CreatedOnBrandCrowd-fr-ca-Bb0rp7BV.js} +3 -3
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-Cu9e2H0K.js → CreatedOnBrandCrowd-fr-fr-Bb0rp7BV.js} +3 -3
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CiCnjxBZ.js → CreatedOnBrandCrowd-pt-br-DsrQHcjs.js} +3 -3
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-CiCnjxBZ.js → CreatedOnBrandCrowd-pt-pt-DsrQHcjs.js} +3 -3
  8. package/lib/src/{CreatedOnDcom-de-de-CwlnedFV.js → CreatedOnDcom-de-de-BshZYzSp.js} +3 -3
  9. package/lib/src/{CreatedOnDcom-en-us-DFHex61v.js → CreatedOnDcom-en-us-CLu8mKUW.js} +3 -3
  10. package/lib/src/{CreatedOnDcom-es-es-BTxH6I4V.js → CreatedOnDcom-es-es-BZYhkONd.js} +3 -3
  11. package/lib/src/{CreatedOnDcom-fr-ca-BVw0KYxu.js → CreatedOnDcom-fr-ca-CIaBEp_9.js} +3 -3
  12. package/lib/src/{CreatedOnDcom-fr-fr-DaqNz1Er.js → CreatedOnDcom-fr-fr-dyF7hioJ.js} +3 -3
  13. package/lib/src/{CreatedOnDcom-pt-br-B4KsMI8W.js → CreatedOnDcom-pt-br-CUHjk2du.js} +3 -3
  14. package/lib/src/{CreatedOnDcom-pt-pt-CWoHEtOZ.js → CreatedOnDcom-pt-pt-CWDvQidv.js} +3 -3
  15. package/lib/src/brand-page/clients/brand-page.client.d.ts +9 -9
  16. package/lib/src/brand-page/components/banner-section/BannerSection.mixin.d.ts +103 -0
  17. package/lib/src/brand-page/components/banner-section/BannerSection.mixin.js +178 -0
  18. package/lib/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.d.ts +1 -2
  19. package/lib/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.d.ts +4 -2
  20. package/lib/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.js +1 -0
  21. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +4 -2
  22. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +11 -5
  23. package/lib/src/brand-page/components/page/Page.mixin.d.ts +1 -1
  24. package/lib/src/brand-page/components/page/PageComponent.mixin.d.ts +1 -1
  25. package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +3 -3
  26. package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +13 -13
  27. package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +13 -13
  28. package/lib/src/brand-page/constants/sections/footer-display.constants.js +1 -1
  29. package/lib/src/brand-page/models/index.d.ts +2 -13
  30. package/lib/src/brand-page/models/index.js +3 -0
  31. package/lib/src/brand-page/models/payment.model.d.ts +1 -1
  32. package/lib/src/brand-page/utils/personalisation.util.js +72 -14
  33. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +21 -19
  34. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.js +1 -0
  35. package/lib/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.d.ts +16 -10
  36. package/lib/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.d.ts +1 -1
  37. package/lib/src/brand-page-maker/components/admin-logo-settings/AdminLogoSettings.mixin.d.ts +3 -3
  38. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +181 -170
  39. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +3 -0
  40. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.js +1 -0
  41. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +12 -12
  42. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.stories.js +2 -2
  43. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-payment.js +0 -7
  44. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +148 -149
  45. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +21 -21
  46. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.js +1 -1
  47. package/lib/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.d.ts +4 -2
  48. package/lib/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.js +1 -0
  49. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.d.ts +4 -2
  50. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.js +1 -0
  51. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.d.ts +5 -2
  52. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.js +1 -0
  53. package/lib/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.d.ts +4 -2
  54. package/lib/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.js +1 -0
  55. package/lib/src/brand-page-maker/components/device/Device.mixin.d.ts +4 -2
  56. package/lib/src/brand-page-maker/components/device/Device.mixin.js +1 -0
  57. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +4 -2
  58. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.js +1 -0
  59. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +3 -3
  60. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +11 -11
  61. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +27 -25
  62. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.js +1 -0
  63. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +27 -27
  64. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.js +1 -1
  65. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +17 -12
  66. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +12 -12
  67. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +30 -32
  68. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +16 -5
  69. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +11 -11
  70. package/lib/src/brand-page-maker/composables/ai-chat/types.d.ts +3 -0
  71. package/lib/src/brand-page-maker/composables/ai-chat/ui-actions.d.ts +29 -0
  72. package/lib/src/brand-page-maker/composables/ai-chat/ui-actions.js +32 -0
  73. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +204 -177
  74. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
  75. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +6 -6
  76. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +3 -2
  77. package/lib/src/brand-page-maker/composables/useEventTracker.js +1 -0
  78. package/lib/src/brand-page-maker/constants/config-settings-constant.d.ts +6 -6
  79. package/lib/src/brand-page-maker/constants/config-settings-constant.js +3 -3
  80. package/lib/src/brand-page-maker/convertors/text-image-display-style.convertor.d.ts +1 -1
  81. package/lib/src/brand-page-maker/convertors/text-image-display-style.convertor.js +1 -1
  82. package/lib/src/brand-page-maker/models/content-settings.d.ts +1 -1
  83. package/lib/src/brand-page-maker/models/navigation-style-configs.js +1 -1
  84. package/lib/src/brand-page-maker/routing/brand-page-maker-router.d.ts +1 -2
  85. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +366 -378
  86. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +5 -4
  87. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +8 -5
  88. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +3 -1
  89. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +7 -3
  90. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +15 -15
  91. package/lib/src/brand-page-maker/stores/ui/ui-store.d.ts +6 -0
  92. package/lib/src/brand-page-maker/stores/ui/ui-store.js +8 -0
  93. package/lib/src/brand-page-maker/utils/content-settings.util.js +1 -1
  94. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +1 -1
  95. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +4 -4
  96. package/lib/src/clients/ai-assistant-client.d.ts +7 -0
  97. package/lib/src/clients/brand-page-client.d.ts +16 -15
  98. package/lib/src/clients/design-template-client.d.ts +3 -0
  99. package/lib/src/clients/media-client.d.ts +2 -2
  100. package/lib/src/clients/models.d.ts +2 -0
  101. package/lib/src/composables/useSnapshot.js +18 -18
  102. package/lib/src/css/library.brand-page-brandCrowd.min.css +371 -344
  103. package/lib/src/css/library.brand-page-brandPage.min.css +649 -344
  104. package/lib/src/css/library.brand-page-designCom.min.css +371 -344
  105. package/lib/src/css/library.brand-page-preview.min.css +627 -344
  106. package/lib/src/index.d.ts +4 -0
  107. package/lib/src/index.mjs +107 -104
  108. package/lib/src/{lib-BPI8E2Ui.js → lib-COw-Rz05.js} +37005 -33761
  109. package/lib/src/lib.js +10 -0
  110. package/lib/src/metadata-builder/builders/footer-builder.js +105 -62
  111. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +68 -57
  112. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +93 -58
  113. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +99 -66
  114. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +17 -57
  115. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +85 -51
  116. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +74 -49
  117. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +7 -0
  118. package/lib/src/metadata-builder/builders/section-field-utils.js +1 -1
  119. package/lib/src/metadata-builder/builders/shape-color-utils.js +1 -1
  120. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +7 -16
  121. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +48 -66
  122. package/lib/src/plugins/google-maps-plugin/google-maps-plugin.d.ts +1 -1
  123. package/lib/src/plugins/google-maps-plugin/google-maps-plugin.js +8 -8
  124. package/lib/src/shared/background-settings/components/background-shapes/BackgroundShapeSettings.mixin.d.ts +13 -13
  125. package/lib/src/shared/background-settings/store/background-settings-store.d.ts +3 -3
  126. package/lib/src/shared/color-picker/components/ColorPicker.mixin.d.ts +4 -2
  127. package/lib/src/shared/color-picker/components/ColorPicker.mixin.js +2 -2
  128. package/lib/src/shared/color-picker/components/ColorPickerSwatch.mixin.d.ts +4 -2
  129. package/lib/src/shared/color-picker/components/ColorPickerSwatch.mixin.js +1 -0
  130. package/lib/src/shared/confirm-modal/ConfirmModal.mixin.d.ts +5 -2
  131. package/lib/src/shared/confirm-modal/ConfirmModal.mixin.js +1 -0
  132. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +0 -1
  133. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +131 -129
  134. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -1
  135. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +111 -110
  136. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +84 -81
  137. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +5 -0
  138. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +117 -109
  139. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +1 -14
  140. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +0 -1
  141. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +72 -70
  142. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +4 -3
  143. package/lib/src/shared/content-settings/components/form-fields-field/FormFieldsField.mixin.d.ts +4 -4
  144. package/lib/src/shared/content-settings/components/icon-library/IconLibrary.mixin.d.ts +3 -1
  145. package/lib/src/shared/content-settings/components/icon-library/IconLibrary.mixin.js +1 -0
  146. package/lib/src/shared/content-settings/components/images-field/ImagesField.mixin.d.ts +2 -2
  147. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.d.ts +4 -3
  148. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.js +1 -1
  149. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +40 -40
  150. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigOptionField.mixin.d.ts +5 -6
  151. package/lib/src/shared/content-settings/components/shape-field/ShapeField.mixin.d.ts +0 -1
  152. package/lib/src/shared/content-settings/components/slider-field/SliderField.mixin.d.ts +2 -2
  153. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +0 -1
  154. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +1 -2
  155. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +0 -1
  156. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
  157. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -1
  158. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +28 -28
  159. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +0 -1
  160. package/lib/src/shared/content-settings/components/toggle-field/ToggleField.mixin.d.ts +2 -2
  161. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +0 -1
  162. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +0 -1
  163. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +39 -39
  164. package/lib/src/shared/content-settings/utils.js +0 -1
  165. package/lib/src/shared/font-family-selector/FontFamilySelector.mixin.d.ts +6 -4
  166. package/lib/src/shared/font-family-selector/FontFamilySelector.mixin.js +1 -0
  167. package/lib/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.d.ts +4 -2
  168. package/lib/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.js +1 -0
  169. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +29 -21
  170. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.js +1 -1
  171. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +50 -51
  172. package/lib/src/shared/logo-settings/components/LogoSettingsHeader.mixin.d.ts +6 -4
  173. package/lib/src/shared/logo-settings/components/LogoSettingsHeader.mixin.js +1 -0
  174. package/lib/src/shared/logo-settings/store/editable-logo-store.js +1 -1
  175. package/lib/src/shared/logo-settings/store/logo-settings-store.d.ts +1 -1
  176. package/lib/src/shared/logo-versions/LogoVersions.mixin.d.ts +13 -5
  177. package/lib/src/shared/logo-versions/LogoVersions.mixin.js +1 -0
  178. package/lib/src/shared/models.d.ts +2 -0
  179. package/lib/src/shared/my-designs/MyDesigns.mixin.d.ts +14 -6
  180. package/lib/src/shared/my-designs/MyDesigns.mixin.js +1 -0
  181. package/lib/src/shared/my-uploads/MyMedia.mixin.d.ts +14 -5
  182. package/lib/src/shared/my-uploads/MyMedia.mixin.js +1 -0
  183. package/lib/src/shared/my-uploads/MyUploads.mixin.d.ts +14 -5
  184. package/lib/src/shared/my-uploads/MyUploads.mixin.js +1 -0
  185. package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.d.ts +5 -3
  186. package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.js +1 -0
  187. package/lib/src/shared/navigation-style-settings/store/index.d.ts +2 -2
  188. package/lib/src/shared/page-navigation/store/page-navigation-store.d.ts +2 -2
  189. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +27 -28
  190. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.js +0 -2
  191. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +188 -179
  192. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +181 -177
  193. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +1 -1
  194. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +9 -9
  195. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +39 -39
  196. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.js +0 -1
  197. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +18 -18
  198. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +6 -6
  199. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +66 -60
  200. package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -1
  201. package/lib/src/shared/style-settings/store/style-settings-store.js +1 -1
  202. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +20 -450
  203. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.js +2 -2
  204. package/lib/src/shared/template-settings/models.d.ts +1 -0
  205. package/lib/src/shared/template-settings/store/template-settings-store.d.ts +4 -0
  206. package/lib/src/shared/template-settings/store/template-settings-store.js +79 -11
  207. package/lib/src/shared/unsplash-library/UnsplashLibrary.mixin.d.ts +9 -4
  208. package/lib/src/utils/build-asset-manifest.d.ts +4 -0
  209. package/lib/src/utils/build-asset-manifest.js +8 -0
  210. package/lib/src/utils/minify-brand-page-metadata.d.ts +0 -2
  211. package/lib/src/utils/minify-brand-page-metadata.js +2 -17
  212. package/package.json +60 -56
  213. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +7 -5
  214. package/src/brand-page/components/banner-section/BannerSection.mixin.ts +210 -0
  215. package/src/brand-page/components/banner-section/BannerSection.vue +5 -1
  216. package/src/brand-page/components/brand-page-footer/BrandPageFooter.vue +1 -1
  217. package/src/brand-page/components/image/Image.mixin.ts +1 -1
  218. package/src/brand-page/components/image/Image.test.ts +1 -1
  219. package/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.ts +1 -2
  220. package/src/brand-page/components/images-section/ImagesSection.vue +0 -1
  221. package/src/brand-page/components/logo/LogoRender.vue +188 -188
  222. package/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.ts +1 -0
  223. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +25 -8
  224. package/src/brand-page/components/page-footer/PageFooter.vue +1 -0
  225. package/src/brand-page/components/page-header/HeaderLayout.vue +12 -6
  226. package/src/brand-page/components/page-header/PageHeader.vue +1 -0
  227. package/src/brand-page/components/shapes-section/ShapesSection.vue +1 -1
  228. package/src/brand-page/components/shop/CartModal.vue +1 -3
  229. package/src/brand-page/components/shop/FeaturedDisplay.vue +2 -2
  230. package/src/brand-page/components/shop/PaymentModal.vue +1 -5
  231. package/src/brand-page/components/shop/ProductDetailModal.vue +1 -1
  232. package/src/brand-page/components/shop/Shop.vue +1 -5
  233. package/src/brand-page/components/shop/TextDisplay.vue +1 -1
  234. package/src/brand-page/components/shop/ThumbnailDisplay.vue +2 -2
  235. package/src/brand-page/components/testimonial-section/TestimonialSection.vue +3 -3
  236. package/src/brand-page/components/text-wrapper/TextWrapper.vue +3 -1
  237. package/src/brand-page/constants/sections/footer-display.constants.ts +1 -1
  238. package/src/brand-page/models/index.ts +4 -12
  239. package/src/brand-page/models/payment.model.ts +2 -1
  240. package/src/brand-page/models/shop.model.ts +0 -2
  241. package/src/brand-page/models/user-personalisation.model.ts +1 -2
  242. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -0
  243. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +1 -0
  244. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +2 -0
  245. package/src/brand-page/utils/migration/migration-01_1.ts +1 -1
  246. package/src/brand-page/utils/migration/migration-02.ts +0 -1
  247. package/src/brand-page/utils/migration/migration-03.ts +0 -1
  248. package/src/brand-page/utils/migration/migration-04.ts +0 -1
  249. package/src/brand-page/utils/migration/migration-05.ts +1 -5
  250. package/src/brand-page/utils/migration/migration-05_2.ts +1 -1
  251. package/src/brand-page/utils/migration/migration-08.test.ts +1 -1
  252. package/src/brand-page/utils/personalisation.util.test.ts +35 -0
  253. package/src/brand-page/utils/personalisation.util.ts +119 -23
  254. package/src/brand-page/view-models.ts +38 -56
  255. package/src/brand-page-maker/assessors/banner-section-description-visibility.assessor.ts +6 -6
  256. package/src/brand-page-maker/assessors/color-replacement-icon-visibility.assessor.ts +2 -2
  257. package/src/brand-page-maker/assessors/color-replacement-profile-visibility.assessor.ts +2 -2
  258. package/src/brand-page-maker/assessors/color-replacement-visibility.assessor.ts +2 -2
  259. package/src/brand-page-maker/assessors/contact-form-visibility.assessor.ts +14 -14
  260. package/src/brand-page-maker/components/action-bar/ActionBar.mixin.ts +1 -0
  261. package/src/brand-page-maker/components/ai-text-edit/AiActionButtons.vue +27 -12
  262. package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +3 -2
  263. package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +8 -7
  264. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +21 -1
  265. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +5 -1
  266. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.ts +1 -0
  267. package/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.stories.ts +2 -5
  268. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -5
  269. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-payment.ts +0 -8
  270. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-site-template.examples.ts +0 -2
  271. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.vue +1 -0
  272. package/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.ts +1 -1
  273. package/src/brand-page-maker/components/color-palette/BpColorPalette.vue +1 -2
  274. package/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.ts +1 -0
  275. package/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.ts +1 -0
  276. package/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.ts +1 -0
  277. package/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.ts +1 -0
  278. package/src/brand-page-maker/components/device/Device.mixin.ts +1 -0
  279. package/src/brand-page-maker/components/navigation/Navigation.mixin.ts +1 -0
  280. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +3 -1
  281. package/src/brand-page-maker/components/sensitive-content/SensitiveContent.vue +1 -4
  282. package/src/brand-page-maker/components/seo-settings/DeleteDomainModal.vue +1 -1
  283. package/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.ts +1 -0
  284. package/src/brand-page-maker/components/seo-settings/SeoPageSettings.vue +1 -1
  285. package/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.ts +0 -1
  286. package/src/brand-page-maker/components/seo-settings/UrlSettings.vue +0 -1
  287. package/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.vue +1 -5
  288. package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -1
  289. package/src/brand-page-maker/components/shop/ReplaceImageSettingsForShop.vue +1 -1
  290. package/src/brand-page-maker/components/social-share/SocialShare.vue +1 -1
  291. package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +22 -8
  292. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +5 -10
  293. package/src/brand-page-maker/components/template-preview/TemplatePreviewAiBadge.vue +12 -0
  294. package/src/brand-page-maker/components/video-play/VideoPlayButton.vue +1 -1
  295. package/src/brand-page-maker/composables/ai-chat/types.ts +6 -0
  296. package/src/brand-page-maker/composables/ai-chat/ui-actions.test.ts +80 -0
  297. package/src/brand-page-maker/composables/ai-chat/ui-actions.ts +58 -0
  298. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +308 -262
  299. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +6 -6
  300. package/src/brand-page-maker/composables/useEventTracker.ts +1 -0
  301. package/src/brand-page-maker/constants/config-settings-constant.ts +5 -5
  302. package/src/brand-page-maker/convertors/text-image-display-style.convertor.ts +1 -1
  303. package/src/brand-page-maker/models/button-styles-config.ts +4 -2
  304. package/src/brand-page-maker/models/content-settings-configs.ts +4 -2
  305. package/src/brand-page-maker/models/navigation-style-configs.ts +5 -6
  306. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +0 -1
  307. package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +8 -5
  308. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +1 -3
  309. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +12 -4
  310. package/src/brand-page-maker/stores/ui/ui-store.ts +16 -0
  311. package/src/brand-page-maker/utils/content-settings.util.ts +1 -1
  312. package/src/brand-page-maker/utils/rich-text-editor.util.ts +4 -4
  313. package/src/clients/ai-assistant-client.ts +7 -0
  314. package/src/clients/design-template-client.ts +3 -0
  315. package/src/clients/models.ts +2 -0
  316. package/src/composables/useSnapshot.ts +19 -22
  317. package/src/lib.ts +12 -0
  318. package/src/metadata-builder/builders/footer-builder.test.ts +130 -229
  319. package/src/metadata-builder/builders/footer-builder.ts +155 -90
  320. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +88 -62
  321. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +129 -66
  322. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +160 -105
  323. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +20 -65
  324. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +146 -83
  325. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +122 -70
  326. package/src/metadata-builder/builders/section-field-utils.ts +1 -1
  327. package/src/metadata-builder/builders/shape-color-utils.ts +2 -2
  328. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +7 -16
  329. package/src/metadata-builder/parsers/section-tool-arguments.ts +48 -66
  330. package/src/plugins/google-maps-plugin/google-maps-plugin.ts +8 -8
  331. package/src/shared/background-settings/components/BackgroundSettings.vue +1 -1
  332. package/src/shared/background-settings/components/background-color/BackgroundColorSettings.vue +1 -1
  333. package/src/shared/color-picker/components/ColorPicker.mixin.ts +2 -7
  334. package/src/shared/color-picker/components/ColorPickerSwatch.mixin.ts +1 -0
  335. package/src/shared/common/NumberInput.vue +1 -0
  336. package/src/shared/common/SideBarSettingsHeader.vue +2 -2
  337. package/src/shared/confirm-modal/ConfirmModal.mixin.ts +1 -0
  338. package/src/shared/content-settings/components/booking-url-field/BookingUrlField.vue +1 -0
  339. package/src/shared/content-settings/components/button-configuration-field/ButtonConfigurationField.vue +1 -0
  340. package/src/shared/content-settings/components/color-field/ColorField.vue +3 -10
  341. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -1
  342. package/src/shared/content-settings/components/content-settings/ContentSettingsLockedButton.vue +1 -0
  343. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +5 -0
  344. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +1 -14
  345. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +4 -6
  346. package/src/shared/content-settings/components/icon-library/IconLibrary.mixin.ts +1 -0
  347. package/src/shared/content-settings/components/items-field/ItemsField.mixin.ts +1 -1
  348. package/src/shared/content-settings/components/logo-selection-field/LogoSelectionField.vue +1 -1
  349. package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -1
  350. package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +1 -1
  351. package/src/shared/content-settings/components/personalisation-role-field/PersonalisationRoleField.vue +4 -4
  352. package/src/shared/content-settings/components/text-image-field/TextImageField.vue +2 -8
  353. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -1
  354. package/src/shared/content-settings/models.ts +3 -2
  355. package/src/shared/content-settings/utils.ts +0 -1
  356. package/src/shared/dropzone-image-uploader/components/DropzoneImageUploader.vue +1 -0
  357. package/src/shared/ecommerce-settings/store/cart-store.test.ts +1 -1
  358. package/src/shared/font-family-selector/FontFamilySelector.mixin.ts +1 -0
  359. package/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.ts +1 -0
  360. package/src/shared/logo-settings/components/EditLogoSettings.mixin.ts +1 -1
  361. package/src/shared/logo-settings/components/LogoSettings.mixin.ts +0 -1
  362. package/src/shared/logo-settings/components/LogoSettingsHeader.mixin.ts +1 -0
  363. package/src/shared/logo-settings/components/LogoStyleSettingsWithState.vue +2 -2
  364. package/src/shared/logo-settings/components/LogoTemplateSearch.vue +1 -1
  365. package/src/shared/logo-settings/store/editable-logo-store.ts +1 -1
  366. package/src/shared/logo-settings/store/logo-settings-store.test.ts +4 -4
  367. package/src/shared/logo-versions/LogoVersions.mixin.ts +1 -0
  368. package/src/shared/models.ts +6 -0
  369. package/src/shared/my-designs/MyDesigns.mixin.ts +1 -0
  370. package/src/shared/my-uploads/MyMedia.mixin.ts +1 -0
  371. package/src/shared/my-uploads/MyMediaSelectionItem.vue +2 -1
  372. package/src/shared/my-uploads/MyUploads.mixin.ts +1 -0
  373. package/src/shared/my-uploads/models.ts +1 -2
  374. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.ts +1 -0
  375. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -1
  376. package/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.ts +0 -3
  377. package/src/shared/page-settings/components/page-settings/NestedDraggable.vue +1 -1
  378. package/src/shared/page-settings/components/page-settings/PageSettings.vue +1 -2
  379. package/src/shared/page-settings/components/page-settings-section-styles/HeaderDisplayStyle.vue +1 -1
  380. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +1 -1
  381. package/src/shared/page-settings/store/page-settings-store.test.ts +4 -8
  382. package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.ts +0 -1
  383. package/src/shared/shape-library/ShapeLibrary.vue +2 -2
  384. package/src/shared/style-settings/store/style-settings-store.ts +1 -1
  385. package/src/shared/template-settings/components/TemplatesSettings.mixin.ts +2 -2
  386. package/src/shared/template-settings/models.ts +1 -0
  387. package/src/shared/template-settings/store/template-settings-store.ts +105 -18
  388. package/src/shared/unsplash-library/UnsplashLibrary.vue +2 -6
  389. package/src/shared/video-library/VideoLibrary.vue +1 -1
  390. package/src/utils/build-asset-manifest.ts +12 -0
  391. package/src/utils/minify-brand-page-metadata.ts +7 -27
  392. package/lib/src/metadata-builder/builders/item-id-utils.d.ts +0 -54
  393. package/lib/src/metadata-builder/builders/item-id-utils.js +0 -96
  394. package/src/metadata-builder/builders/item-id-utils.test.ts +0 -184
  395. package/src/metadata-builder/builders/item-id-utils.ts +0 -117
@@ -10,17 +10,22 @@ import {
10
10
  import type {
11
11
  UpdateFooterArguments,
12
12
  ViewportFooterOverrides,
13
+ FooterSocialLinkItem,
13
14
  } from '../parsers/ai-toolcall-parser';
14
15
  import type { Logger } from '../logger';
15
- import type { TextStyleOptions } from '../../brand-page/models/styles.model';
16
+ import type {
17
+ TextStyleDeclaration,
18
+ TextStyleOptions,
19
+ } from '../../brand-page/models/styles.model';
16
20
  import { FOOTER_CHECKS } from './section-rules/footer.rules';
17
- import { applyDetachedStyleOverride } from './section-field-utils';
18
21
  import {
19
- ensureItemIds,
20
- generateItemId,
21
- removeItemsByIds,
22
- repositionItemByAnchor,
23
- } from './item-id-utils';
22
+ applyDetachedStyleOverride,
23
+ normalizeStyleValue,
24
+ } from './section-field-utils';
25
+
26
+ type FooterSocialLink = NonNullable<
27
+ AbstractPageFooterStyles['socialLinks']
28
+ >[number];
24
29
 
25
30
  const normaliseSocialUrl = (url: string): string => {
26
31
  for (const prefix of ['mailto:', 'tel:']) {
@@ -30,6 +35,113 @@ const normaliseSocialUrl = (url: string): string => {
30
35
  return url;
31
36
  };
32
37
 
38
+ const makeSocialLink = (
39
+ icon: string | undefined,
40
+ url: string | undefined,
41
+ ): FooterSocialLink =>
42
+ ({
43
+ imageUrl: icon || '',
44
+ url: normaliseSocialUrl(url || ''),
45
+ imageTitle: '',
46
+ width: 0,
47
+ height: 0,
48
+ imageLink: '',
49
+ }) as FooterSocialLink;
50
+
51
+ const hasSocialLinkMutation = (args: UpdateFooterArguments): boolean =>
52
+ args._replace_social_links === true ||
53
+ (args._remove_social_link_indices?.length ?? 0) > 0 ||
54
+ (args._reorder_social_links?.length ?? 0) > 0 ||
55
+ (args.social_links?.length ?? 0) > 0;
56
+
57
+ /**
58
+ * Social links are a GLOBAL footer concern — one logical list that both
59
+ * viewports render identically. Derive the new list ONCE from the current one
60
+ * WITHOUT mutating the input, so the caller can assign an independent copy to
61
+ * each viewport.
62
+ *
63
+ * Why this can't mutate per-viewport in place: footers migrated from the legacy
64
+ * single `footerStyles` model (migration-01) share ONE `socialLinks` array
65
+ * reference across pageFooterDesktop and pageFooterMobile, and `cloneDeep`
66
+ * preserves that shared reference. Running an in-place `splice` once per
67
+ * viewport therefore applies it TWICE to the same array — e.g. one requested
68
+ * removal index drops two links. Compute-once + assign-fresh is correct for
69
+ * both shared (legacy) and independent (new-model) footers.
70
+ */
71
+ const computeSocialLinks = (
72
+ current: FooterSocialLink[] | undefined,
73
+ args: UpdateFooterArguments,
74
+ ): FooterSocialLink[] => {
75
+ // _replace_social_links: replace entire list (empty/absent social_links = clear all).
76
+ // A replacement supersedes every other social link mutation.
77
+ if (args._replace_social_links) {
78
+ return (args.social_links ?? []).map((l) =>
79
+ makeSocialLink(l.social_link_icon, l.url),
80
+ );
81
+ }
82
+
83
+ const links: FooterSocialLink[] = [...(current ?? [])];
84
+
85
+ // item_index-based updates for existing links — replace the item reference
86
+ // (never mutate the original object, which may be shared across viewports).
87
+ for (const link of args.social_links ?? []) {
88
+ if (link.item_index === undefined) continue;
89
+
90
+ const existing = links[link.item_index];
91
+
92
+ if (!existing) continue;
93
+
94
+ links[link.item_index] = {
95
+ ...existing,
96
+ ...(link.social_link_icon !== undefined
97
+ ? { imageUrl: link.social_link_icon }
98
+ : {}),
99
+ ...(link.url !== undefined ? { url: normaliseSocialUrl(link.url) } : {}),
100
+ };
101
+ }
102
+
103
+ // Remove by index (descending order to preserve indices during splice).
104
+ if (args._remove_social_link_indices?.length) {
105
+ const sorted = [...args._remove_social_link_indices].sort((a, b) => b - a);
106
+
107
+ for (const idx of sorted) {
108
+ if (idx >= 0 && idx < links.length) links.splice(idx, 1);
109
+ }
110
+ }
111
+
112
+ // Insert new links (descending insert_at order to preserve positions).
113
+ const insertLinks = (args.social_links ?? []).filter(
114
+ (l): l is FooterSocialLinkItem & { insert_at: number } =>
115
+ l.insert_at !== undefined && l.item_index === undefined,
116
+ );
117
+ const sortedInserts = [...insertLinks].sort(
118
+ (a, b) => b.insert_at - a.insert_at,
119
+ );
120
+
121
+ for (const link of sortedInserts) {
122
+ const pos = Math.max(0, Math.min(link.insert_at, links.length));
123
+
124
+ links.splice(pos, 0, makeSocialLink(link.social_link_icon, link.url));
125
+ }
126
+
127
+ // Reorder (requires ALL indices — partial reorder is not supported).
128
+ if (args._reorder_social_links?.length) {
129
+ const newOrder = args._reorder_social_links;
130
+ const unique = new Set(newOrder);
131
+
132
+ if (
133
+ unique.size === newOrder.length &&
134
+ newOrder.every((idx) => idx >= 0 && idx < links.length)
135
+ ) {
136
+ const reordered = newOrder.map((idx) => links[idx]);
137
+
138
+ if (reordered.length === links.length) return reordered;
139
+ }
140
+ }
141
+
142
+ return links;
143
+ };
144
+
33
145
  const applyGlobalFooterChanges = (
34
146
  footer: AbstractPageFooterStyles,
35
147
  args: UpdateFooterArguments,
@@ -38,85 +150,27 @@ const applyGlobalFooterChanges = (
38
150
  if (args.copyright_text !== undefined)
39
151
  footer.copyrightText = args.copyright_text;
40
152
 
41
- if (args.copyright_text_font_family !== undefined)
42
- footer.copyrightStyle = applyDetachedStyleOverride(
43
- footer.copyrightStyle,
44
- { fontFamily: args.copyright_text_font_family },
45
- textStyleOptions,
46
- );
153
+ // copyright_text_style is the same text-style object sections use (typography
154
+ // + colour). Normalise each value the way section styles are normalised
155
+ // (letterSpacing int→em, lineHeight snap, null→''), then detach from the
156
+ // global preset via the override helper so a single call resolves the preset
157
+ // and clears textStyleType once — see resolveGlobalPresetIntoStyle (BP-5420).
158
+ if (args.copyright_text_style) {
159
+ const updates: Partial<TextStyleDeclaration> = {};
47
160
 
48
- const links = args.social_links;
161
+ for (const [key, value] of Object.entries(args.copyright_text_style)) {
162
+ const normalized = normalizeStyleValue(key, value);
49
163
 
50
- // _replace_social_links: replace entire list (empty/absent social_links = clear all).
51
- // When replacing, all other social link mutations (remove, insert, reorder) are skipped —
52
- // they are superseded by the replacement and running them would cause duplicates.
53
- if (args._replace_social_links) {
54
- footer.socialLinks = (links ?? []).map((l) => ({
55
- id: generateItemId(),
56
- imageUrl: l.social_link_icon || '',
57
- url: normaliseSocialUrl(l.url || ''),
58
- imageTitle: '',
59
- width: 0,
60
- height: 0,
61
- imageLink: '',
62
- }));
63
- } else {
64
- // Targeted mutations — only run when NOT replacing the entire list.
65
- // BP-5603: id-based contract (item_id / move_before_item_id / _remove_social_link_ids).
66
- // Backfill ids on legacy links so they become referenceable after this call.
67
- ensureItemIds(footer.socialLinks);
68
-
69
- // Remove by id (order-independent — no index shifting needed).
70
- footer.socialLinks = removeItemsByIds(
71
- footer.socialLinks,
72
- args._remove_social_link_ids,
73
- );
74
-
75
- // Update existing links (item_id present) or insert new links (no item_id).
76
- if (links?.length) {
77
- footer.socialLinks = footer.socialLinks ?? [];
78
-
79
- for (const link of links) {
80
- if (link.item_id) {
81
- // Update existing link in place; reposition if move_before_item_id set.
82
- const existing = footer.socialLinks.find(
83
- (l) => l.id === link.item_id,
84
- );
85
-
86
- // Unknown id — skip rather than guess at a position.
87
- if (!existing) continue;
88
-
89
- if (link.social_link_icon !== undefined)
90
- existing.imageUrl = link.social_link_icon;
91
-
92
- if (link.url !== undefined)
93
- existing.url = normaliseSocialUrl(link.url);
94
-
95
- repositionItemByAnchor(
96
- footer.socialLinks,
97
- existing,
98
- link.move_before_item_id,
99
- );
100
- } else {
101
- // New link — assign a stable id and position via move_before_item_id.
102
- const newLink = {
103
- id: generateItemId(),
104
- imageUrl: link.social_link_icon || '',
105
- url: normaliseSocialUrl(link.url || ''),
106
- imageTitle: '',
107
- width: 0,
108
- height: 0,
109
- imageLink: '' as string | false,
110
- };
111
-
112
- repositionItemByAnchor(
113
- footer.socialLinks,
114
- newLink,
115
- link.move_before_item_id,
116
- );
117
- }
118
- }
164
+ if (normalized !== undefined)
165
+ (updates as Record<string, unknown>)[key] = normalized;
119
166
  }
167
+
168
+ if (Object.keys(updates).length > 0)
169
+ footer.copyrightStyle = applyDetachedStyleOverride(
170
+ footer.copyrightStyle,
171
+ updates,
172
+ textStyleOptions,
173
+ );
120
174
  }
121
175
  };
122
176
 
@@ -141,12 +195,6 @@ const applyViewportFooterChanges = (
141
195
  fill: overrides.icon_color,
142
196
  };
143
197
 
144
- if (overrides.copyright_text_color !== undefined)
145
- footer.copyrightStyle = {
146
- ...footer.copyrightStyle,
147
- color: overrides.copyright_text_color,
148
- };
149
-
150
198
  if (overrides.is_logo_visible !== undefined)
151
199
  footer.isLogoVisible = overrides.is_logo_visible;
152
200
 
@@ -198,13 +246,30 @@ export class FooterBuilder extends BaseMetadataBuilder<UpdateFooterArguments> {
198
246
  const args = this.request.payload ?? {};
199
247
  const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
200
248
 
201
- // Global fields (copyright_text, social links) always apply to both viewports.
249
+ // Global scalar/style fields (copyright text + font) apply to both
250
+ // viewports. These are idempotent assignments, safe to run per-viewport.
202
251
  if (model.pageFooterDesktop)
203
252
  applyGlobalFooterChanges(model.pageFooterDesktop, args, textStyleOptions);
204
253
 
205
254
  if (model.pageFooterMobile)
206
255
  applyGlobalFooterChanges(model.pageFooterMobile, args, textStyleOptions);
207
256
 
257
+ // Social links are a single global list. Derive the new list ONCE, then
258
+ // assign an INDEPENDENT copy to each viewport — never mutate a (possibly
259
+ // shared) viewport array in place. See computeSocialLinks.
260
+ if (hasSocialLinkMutation(args)) {
261
+ const current =
262
+ model.pageFooterDesktop?.socialLinks ??
263
+ model.pageFooterMobile?.socialLinks;
264
+ const updated = computeSocialLinks(current, args);
265
+
266
+ if (model.pageFooterDesktop)
267
+ model.pageFooterDesktop.socialLinks = updated.map((l) => ({ ...l }));
268
+
269
+ if (model.pageFooterMobile)
270
+ model.pageFooterMobile.socialLinks = updated.map((l) => ({ ...l }));
271
+ }
272
+
208
273
  // Viewport-specific styling via explicit sub-objects.
209
274
  if (args.desktop && model.pageFooterDesktop)
210
275
  applyViewportFooterChanges(model.pageFooterDesktop, args.desktop);
@@ -10,12 +10,6 @@ import type { BuilderResult } from '../../models';
10
10
  import { applyScalarFields, isValidUrl } from '../section-field-utils';
11
11
  import { BaseSectionBuilder } from './base-section-builder';
12
12
  import { validateImageGallery } from '../section-rules/image-gallery.rules';
13
- import {
14
- ensureItemIds,
15
- generateItemId,
16
- removeItemsByIds,
17
- repositionItemByAnchor,
18
- } from '../item-id-utils';
19
13
 
20
14
  const applyGalleryType = (
21
15
  content: ImageGalleryContent,
@@ -27,17 +21,11 @@ const applyGalleryType = (
27
21
  };
28
22
  };
29
23
 
30
- /**
31
- * Full rebuild: discard existing images and map the payload directly.
32
- * Used on create and when `_replace_items` is set. Each item gets a fresh id
33
- * (or keeps the caller-supplied `item_id` when provided).
34
- */
35
24
  const applyGalleryImages = (
36
25
  content: ImageGalleryContent,
37
26
  images: ImageGalleryItem[],
38
27
  ): void => {
39
28
  content.images = images.map((img) => ({
40
- id: img.item_id || generateItemId(),
41
29
  imageUrl: isValidUrl(img.image_url) ? img.image_url! : '',
42
30
  imageTitle: img.caption || '',
43
31
  width: 0,
@@ -47,53 +35,84 @@ const applyGalleryImages = (
47
35
  }));
48
36
  };
49
37
 
50
- /**
51
- * Id-based merge (BP-5603), mirroring testimonial-section-builder one level
52
- * deeper into `content.images`:
53
- * - `item_id` matches existing item → update in place; reposition if
54
- * `move_before_item_id` is set.
55
- * - no `item_id` → add new item, positioned by
56
- * `move_before_item_id`.
57
- * - `removeIds` → delete by id (order-independent).
58
- *
59
- * Existing items are id-backfilled first so legacy galleries become
60
- * referenceable as soon as the metadata builder touches them.
61
- */
62
38
  const mergeGalleryImages = (
63
39
  content: ImageGalleryContent,
64
40
  images: ImageGalleryItem[],
65
- removeIds: string[] | undefined,
41
+ replaceAll: boolean,
66
42
  ): void => {
67
- ensureItemIds(content.images);
68
- content.images = removeItemsByIds(content.images, removeIds);
43
+ const itemsToMerge = images.filter((img) => img.insert_at === undefined);
44
+
45
+ const updatedImages = itemsToMerge.map((img, index) => {
46
+ const existing = content.images?.[index];
47
+ const imageUrl = isValidUrl(img.image_url)
48
+ ? img.image_url!
49
+ : (existing?.imageUrl ?? '');
50
+
51
+ return {
52
+ ...(existing || {}),
53
+ imageUrl,
54
+ imageTitle: img.caption ?? existing?.imageTitle ?? '',
55
+ width: existing?.width ?? 0,
56
+ height: existing?.height ?? 0,
57
+ mediaType: existing?.mediaType ?? 'image',
58
+ imageLink: existing?.imageLink ?? '',
59
+ };
60
+ });
61
+
62
+ if (
63
+ !replaceAll &&
64
+ content.images &&
65
+ content.images.length > itemsToMerge.length
66
+ ) {
67
+ const extras = content.images.slice(itemsToMerge.length).map((img) => ({
68
+ imageUrl: img.imageUrl ?? '',
69
+ imageTitle: img.imageTitle ?? '',
70
+ width: img.width ?? 0,
71
+ height: img.height ?? 0,
72
+ mediaType: img.mediaType ?? ('image' as const),
73
+ imageLink: img.imageLink ?? '',
74
+ }));
75
+
76
+ updatedImages.push(...extras);
77
+ }
69
78
 
70
- for (const img of images) {
71
- if (img.item_id) {
72
- const existing = content.images.find((i) => i.id === img.item_id);
79
+ content.images = updatedImages;
80
+ };
73
81
 
74
- // Unknown id — skip rather than guess at a position.
75
- if (!existing) continue;
82
+ const insertGalleryImages = (
83
+ content: ImageGalleryContent,
84
+ images: ImageGalleryItem[],
85
+ ): void => {
86
+ const inserts = images.filter((img) => img.insert_at !== undefined);
76
87
 
77
- if (img.image_url !== undefined) {
78
- existing.imageUrl = isValidUrl(img.image_url) ? img.image_url! : '';
79
- }
88
+ if (!inserts.length) return;
80
89
 
81
- if (img.caption !== undefined) existing.imageTitle = img.caption;
82
-
83
- repositionItemByAnchor(content.images, existing, img.move_before_item_id);
84
- } else {
85
- const newItem = {
86
- id: generateItemId(),
87
- imageUrl: isValidUrl(img.image_url) ? img.image_url! : '',
88
- imageTitle: img.caption ?? '',
89
- width: 0,
90
- height: 0,
91
- mediaType: 'image' as const,
92
- imageLink: '',
93
- };
94
-
95
- repositionItemByAnchor(content.images, newItem, img.move_before_item_id);
96
- }
90
+ const sorted = [...inserts].sort(
91
+ (a, b) => (b.insert_at ?? 0) - (a.insert_at ?? 0),
92
+ );
93
+
94
+ for (const img of sorted) {
95
+ if (!isValidUrl(img.image_url)) continue;
96
+
97
+ if (content.images?.some((existing) => existing.imageUrl === img.image_url))
98
+ continue;
99
+
100
+ content.images = content.images ?? [];
101
+
102
+ const pos = Math.max(
103
+ 0,
104
+ Math.min(img.insert_at ?? 0, content.images.length),
105
+ );
106
+
107
+ content.images.splice(pos, 0, {
108
+ imageUrl: img.image_url!,
109
+ imageTitle: img.caption ?? '',
110
+ width: 0,
111
+ height: 0,
112
+ mediaType: 'image',
113
+ imageLink: '',
114
+ colorReplacements: [],
115
+ });
97
116
  }
98
117
  };
99
118
 
@@ -125,19 +144,26 @@ export class ImageGalleryBuilder extends BaseSectionBuilder<ImageGalleryContent>
125
144
  applyGalleryType(content, args.gallery_type);
126
145
  }
127
146
 
128
- if (args._replace_items && args.images && Array.isArray(args.images)) {
129
- // Full replacement: discard existing images and rebuild from the payload.
130
- applyGalleryImages(content, args.images);
131
- } else if (this.mode === 'create') {
132
- if (args.images && Array.isArray(args.images)) {
147
+ if (args.images && Array.isArray(args.images)) {
148
+ if (this.mode === 'create') {
133
149
  applyGalleryImages(content, args.images);
150
+ } else {
151
+ mergeGalleryImages(content, args.images, !!args._replace_items);
134
152
  }
135
- } else if (
136
- (args.images && Array.isArray(args.images)) ||
137
- args._remove_item_ids?.length
138
- ) {
139
- // Update: id-based add / edit / move / remove in a single pass.
140
- mergeGalleryImages(content, args.images ?? [], args._remove_item_ids);
153
+ }
154
+
155
+ if (args._remove_item_indices?.length && content.images) {
156
+ const sorted = [...args._remove_item_indices].sort((a, b) => b - a);
157
+
158
+ for (const idx of sorted) {
159
+ if (idx >= 0 && idx < content.images.length) {
160
+ content.images.splice(idx, 1);
161
+ }
162
+ }
163
+ }
164
+
165
+ if (args.images && Array.isArray(args.images) && this.mode === 'update') {
166
+ insertGalleryImages(content, args.images);
141
167
  }
142
168
 
143
169
  return { request: this.request, model };