@designcrowd/library.brand-page 6.2.0 → 6.2.2-live-preview-1

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 (186) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-VQCQvlMg.js → CreatedOnBrandCrowd-de-de-Cn0M-eZ1.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DSf3BjCG.js → CreatedOnBrandCrowd-en-us-DRLMSDZr.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-DGcdM9Ec.js → CreatedOnBrandCrowd-es-es-BglTu73U.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-C9g1fc39.js → CreatedOnBrandCrowd-fr-ca-Bj6YZ_el.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-C9g1fc39.js → CreatedOnBrandCrowd-fr-fr-Bj6YZ_el.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DSXr7Bxl.js → CreatedOnBrandCrowd-pt-br-DEoOmQ1F.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DSXr7Bxl.js → CreatedOnBrandCrowd-pt-pt-DEoOmQ1F.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BPdCL6wS.js → CreatedOnDcom-de-de-BZ7gTt4Z.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CLkSTQRu.js → CreatedOnDcom-en-us-CD6Km5sH.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CRknMAGv.js → CreatedOnDcom-es-es-CNpZHvEl.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-ClAY_dHI.js → CreatedOnDcom-fr-ca-URS-ydJ1.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DQtv9rR-.js → CreatedOnDcom-fr-fr-D2AVeA3H.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-BbIxvmxv.js → CreatedOnDcom-pt-br-C32frnFs.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BOfOesBj.js → CreatedOnDcom-pt-pt-TDYGjRXS.js} +1 -1
  15. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +16 -2
  16. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +17 -0
  17. package/lib/src/brand-page/components/page/Page.mixin.d.ts +2 -1
  18. package/lib/src/brand-page/components/page/Page.mixin.js +12 -7
  19. package/lib/src/brand-page/components/page-header/HeaderLayout.stories.d.ts +1 -0
  20. package/lib/src/brand-page/components/page-header/HeaderLayout.stories.js +9 -0
  21. package/lib/src/brand-page/components/page-header/PageHeader.mixin.d.ts +3 -1
  22. package/lib/src/brand-page/components/page-header/PageHeader.mixin.js +10 -4
  23. package/lib/src/brand-page/constants/sections/header-display.constants.d.ts +3 -0
  24. package/lib/src/brand-page/constants/sections/header-display.constants.js +15 -0
  25. package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
  26. package/lib/src/brand-page/models/brand-page-context.model.js +0 -12
  27. package/lib/src/brand-page/models/index.d.ts +12 -0
  28. package/lib/src/brand-page/models/index.js +4 -0
  29. package/lib/src/brand-page/utils/context.util.d.ts +1 -0
  30. package/lib/src/brand-page/utils/context.util.js +9 -0
  31. package/lib/src/brand-page/utils/route.util.d.ts +1 -0
  32. package/lib/src/brand-page/utils/route.util.js +9 -0
  33. package/lib/src/brand-page/utils/view-model.util.js +53 -1
  34. package/lib/src/brand-page/view-models.d.ts +3 -1
  35. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +0 -1
  36. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.js +0 -9
  37. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +9 -44
  38. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +8 -43
  39. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -14
  40. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -42
  41. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -42
  42. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -42
  43. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -42
  44. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -42
  45. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -42
  46. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +3 -0
  47. package/lib/src/brand-page-maker/composables/useEventTracker.js +10 -0
  48. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +1626 -0
  49. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -42
  50. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +2 -4
  51. package/lib/src/brand-page-maker/validators/section-button.validator.d.ts +5 -2
  52. package/lib/src/brand-page-maker/validators/section-button.validator.js +11 -15
  53. package/lib/src/{bundled-translations-B2q5GWTQ.js → bundled-translations-BYUfWBT3.js} +17 -17
  54. package/lib/src/{bundled-translations.de-DE-FhH2H_rd.js → bundled-translations.de-DE-MmzUu1tt.js} +21 -21
  55. package/lib/src/{bundled-translations.es-ES-_ZExxMi7.js → bundled-translations.es-ES-D-tG33XL.js} +5 -5
  56. package/lib/src/{bundled-translations.fr-CA-Tg-ODIiC.js → bundled-translations.fr-CA-CNc1H1h3.js} +1 -1
  57. package/lib/src/{bundled-translations.fr-FR-C0sU51Mz.js → bundled-translations.fr-FR-DX0-yepT.js} +9 -9
  58. package/lib/src/{bundled-translations.pt-BR-MYFIhA4u.js → bundled-translations.pt-BR-ih1-LRgy.js} +9 -9
  59. package/lib/src/{bundled-translations.pt-PT-DeUBSzCB.js → bundled-translations.pt-PT-Dq2CmD1p.js} +22 -22
  60. package/lib/src/bundles/bundled-translations.de-DE.json +9 -2
  61. package/lib/src/bundles/bundled-translations.es-ES.json +9 -2
  62. package/lib/src/bundles/bundled-translations.fr-CA.json +9 -2
  63. package/lib/src/bundles/bundled-translations.fr-FR.json +9 -2
  64. package/lib/src/bundles/bundled-translations.json +9 -2
  65. package/lib/src/bundles/bundled-translations.pt-BR.json +9 -2
  66. package/lib/src/bundles/bundled-translations.pt-PT.json +9 -2
  67. package/lib/src/composables/useTranslate.d.ts +1 -1
  68. package/lib/src/composables/useTranslate.js +1 -1
  69. package/lib/src/css/library.brand-page-brandCrowd.min.css +577 -139
  70. package/lib/src/css/library.brand-page-brandPage.min.css +577 -139
  71. package/lib/src/css/library.brand-page-designCom.min.css +577 -139
  72. package/lib/src/css/library.brand-page-preview.min.css +577 -139
  73. package/lib/src/index.mjs +2 -2
  74. package/lib/src/{lib-BMVF4uNy.js → lib-Dm9AuOJL.js} +22487 -21900
  75. package/lib/src/metadata-builder/builders/item-id-utils.d.ts +2 -0
  76. package/lib/src/metadata-builder/builders/item-id-utils.js +8 -2
  77. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +10 -2
  78. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +7 -1
  79. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +1 -0
  80. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +6 -1
  81. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +6 -43
  82. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +14 -2
  83. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.js +14 -0
  84. package/lib/src/shared/ecommerce-settings/util/refreshDuplicatedMetadata.d.ts +9 -1
  85. package/lib/src/shared/ecommerce-settings/util/refreshDuplicatedMetadata.js +31 -9
  86. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +1 -0
  87. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +6 -43
  88. package/lib/src/shared/page-navigation/store/page-navigation-store.d.ts +3 -1
  89. package/lib/src/shared/page-navigation/store/page-navigation-store.js +34 -9
  90. package/lib/src/shared/page-settings/components/delete-page-modal/DeletePageModal.mixin.d.ts +1 -1
  91. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +9 -2
  92. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +200 -44
  93. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.js +12 -35
  94. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +190 -44
  95. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +34 -2
  96. package/lib/src/shared/page-settings/duplicate-page.util.d.ts +4 -0
  97. package/lib/src/shared/page-settings/duplicate-page.util.js +82 -0
  98. package/lib/src/shared/page-settings/models.d.ts +1 -0
  99. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +7 -2
  100. package/lib/src/shared/page-settings/store/page-settings-store.js +90 -7
  101. package/lib/src/shared/page-settings/utils.d.ts +3 -0
  102. package/lib/src/shared/page-settings/utils.js +6 -0
  103. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +1 -56
  104. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +0 -42
  105. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
  106. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +4 -42
  107. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +1 -0
  108. package/lib/src/tracker.mjs +1 -1
  109. package/lib/src/{useEventTracker-C5Ql5p7u.js → useEventTracker-DwPTmzpa.js} +13 -3
  110. package/package.json +2 -2
  111. package/src/brand-page/components/navigation/hamburger/HamburgerNavigation.vue +1 -0
  112. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +18 -1
  113. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue +73 -3
  114. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue.test.ts +181 -0
  115. package/src/brand-page/components/page/Page.mixin.ts +21 -11
  116. package/src/brand-page/components/page/Page.vue +2 -0
  117. package/src/brand-page/components/page-header/HeaderLayout.stories.ts +10 -0
  118. package/src/brand-page/components/page-header/HeaderLayout.vue +415 -71
  119. package/src/brand-page/components/page-header/PageHeader.mixin.ts +14 -10
  120. package/src/brand-page/components/page-header/PageHeader.vue +16 -1
  121. package/src/brand-page/components/page-header/PageHeader.vue.test.ts +339 -0
  122. package/src/brand-page/constants/sections/header-display.constants.test.ts +44 -0
  123. package/src/brand-page/constants/sections/header-display.constants.ts +35 -0
  124. package/src/brand-page/models/brand-page-context.model.ts +0 -23
  125. package/src/brand-page/models/header-button.model.test.ts +85 -0
  126. package/src/brand-page/models/index.ts +19 -0
  127. package/src/brand-page/utils/context.util.ts +15 -0
  128. package/src/brand-page/utils/route.util.ts +13 -0
  129. package/src/brand-page/utils/view-model.util.test.ts +151 -1
  130. package/src/brand-page/utils/view-model.util.ts +73 -1
  131. package/src/brand-page/view-models.ts +3 -0
  132. package/src/brand-page-maker/components/action-bar/ActionBar.mixin.ts +0 -10
  133. package/src/brand-page-maker/components/action-bar/ActionBarNavigation.test.ts +8 -49
  134. package/src/brand-page-maker/components/action-bar/ActionBarNavigation.vue +1 -1
  135. package/src/brand-page-maker/composables/useEventTracker.ts +13 -0
  136. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +2 -4
  137. package/src/brand-page-maker/validators/section-button.validator.ts +23 -19
  138. package/src/bundles/bundled-translations.de-DE.json +9 -2
  139. package/src/bundles/bundled-translations.es-ES.json +9 -2
  140. package/src/bundles/bundled-translations.fr-CA.json +9 -2
  141. package/src/bundles/bundled-translations.fr-FR.json +9 -2
  142. package/src/bundles/bundled-translations.json +9 -2
  143. package/src/bundles/bundled-translations.pt-BR.json +9 -2
  144. package/src/bundles/bundled-translations.pt-PT.json +9 -2
  145. package/src/composables/useTranslate.ts +2 -1
  146. package/src/metadata-builder/builders/item-id-utils.ts +9 -2
  147. package/src/shared/content-settings/components/text-field/TextField.mixin.ts +15 -0
  148. package/src/shared/content-settings/components/url-field/UrlField.vue +1 -0
  149. package/src/shared/ecommerce-settings/components/product-config-field/ProductConfigOption.vue +0 -2
  150. package/src/shared/ecommerce-settings/util/refreshDuplicatedMetadata.ts +32 -10
  151. package/src/shared/page-navigation/store/page-navigation-store.ts +57 -13
  152. package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.button-section.test.ts +131 -0
  153. package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.vue +65 -10
  154. package/src/shared/page-settings/components/page-settings/NestedDraggable.vue +3 -0
  155. package/src/shared/page-settings/components/page-settings/PageElement.vue +2 -0
  156. package/src/shared/page-settings/components/page-settings/PageSettingMenu.test.ts +105 -0
  157. package/src/shared/page-settings/components/page-settings/PageSettingMenu.vue +16 -0
  158. package/src/shared/page-settings/components/page-settings/PageSettings.duplicate.test.ts +108 -0
  159. package/src/shared/page-settings/components/page-settings/PageSettings.mixin.ts +22 -50
  160. package/src/shared/page-settings/components/page-settings/PageSettings.vue +1 -0
  161. package/src/shared/page-settings/components/page-settings/i18n/page-settings.de-DE.json +3 -1
  162. package/src/shared/page-settings/components/page-settings/i18n/page-settings.es-ES.json +3 -1
  163. package/src/shared/page-settings/components/page-settings/i18n/page-settings.fr-CA.json +3 -1
  164. package/src/shared/page-settings/components/page-settings/i18n/page-settings.fr-FR.json +3 -1
  165. package/src/shared/page-settings/components/page-settings/i18n/page-settings.json +3 -1
  166. package/src/shared/page-settings/components/page-settings/i18n/page-settings.pt-BR.json +3 -1
  167. package/src/shared/page-settings/components/page-settings/i18n/page-settings.pt-PT.json +3 -1
  168. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.test.ts +305 -0
  169. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.vue +265 -0
  170. package/src/shared/page-settings/components/page-settings-section-styles/HeaderDisplayStyle.test.ts +354 -0
  171. package/src/shared/page-settings/components/page-settings-section-styles/HeaderDisplayStyle.vue +48 -9
  172. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.header-button.test.ts +114 -0
  173. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +38 -1
  174. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.de-DE.json +6 -1
  175. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.es-ES.json +6 -1
  176. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.fr-CA.json +6 -1
  177. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.fr-FR.json +6 -1
  178. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.json +6 -1
  179. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.pt-BR.json +6 -1
  180. package/src/shared/page-settings/components/page-settings-section-styles/i18n/page-settings-section.pt-PT.json +6 -1
  181. package/src/shared/page-settings/duplicate-page.util.test.ts +382 -0
  182. package/src/shared/page-settings/duplicate-page.util.ts +124 -0
  183. package/src/shared/page-settings/models.ts +1 -0
  184. package/src/shared/page-settings/store/page-settings-store.test.ts +441 -1
  185. package/src/shared/page-settings/store/page-settings-store.ts +147 -11
  186. package/src/shared/page-settings/utils.ts +10 -0
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "275",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "251",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "250",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-BMVF4uNy.js";
2
+ import { _ as t } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-BMVF4uNy.js";
2
+ import { _ as e } from "./lib-Dm9AuOJL.js";
3
3
  const M = {}, Z = {
4
4
  width: "242",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-BMVF4uNy.js";
2
+ import { _ as e } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, M = {
4
4
  width: "231",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-BMVF4uNy.js";
2
+ import { _ as e } from "./lib-Dm9AuOJL.js";
3
3
  const M = {}, Z = {
4
4
  width: "230",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-BMVF4uNy.js";
2
+ import { _ as e } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-BMVF4uNy.js";
2
+ import { _ as e } from "./lib-Dm9AuOJL.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-BMVF4uNy.js";
2
+ import { _ as M } from "./lib-Dm9AuOJL.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-BMVF4uNy.js";
2
+ import { _ as M } from "./lib-Dm9AuOJL.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,6 +1,6 @@
1
1
  import type { PropType } from 'vue';
2
2
  import type { BrandPageContext, NavigationDesktop, NavigationMobile } from '../../../models';
3
- import type { NavItemViewModel } from '../../../view-models';
3
+ import type { ButtonViewModel, NavItemViewModel } from '../../../view-models';
4
4
  declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
5
5
  context: {
6
6
  type: PropType<BrandPageContext>;
@@ -18,6 +18,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
18
18
  type: PropType<NavigationDesktop | NavigationMobile>;
19
19
  required: true;
20
20
  };
21
+ headerButtonViewModel: {
22
+ type: PropType<ButtonViewModel>;
23
+ required: false;
24
+ default: undefined;
25
+ };
21
26
  }>, {}, {
22
27
  expandedItems: Record<string, boolean>;
23
28
  }, {
@@ -27,12 +32,14 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
27
32
  selectedButtonStyle(): BrandPageCssStyle;
28
33
  defaultWrapperStyle(): BrandPageCssStyle;
29
34
  selectedWrapperStyle(): BrandPageCssStyle;
35
+ showHeaderButton(): boolean;
30
36
  routes(): any[];
31
37
  }, {
32
38
  filterHiddenNavItems(navItems: NavItemViewModel[]): NavItemViewModel[];
33
39
  isCurrentPage(navItem: NavItemViewModel): boolean;
34
40
  getSubNavItemStyle(navItem: NavItemViewModel): BrandPageCssStyle;
35
41
  closeSideMenu(): void;
42
+ onSideMenuCtaClick(event: MouseEvent): void;
36
43
  toggleExpanded(pageId: string): void;
37
44
  isExpanded(pageId: string): boolean;
38
45
  expandSubPageIfCurrentPage(): void;
@@ -53,7 +60,14 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
53
60
  type: PropType<NavigationDesktop | NavigationMobile>;
54
61
  required: true;
55
62
  };
63
+ headerButtonViewModel: {
64
+ type: PropType<ButtonViewModel>;
65
+ required: false;
66
+ default: undefined;
67
+ };
56
68
  }>> & Readonly<{
57
69
  "onClose-side-menu"?: ((...args: any[]) => any) | undefined;
58
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
70
+ }>, {
71
+ headerButtonViewModel: ButtonViewModel;
72
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
59
73
  export default _default;
@@ -1,5 +1,6 @@
1
1
  import { defineComponent } from 'vue';
2
2
  import { resolveSubNavItemBackgroundColor } from '../../../models';
3
+ import { guardPreviewClick } from '../../../utils/context.util';
3
4
  export default defineComponent({
4
5
  props: {
5
6
  context: {
@@ -18,6 +19,13 @@ export default defineComponent({
18
19
  type: Object,
19
20
  required: true,
20
21
  },
22
+ // Provided only when the header row does not render the CTA (the caller
23
+ // decides via headerRowRendersCta) — absent means the side menu shows none.
24
+ headerButtonViewModel: {
25
+ type: Object,
26
+ required: false,
27
+ default: undefined,
28
+ },
21
29
  },
22
30
  emits: ['close-side-menu'],
23
31
  data() {
@@ -50,6 +58,9 @@ export default defineComponent({
50
58
  const { fontSize: _fontSize, lineHeight: _lineHeight, letterSpacing: _letterSpacing, ...rest } = this.selectedButtonStyle;
51
59
  return rest;
52
60
  },
61
+ showHeaderButton() {
62
+ return Boolean(this.headerButtonViewModel);
63
+ },
53
64
  routes() {
54
65
  return this.visibleNavItems.map((navItem, _i) => {
55
66
  return {
@@ -85,6 +96,12 @@ export default defineComponent({
85
96
  closeSideMenu() {
86
97
  this.$emit('close-side-menu');
87
98
  },
99
+ // Preview: inert; published: follow the link and close the side menu behind it.
100
+ onSideMenuCtaClick(event) {
101
+ if (!guardPreviewClick(event, this.context)) {
102
+ this.closeSideMenu();
103
+ }
104
+ },
88
105
  toggleExpanded(pageId) {
89
106
  const isCurrentlyExpanded = this.expandedItems[pageId];
90
107
  this.expandedItems = {};
@@ -1,5 +1,5 @@
1
1
  import type { PropType } from 'vue';
2
- import type { BrandPageViewModel, ContentViewModel, PageViewModel } from '@brand-page/view-models';
2
+ import type { BrandPageViewModel, ButtonViewModel, ContentViewModel, PageViewModel } from '@brand-page/view-models';
3
3
  import type { BackgroundShape, BrandPageContext, ViewportsType } from '@brand-page/models';
4
4
  declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
5
5
  context: {
@@ -81,6 +81,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
81
81
  headerViewModelDesktop(): any;
82
82
  isNavigationEmbeddedInLogoMobile(): boolean;
83
83
  isNavigationEmbeddedInLogoDesktop(): boolean;
84
+ sideMenuHeaderButtonViewModel(): ButtonViewModel | undefined;
84
85
  shouldShowNavigation(): boolean;
85
86
  showNavigationAfterLogoMobile(): boolean;
86
87
  showNavigationAfterLogoDesktop(): boolean;
@@ -1,7 +1,7 @@
1
1
  import { defineComponent } from 'vue';
2
- import { DEFAULT_FONT_FAMILY_KEY, FALLBACK_FONT_FAMILIES, FONT_FAMILY_CONFIGS, } from '../../constants';
2
+ import { DEFAULT_FONT_FAMILY_KEY, FALLBACK_FONT_FAMILIES, FONT_FAMILY_CONFIGS, headerRowRendersCta, } from '../../constants';
3
3
  import { getSlugFromContext, getPageHeadingText, buildPaletteRootCss, buildPaletteScopedCss, PAGE_SCOPE_ID_ATTRIBUTE, resolveColorReference, } from '@brand-page/utils';
4
- import { findNavItemByRelativePath } from '@brand-page/utils/route.util';
4
+ import { findNavItemByRelativePath, hasVisibleNavigation, } from '@brand-page/utils/route.util';
5
5
  import { BRAND_PAGE_TYPES } from '@brand-page/models';
6
6
  import { hasProfileContent as checkHasProfileContent } from '@brand-page/utils/vcard.util';
7
7
  // Per-instance id for a `Page` instance. Deliberately generic — any per-instance
@@ -276,12 +276,17 @@ export default defineComponent({
276
276
  this.contents[0]?.type === 'logo' &&
277
277
  this.viewModel.pages.length > 1);
278
278
  },
279
+ // The button shows in the header row OR in the side menu, never both. This gives it to the side menu when the header doesn't show it; undefined = no button in the menu.
280
+ sideMenuHeaderButtonViewModel() {
281
+ const header = this.viewModel.headerViewModelMobile;
282
+ if (!header.headerButtonViewModel ||
283
+ headerRowRendersCta(header.displayStyle, this.shouldShowNavigation)) {
284
+ return undefined;
285
+ }
286
+ return header.headerButtonViewModel;
287
+ },
279
288
  shouldShowNavigation() {
280
- // Show navigation if more than 1 non-hidden page exists, or if there's 1 page with non-hidden subpages
281
- const visibleNavItems = this.context.nav.navItems.filter((item) => !item.isHidden);
282
- return (visibleNavItems.length > 1 ||
283
- (visibleNavItems.length === 1 &&
284
- visibleNavItems[0].nestedNavItems.some((item) => !item.isHidden)));
289
+ return hasVisibleNavigation(this.context.nav.navItems);
285
290
  },
286
291
  showNavigationAfterLogoMobile() {
287
292
  return (!this.context.isBrandSite &&
@@ -3,3 +3,4 @@ import HeaderLayout from './HeaderLayout.vue';
3
3
  declare const meta: Meta<typeof HeaderLayout>;
4
4
  export default meta;
5
5
  export declare const Sample: StoryFn;
6
+ export declare const WithHeaderButton: StoryFn;
@@ -36,6 +36,7 @@ const Template = (args) => ({
36
36
  nav-id="nav-1"
37
37
  :show-nav="args.showNav"
38
38
  :display-style="args.displayStyle"
39
+ :has-cta="args.hasCta"
39
40
  logo-width="100px"
40
41
  >
41
42
  <template v-slot:logo>
@@ -44,6 +45,9 @@ const Template = (args) => ({
44
45
  <template v-slot:nav>
45
46
  <div style="border: 1px solid red; display: inline-block;">Nav | Nav | Nav | Nav | Nav | Nav | Nav | Nav</div>
46
47
  </template>
48
+ <template v-slot:cta>
49
+ <div style="border: 1px solid green; display: inline-block; padding: 8px 16px;">Contact Us</div>
50
+ </template>
47
51
  </HeaderLayout>
48
52
  </div>
49
53
  `,
@@ -52,3 +56,8 @@ export const Sample = Template.bind({});
52
56
  Sample.args = {
53
57
  displayStyle: HEADER_DISPLAY.DESKTOP_TAB_5,
54
58
  };
59
+ export const WithHeaderButton = Template.bind({});
60
+ WithHeaderButton.args = {
61
+ displayStyle: HEADER_DISPLAY.DESKTOP_TAB_1,
62
+ hasCta: true,
63
+ };
@@ -1,6 +1,6 @@
1
1
  import type { PropType } from 'vue';
2
2
  import type { BrandPageContext } from '@brand-page/models';
3
- import type { PageHeaderViewModel } from '@brand-page/view-models';
3
+ import type { ButtonViewModel, PageHeaderViewModel } from '@brand-page/view-models';
4
4
  declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
5
5
  navId: {
6
6
  type: StringConstructor;
@@ -23,9 +23,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
23
23
  LOGO_SLIDER_DESKTOP_MAX: number;
24
24
  }, {
25
25
  containerCss(): BrandPageCssStyle;
26
+ headerButtonViewModel(): ButtonViewModel | undefined;
26
27
  showNav(): boolean;
27
28
  }, {
28
29
  onHeaderContainerClick(): void;
30
+ onHeaderCtaClick(event: MouseEvent): void;
29
31
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "header-container-click"[], "header-container-click", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
30
32
  navId: {
31
33
  type: StringConstructor;
@@ -1,5 +1,7 @@
1
1
  import { defineComponent } from 'vue';
2
2
  import { LOGO_SLIDER_DESKTOP_MAX } from '../../constants';
3
+ import { hasVisibleNavigation } from '../../utils/route.util';
4
+ import { guardPreviewClick } from '../../utils/context.util';
3
5
  export default defineComponent({
4
6
  props: {
5
7
  navId: {
@@ -33,11 +35,11 @@ export default defineComponent({
33
35
  padding: '1.5rem 0', // var(--page-padding) 0
34
36
  };
35
37
  },
38
+ headerButtonViewModel() {
39
+ return this.viewModel.headerButtonViewModel;
40
+ },
36
41
  showNav() {
37
- const visibleNavItems = this.context.nav.navItems.filter((item) => !item.isHidden);
38
- return (visibleNavItems.length > 1 ||
39
- (visibleNavItems.length === 1 &&
40
- visibleNavItems[0].nestedNavItems.some((item) => !item.isHidden)));
42
+ return hasVisibleNavigation(this.context.nav.navItems);
41
43
  },
42
44
  },
43
45
  emits: ['header-container-click'],
@@ -45,5 +47,9 @@ export default defineComponent({
45
47
  onHeaderContainerClick() {
46
48
  this.$emit('header-container-click');
47
49
  },
50
+ // Preview only: deliberately inert — no link-follow, no Header Settings open.
51
+ onHeaderCtaClick(event) {
52
+ guardPreviewClick(event, this.context);
53
+ },
48
54
  },
49
55
  });
@@ -42,6 +42,9 @@ interface HeaderDisplayStyleConfig {
42
42
  supportLogo: boolean;
43
43
  supportedNavTypes: string[];
44
44
  option: ButtonGroupOption;
45
+ withButtonIconName?: string;
45
46
  }
46
47
  export declare const HEADER_DISPLAY_STYLE_CONFIGS: HeaderDisplayStyleConfig[];
48
+ /** True when the header row shows the button; mobile hamburger styles put it in the side menu instead (unless the nav is hidden — then there is no side menu). */
49
+ export declare const headerRowRendersCta: (displayStyle: string, showNav: boolean) => boolean;
47
50
  export {};
@@ -48,6 +48,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
48
48
  dataAttribute: HEADER_DISPLAY.DESKTOP_TAB_1,
49
49
  isSelected: false,
50
50
  },
51
+ withButtonIconName: 'header-desktop-nav-style-tab-display-style-with-button-1',
51
52
  },
52
53
  {
53
54
  viewMode: 'desktop',
@@ -61,6 +62,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
61
62
  dataAttribute: HEADER_DISPLAY.DESKTOP_TAB_2,
62
63
  isSelected: false,
63
64
  },
65
+ withButtonIconName: 'header-desktop-nav-style-tab-display-style-with-button-2',
64
66
  },
65
67
  {
66
68
  viewMode: 'desktop',
@@ -74,6 +76,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
74
76
  dataAttribute: HEADER_DISPLAY.DESKTOP_TAB_3,
75
77
  isSelected: false,
76
78
  },
79
+ withButtonIconName: 'header-desktop-nav-style-tab-display-style-with-button-3',
77
80
  },
78
81
  {
79
82
  viewMode: 'desktop',
@@ -87,6 +90,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
87
90
  dataAttribute: HEADER_DISPLAY.DESKTOP_TAB_4,
88
91
  isSelected: false,
89
92
  },
93
+ withButtonIconName: 'header-desktop-nav-style-tab-display-style-with-button-4',
90
94
  },
91
95
  {
92
96
  viewMode: 'desktop',
@@ -100,6 +104,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
100
104
  dataAttribute: HEADER_DISPLAY.DESKTOP_TAB_5,
101
105
  isSelected: false,
102
106
  },
107
+ withButtonIconName: 'header-desktop-nav-style-tab-display-style-with-button-5',
103
108
  },
104
109
  {
105
110
  viewMode: 'desktop',
@@ -113,6 +118,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
113
118
  dataAttribute: HEADER_DISPLAY.DESKTOP_TAB_6,
114
119
  isSelected: false,
115
120
  },
121
+ withButtonIconName: 'header-desktop-nav-style-tab-display-style-with-button-6',
116
122
  },
117
123
  // desktop - tab with no logo
118
124
  {
@@ -172,6 +178,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
172
178
  dataAttribute: HEADER_DISPLAY.DESKTOP_HAMBURGER_1,
173
179
  isSelected: false,
174
180
  },
181
+ withButtonIconName: 'header-desktop-nav-style-hamburger-display-style-with-button-1',
175
182
  },
176
183
  {
177
184
  viewMode: 'desktop',
@@ -190,6 +197,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
190
197
  dataAttribute: HEADER_DISPLAY.DESKTOP_HAMBURGER_2,
191
198
  isSelected: false,
192
199
  },
200
+ withButtonIconName: 'header-desktop-nav-style-hamburger-display-style-with-button-2',
193
201
  },
194
202
  // desktop - hamburger no logo
195
203
  {
@@ -259,6 +267,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
259
267
  dataAttribute: HEADER_DISPLAY.MOBILE_TAB_1,
260
268
  isSelected: false,
261
269
  },
270
+ withButtonIconName: 'header-mobile-nav-style-tab-display-style-with-button-1',
262
271
  },
263
272
  {
264
273
  viewMode: 'mobile',
@@ -272,6 +281,7 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
272
281
  dataAttribute: HEADER_DISPLAY.MOBILE_TAB_2,
273
282
  isSelected: false,
274
283
  },
284
+ withButtonIconName: 'header-mobile-nav-style-tab-display-style-with-button-2',
275
285
  },
276
286
  // mobile - tab with no logo
277
287
  {
@@ -416,3 +426,8 @@ export const HEADER_DISPLAY_STYLE_CONFIGS = [
416
426
  },
417
427
  },
418
428
  ];
429
+ /** True when the header row shows the button; mobile hamburger styles put it in the side menu instead (unless the nav is hidden — then there is no side menu). */
430
+ export const headerRowRendersCta = (displayStyle, showNav) => !showNav ||
431
+ !HEADER_DISPLAY_STYLE_CONFIGS.some((config) => config.option.value === displayStyle &&
432
+ config.viewMode === 'mobile' &&
433
+ config.navType === 'hamburger');
@@ -36,8 +36,6 @@ export interface AbTestResult {
36
36
  }
37
37
  export interface AbTest {
38
38
  bp_3926_freemium_watermark?: AbTestResult;
39
- bp_5873_live_preview_prepurchase?: AbTestResult;
40
- bp_5873_live_preview_postpurchase?: AbTestResult;
41
39
  }
42
40
  export declare const MEDIA_SIZES: {
43
41
  readonly size1x: "size1x";
@@ -24,11 +24,6 @@ export const AB_TEST_FLAG = {
24
24
  };
25
25
  const AB_TEST_KEYS = {
26
26
  BP_3926_FREEMIUM_WATERMARK: 'bc-bp-3926-freemium-cta-in-website-editor',
27
- // Two separate live-preview experiments — bc-net sends only the one for the
28
- // current purchase state, and a user's value on each side is independent
29
- // (BP-5873). Keys must match `CampaignNames.LivePreview*Test` in bc-net.
30
- BP_5873_LIVE_PREVIEW_PREPURCHASE: 'bc-bp-5873-live-preview-prepurchase',
31
- BP_5873_LIVE_PREVIEW_POSTPURCHASE: 'bc-bp-5873-live-preview-postpurchase',
32
27
  };
33
28
  export const MEDIA_SIZES = {
34
29
  size1x: 'size1x',
@@ -50,12 +45,5 @@ export const getAbTestResults = (abtestKeyValues) => {
50
45
  if (abtestKeyValues[AB_TEST_KEYS.BP_3926_FREEMIUM_WATERMARK]) {
51
46
  abTests.bp_3926_freemium_watermark = getValueType(AB_TEST_KEYS.BP_3926_FREEMIUM_WATERMARK, abtestKeyValues[AB_TEST_KEYS.BP_3926_FREEMIUM_WATERMARK]);
52
47
  }
53
- // AB Test for BP-5873 - Live preview (pre- and post-purchase run separately)
54
- if (abtestKeyValues[AB_TEST_KEYS.BP_5873_LIVE_PREVIEW_PREPURCHASE]) {
55
- abTests.bp_5873_live_preview_prepurchase = getValueType(AB_TEST_KEYS.BP_5873_LIVE_PREVIEW_PREPURCHASE, abtestKeyValues[AB_TEST_KEYS.BP_5873_LIVE_PREVIEW_PREPURCHASE]);
56
- }
57
- if (abtestKeyValues[AB_TEST_KEYS.BP_5873_LIVE_PREVIEW_POSTPURCHASE]) {
58
- abTests.bp_5873_live_preview_postpurchase = getValueType(AB_TEST_KEYS.BP_5873_LIVE_PREVIEW_POSTPURCHASE, abtestKeyValues[AB_TEST_KEYS.BP_5873_LIVE_PREVIEW_POSTPURCHASE]);
59
- }
60
48
  return abTests;
61
49
  };
@@ -501,6 +501,16 @@ export declare class NavModel {
501
501
  routes: NavRoute[];
502
502
  constructor(options?: Partial<NavModel>);
503
503
  }
504
+ export interface HeaderButton {
505
+ isVisible: boolean;
506
+ text: string;
507
+ buttonLinkType: ButtonLinkType;
508
+ url?: string;
509
+ buttonPageId?: string;
510
+ buttonTextStyle?: TextStyleDeclaration;
511
+ fillColor?: string;
512
+ borderColor?: string;
513
+ }
504
514
  type AbstractPageHeaderStylesType = Partial<AbstractPageHeaderStyles>;
505
515
  export declare abstract class AbstractPageHeaderStyles {
506
516
  displayStyle: HeaderDisplayStyle;
@@ -525,6 +535,8 @@ export declare abstract class AbstractPageHeaderStyles {
525
535
  backgroundStyle: BackgroundColorStyle;
526
536
  style: BrandPageCssStyle;
527
537
  viewport: ViewportsType;
538
+ /** Missing = no button. `declare` keeps it off saved data so old migrations still see the same shape. */
539
+ headerButton?: HeaderButton;
528
540
  protected constructor(options?: AbstractPageHeaderStylesType);
529
541
  }
530
542
  export declare class PageHeaderDesktop extends AbstractPageHeaderStyles {
@@ -257,6 +257,10 @@ export class AbstractPageHeaderStyles {
257
257
  ...(options.backgroundStyle || {}),
258
258
  backgroundOpacity: options.backgroundStyle?.backgroundOpacity ?? 100,
259
259
  };
260
+ // Only set when given — a missing button must stay missing for old migrations.
261
+ if (options.headerButton) {
262
+ this.headerButton = options.headerButton;
263
+ }
260
264
  }
261
265
  }
262
266
  export class PageHeaderDesktop extends AbstractPageHeaderStyles {
@@ -8,3 +8,4 @@ export declare const getSlugFromContext: (context: BrandPageContext) => string;
8
8
  * placeholders) must keep reading `context.isPreview` directly.
9
9
  */
10
10
  export declare const isPreviewMode: (context: BrandPageContext) => boolean;
11
+ export declare const guardPreviewClick: (event: MouseEvent, context: BrandPageContext) => boolean;
@@ -12,3 +12,12 @@ export const getSlugFromContext = (context) => {
12
12
  * placeholders) must keep reading `context.isPreview` directly.
13
13
  */
14
14
  export const isPreviewMode = (context) => !!(context.isPreview || context.isLivePreview);
15
+ // Blocks a click in the maker preview (no link-follow, no bubbling); true when it fired.
16
+ export const guardPreviewClick = (event, context) => {
17
+ if (!context.isPreview) {
18
+ return false;
19
+ }
20
+ event.preventDefault();
21
+ event.stopPropagation();
22
+ return true;
23
+ };
@@ -33,3 +33,4 @@ export declare const toRouteLocation: (navItem?: NavItemViewModel) => {
33
33
  };
34
34
  export declare const findNavItemByRelativePath: (navItems: NavItemViewModel[], relativePath: string) => NavItemViewModel | undefined;
35
35
  export declare const findNavItemByPageSlug: (navItems: NavItemViewModel[], pageSlug: string) => NavItemViewModel | undefined;
36
+ export declare const hasVisibleNavigation: (navItems: NavItemViewModel[]) => boolean;
@@ -136,3 +136,12 @@ export const findNavItemByPageSlug = (navItems, pageSlug) => {
136
136
  }
137
137
  return undefined;
138
138
  };
139
+ // Nav shows when more than one page is visible, or one page has visible subpages.
140
+ // The header row and the side menu both key the button placement off this — one
141
+ // source so the two can never disagree.
142
+ export const hasVisibleNavigation = (navItems) => {
143
+ const visibleNavItems = navItems.filter((item) => !item.isHidden);
144
+ return (visibleNavItems.length > 1 ||
145
+ (visibleNavItems.length === 1 &&
146
+ visibleNavItems[0].nestedNavItems.some((item) => !item.isHidden)));
147
+ };
@@ -1,6 +1,6 @@
1
1
  import { reactive } from 'vue';
2
2
  import { assertUnreachable } from '../../helpers/ts.helper';
3
- import { ButtonStyles, VIEWPORTS } from '../models';
3
+ import { ButtonStyles, TEXT_STYLE_TYPES, VIEWPORTS } from '../models';
4
4
  import { NavigationMobile, NavigationDesktop, BRAND_PAGE_TYPES, BUTTON_LINK_TYPE, NavigationMenuStyles, } from '../models';
5
5
  import { backgroundColorFromStyle, isTransparentColour, mutedTextForBackground, withColorOpacity, } from './color.util';
6
6
  import { resolveColorReference } from './color-palette.util';
@@ -691,6 +691,57 @@ export const mapToPageStyleViewModel = (pageStyles, options) => {
691
691
  colors: pageStyles.colors ?? [],
692
692
  };
693
693
  };
694
+ // Maps each link kind to the role Button.vue already understands, so the button needs no new code.
695
+ const HEADER_BUTTON_LINK_ROLES = {
696
+ [BUTTON_LINK_TYPE.url]: 'general-link',
697
+ [BUTTON_LINK_TYPE.page]: 'general-link',
698
+ [BUTTON_LINK_TYPE.mailTo]: 'email',
699
+ [BUTTON_LINK_TYPE.tel]: 'phone',
700
+ };
701
+ const mapToHeaderButtonViewModel = (headerButton, styles) => {
702
+ // No label means no button — hidden in preview and on the published site.
703
+ if (!headerButton?.isVisible || !headerButton.text?.trim()) {
704
+ return undefined;
705
+ }
706
+ const titleStyle = headerButton.buttonTextStyle ?? {
707
+ textStyleType: TEXT_STYLE_TYPES.buttons,
708
+ };
709
+ const viewModel = mapToButtonViewModel({
710
+ id: 'page-header-button',
711
+ // Old saved data may have no link kind — treat it as a url.
712
+ type: HEADER_BUTTON_LINK_ROLES[headerButton.buttonLinkType] ??
713
+ HEADER_BUTTON_LINK_ROLES[BUTTON_LINK_TYPE.url],
714
+ iconUrl: '',
715
+ modalImageUrl: '',
716
+ colorReplacements: [],
717
+ title: headerButton.text.trim(),
718
+ titleStyle,
719
+ url: headerButton.url ?? '',
720
+ page: headerButton.buttonPageId ?? '',
721
+ clickActionField: headerButton.buttonLinkType === BUTTON_LINK_TYPE.page ? 'page' : 'url',
722
+ }, styles, { titleStyle });
723
+ return {
724
+ ...viewModel,
725
+ // A wrapped label justifies; the last (or only) line stays centered like a short label.
726
+ titleStyle: {
727
+ ...viewModel.titleStyle,
728
+ textAlign: 'justify',
729
+ textAlignLast: 'center',
730
+ },
731
+ styles: {
732
+ ...viewModel.styles,
733
+ style: {
734
+ ...viewModel.styles.style,
735
+ ...(headerButton.fillColor
736
+ ? { backgroundColor: headerButton.fillColor }
737
+ : {}),
738
+ ...(headerButton.borderColor
739
+ ? { borderColor: headerButton.borderColor }
740
+ : {}),
741
+ },
742
+ },
743
+ };
744
+ };
694
745
  export const mapToPageHeaderViewModel = (pageHeader, pageStyles, pages, useOldLogoRenderSize = false) => {
695
746
  const viewport = pageHeader.viewport;
696
747
  const logoContent = {
@@ -738,6 +789,7 @@ export const mapToPageHeaderViewModel = (pageHeader, pageStyles, pages, useOldLo
738
789
  }),
739
790
  style: pageHeader.style,
740
791
  backgroundStyle: getHeaderBackgroundStyleWithOpacity(pageHeader),
792
+ headerButtonViewModel: mapToHeaderButtonViewModel(pageHeader.headerButton, pageStyles),
741
793
  };
742
794
  };
743
795
  // Folds backgroundOpacity into backgroundColor's alpha so only the container's paint fades, not its children.
@@ -132,10 +132,12 @@ export interface BookingSectionViewModel extends ContentViewModel, Omit<BookingS
132
132
  buttonViewModel: ButtonViewModel;
133
133
  isFullWidth: boolean;
134
134
  }
135
- export interface PageHeaderViewModel extends Omit<PageHeaderDesktop | PageHeaderMobile, 'logoImage' | 'logoImageStyle' | 'isLogoOptional' | 'viewport' | 'isLogoVisible' | 'logoTemplateImage' | 'logoImageHeight' | 'logoImageWidth' | 'backgroundStyle'> {
135
+ export interface PageHeaderViewModel extends Omit<PageHeaderDesktop | PageHeaderMobile, 'logoImage' | 'logoImageStyle' | 'isLogoOptional' | 'viewport' | 'isLogoVisible' | 'logoTemplateImage' | 'logoImageHeight' | 'logoImageWidth' | 'headerButton' | 'backgroundStyle'> {
136
136
  logo: LogoViewModel;
137
137
  pages: PageViewModel[];
138
138
  backgroundStyle: BrandPageCssStyle;
139
+ /** Absent unless the header call-to-action button is configured AND visible. */
140
+ headerButtonViewModel?: ButtonViewModel;
139
141
  }
140
142
  export interface PageFooterViewModel extends Omit<PageFooterDesktop | PageFooterMobile, 'logoImage' | 'logoImageStyle' | 'isLogoOptional' | 'viewport' | 'isLogoVisible' | 'logoTemplateImage' | 'logoImageHeight' | 'logoImageWidth'> {
141
143
  logo: LogoViewModel;