@designcrowd/library.brand-page 5.17.21 → 5.17.23-ast-subnav

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 (121) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-Brtp2yWB.js → CreatedOnBrandCrowd-de-de-Ct9Aewoo.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-BIJ5VoX4.js → CreatedOnBrandCrowd-en-us-BsEzGp5K.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-JrKK9K0u.js → CreatedOnBrandCrowd-es-es-UiIPmY0h.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-D_HvOZe-.js → CreatedOnBrandCrowd-fr-ca-CQmEXbU7.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-D_HvOZe-.js → CreatedOnBrandCrowd-fr-fr-CQmEXbU7.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-SSLb0vlp.js → CreatedOnBrandCrowd-pt-br-DoMI5QSQ.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-SSLb0vlp.js → CreatedOnBrandCrowd-pt-pt-DoMI5QSQ.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BG39ozFo.js → CreatedOnDcom-de-de-gexV_wWX.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-D2NzqECZ.js → CreatedOnDcom-en-us-C2sLHLjJ.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-C55r2Lb4.js → CreatedOnDcom-es-es-CZFd666H.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-Bj-sAaJI.js → CreatedOnDcom-fr-ca-CPaRB_io.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-D8l0r-Tc.js → CreatedOnDcom-fr-fr-BQo5D5gE.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CXHC6E1h.js → CreatedOnDcom-pt-br-CRr3CqOj.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-2dMvgnyi.js → CreatedOnDcom-pt-pt-DR6Vi-eZ.js} +1 -1
  15. package/lib/src/brand-page/components/banner-section/BannerSection.mixin.d.ts +1 -1
  16. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +1 -0
  17. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +20 -2
  18. package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.d.ts +8 -1
  19. package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +97 -3
  20. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +6 -2
  21. package/lib/src/brand-page/models/index.d.ts +1 -1
  22. package/lib/src/brand-page/models/navigation-styles.model.d.ts +2 -0
  23. package/lib/src/brand-page/models/navigation-styles.model.js +20 -1
  24. package/lib/src/brand-page/utils/migration/migration-14.d.ts +2 -0
  25. package/lib/src/brand-page/utils/migration/migration-14.js +16 -0
  26. package/lib/src/brand-page/utils/migration/migration-15.d.ts +2 -0
  27. package/lib/src/brand-page/utils/migration/migration-15.js +37 -0
  28. package/lib/src/brand-page/utils/migration.util.js +12 -0
  29. package/lib/src/brand-page/utils/style.util.js +16 -2
  30. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.d.ts +1 -1
  31. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +1 -1
  32. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-site-template.examples.js +1 -1
  33. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +7 -1
  34. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +1 -1
  35. package/lib/src/brand-page-maker/constants/config-settings-constant.js +1 -10
  36. package/lib/src/brand-page-maker/models/content-settings-configs.d.ts +5 -0
  37. package/lib/src/brand-page-maker/models/content-settings.js +3 -0
  38. package/lib/src/brand-page-maker/models/navigation-style-configs.d.ts +1 -0
  39. package/lib/src/brand-page-maker/models/navigation-style-configs.js +5 -0
  40. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +170 -388
  41. package/lib/src/{bundled-translations-Bu_5FO26.js → bundled-translations-Cy6nun02.js} +1 -1
  42. package/lib/src/{bundled-translations.de-DE-CZTzknyj.js → bundled-translations.de-DE-BUZncCAM.js} +1 -1
  43. package/lib/src/{bundled-translations.es-ES-p86F-gOD.js → bundled-translations.es-ES-D4IPwZD-.js} +9 -9
  44. package/lib/src/{bundled-translations.fr-CA-CM5ZA8dQ.js → bundled-translations.fr-CA-BMgRrrwA.js} +9 -9
  45. package/lib/src/{bundled-translations.fr-FR-DV7sOgtb.js → bundled-translations.fr-FR-Ck7kYrK4.js} +1 -1
  46. package/lib/src/{bundled-translations.pt-BR-DkWWGrsz.js → bundled-translations.pt-BR--5_9viJ9.js} +1 -1
  47. package/lib/src/{bundled-translations.pt-PT-C5Td5lLs.js → bundled-translations.pt-PT-DAGUOQ7m.js} +13 -13
  48. package/lib/src/bundles/bundled-translations.de-DE.json +1 -0
  49. package/lib/src/bundles/bundled-translations.es-ES.json +1 -0
  50. package/lib/src/bundles/bundled-translations.fr-CA.json +1 -0
  51. package/lib/src/bundles/bundled-translations.fr-FR.json +1 -0
  52. package/lib/src/bundles/bundled-translations.json +1 -0
  53. package/lib/src/bundles/bundled-translations.pt-BR.json +1 -0
  54. package/lib/src/bundles/bundled-translations.pt-PT.json +1 -0
  55. package/lib/src/css/library.brand-page-brandCrowd.min.css +110 -103
  56. package/lib/src/css/library.brand-page-brandPage.min.css +110 -103
  57. package/lib/src/css/library.brand-page-designCom.min.css +110 -103
  58. package/lib/src/css/library.brand-page-preview.min.css +110 -103
  59. package/lib/src/index.mjs +1 -1
  60. package/lib/src/{lib-CrBvj1a5.js → lib-wvy4koSU.js} +22606 -22689
  61. package/lib/src/metadata-builder/builders/section-field-maps.js +1 -0
  62. package/lib/src/metadata-builder/builders/section-field-utils.js +5 -0
  63. package/lib/src/metadata-builder/helpers/rte.helpers.js +3 -0
  64. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +2 -1
  65. package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.d.ts +4 -1
  66. package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.js +55 -2
  67. package/lib/src/shared/navigation-style-settings/store/index.d.ts +6 -0
  68. package/lib/src/shared/navigation-style-settings/store/index.js +15 -0
  69. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +27 -1
  70. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +25 -2
  71. package/package.json +1 -1
  72. package/src/brand-page/components/about-section/AboutSection.vue +63 -6
  73. package/src/brand-page/components/collapsible/Collapsible.vue +8 -2
  74. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +21 -2
  75. package/src/brand-page/components/contact-form/ContactForm.vue +15 -15
  76. package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +114 -5
  77. package/src/brand-page/components/image-gallery/ImageGalleryModal.vue +25 -8
  78. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +19 -8
  79. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +6 -2
  80. package/src/brand-page/components/text-wrapper/TextWrapper.vue +5 -1
  81. package/src/brand-page/models/index.ts +1 -1
  82. package/src/brand-page/models/navigation-styles.model.ts +31 -0
  83. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +15 -3
  84. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +4 -0
  85. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +8 -0
  86. package/src/brand-page/utils/migration/migration-14.ts +23 -0
  87. package/src/brand-page/utils/migration/migration-15.ts +62 -0
  88. package/src/brand-page/utils/migration.util.ts +14 -0
  89. package/src/brand-page/utils/style.util.ts +16 -2
  90. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +1 -1
  91. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-site-template.examples.ts +1 -1
  92. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +8 -1
  93. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +1 -1
  94. package/src/brand-page-maker/constants/config-settings-constant.ts +1 -10
  95. package/src/brand-page-maker/models/content-settings-configs.ts +6 -0
  96. package/src/brand-page-maker/models/content-settings.ts +3 -0
  97. package/src/brand-page-maker/models/i18n/models.de-DE.json +1 -0
  98. package/src/brand-page-maker/models/i18n/models.es-ES.json +1 -0
  99. package/src/brand-page-maker/models/i18n/models.fr-CA.json +1 -0
  100. package/src/brand-page-maker/models/i18n/models.fr-FR.json +1 -0
  101. package/src/brand-page-maker/models/i18n/models.json +1 -0
  102. package/src/brand-page-maker/models/i18n/models.pt-BR.json +1 -0
  103. package/src/brand-page-maker/models/i18n/models.pt-PT.json +1 -0
  104. package/src/brand-page-maker/models/navigation-style-configs.ts +5 -0
  105. package/src/brand-page-maker/utils/rich-text-editor.util.ts +274 -684
  106. package/src/bundles/bundled-translations.de-DE.json +1 -0
  107. package/src/bundles/bundled-translations.es-ES.json +1 -0
  108. package/src/bundles/bundled-translations.fr-CA.json +1 -0
  109. package/src/bundles/bundled-translations.fr-FR.json +1 -0
  110. package/src/bundles/bundled-translations.json +1 -0
  111. package/src/bundles/bundled-translations.pt-BR.json +1 -0
  112. package/src/bundles/bundled-translations.pt-PT.json +1 -0
  113. package/src/metadata-builder/builders/section-field-maps.ts +1 -0
  114. package/src/metadata-builder/builders/section-field-utils.ts +5 -0
  115. package/src/metadata-builder/helpers/rte.helpers.ts +4 -0
  116. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +2 -1
  117. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.ts +82 -4
  118. package/src/shared/navigation-style-settings/store/index.ts +30 -0
  119. package/lib/src/brand-page/components/about-section/AboutSection.mixin.d.ts +0 -83
  120. package/lib/src/brand-page/components/about-section/AboutSection.mixin.js +0 -65
  121. package/src/brand-page/components/about-section/AboutSection.mixin.ts +0 -78
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as t } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as e } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as e } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as e } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as e } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as e } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as M } from "./lib-wvy4koSU.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-CrBvj1a5.js";
2
+ import { _ as M } from "./lib-wvy4koSU.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -96,8 +96,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
96
96
  default: undefined;
97
97
  };
98
98
  }>> & Readonly<{}>, {
99
- contentIndex: number;
100
99
  containerClientWidth: number | undefined;
101
100
  containerClientHeight: number | undefined;
101
+ contentIndex: number;
102
102
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
103
103
  export default _default;
@@ -60,6 +60,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
60
60
  title(): string;
61
61
  renderText(): string;
62
62
  renderSuccessText(): string;
63
+ successMessageColorStyle(): BrandPageCssStyle;
63
64
  }, {
64
65
  submitContactForm(): Promise<void>;
65
66
  validateFormValues(): void;
@@ -5,6 +5,7 @@ import brandPageClient from '../../clients/brand-page.client';
5
5
  import { isEmail } from '../../../utils/validator.util';
6
6
  import { ALIGN_CARD_CENTER, ALIGN_CARD_CENTER_IMAGE, ALIGN_CENTERED, ALIGN_LEFT_FULL_IMAGE, ALIGN_RIGHT_FULL_IMAGE, DISPLAY_STYLE_COLLAPSED, RECAPTCHA_ACTION_CONTACT_FORM, TEXT_ONLY, } from '../../constants';
7
7
  import { getRenderText } from '@brand-page/utils';
8
+ import { hasRTEContent } from '@brand-page-maker/utils';
8
9
  import { useReCaptcha } from '../../composables/recaptcha.composable';
9
10
  export default defineComponent({
10
11
  props: {
@@ -116,13 +117,30 @@ export default defineComponent({
116
117
  if (!this.viewModel.description) {
117
118
  return '';
118
119
  }
119
- return getRenderText(this.viewModel.description);
120
+ if (hasRTEContent(this.viewModel.description)) {
121
+ return this.viewModel.description;
122
+ }
123
+ else {
124
+ return getRenderText(this.viewModel.description);
125
+ }
120
126
  },
121
127
  renderSuccessText() {
122
128
  if (!this.viewModel.successMessage) {
123
129
  return '';
124
130
  }
125
- return getRenderText(this.viewModel.successMessage);
131
+ if (hasRTEContent(this.viewModel.successMessage)) {
132
+ return this.viewModel.successMessage;
133
+ }
134
+ else {
135
+ return getRenderText(this.viewModel.successMessage);
136
+ }
137
+ },
138
+ successMessageColorStyle() {
139
+ const color = this.viewModel.successMessageStyle?.color;
140
+ if (color) {
141
+ return { color };
142
+ }
143
+ return {};
126
144
  },
127
145
  },
128
146
  watch: {
@@ -30,13 +30,14 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
30
30
  isImageModalLoading: boolean;
31
31
  carouselImages: any[][] | undefined;
32
32
  showControl: boolean;
33
+ carouselComponentRef: string;
33
34
  }, {
34
35
  isImageModalVisible(): boolean;
35
36
  altText(): string;
36
37
  showCarouselControls(): boolean;
37
38
  navigationUniqueIndexer(): string;
38
39
  swiperOptions(): {
39
- initialSlide: number;
40
+ initialSlide: any;
40
41
  loop: boolean;
41
42
  slidesPerGroup: number;
42
43
  slidesPerView: number;
@@ -58,6 +59,12 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
58
59
  imageLoading(): void;
59
60
  checkImageLoading(isLoading: any): void;
60
61
  onImageModalClose(): void;
62
+ isSlideInRenderWindow(index: number): boolean;
63
+ onCarouselLoaded(): void;
64
+ onSlideImageLoading(index: number): void;
65
+ onSlideImageLoaded(index: number): void;
66
+ onSlideImageError(index: number): void;
67
+ placeholderStyle(slide: any): Record<string, string>;
61
68
  }, import("vue").DefineComponent<import("vue").ExtractPropTypes<{
62
69
  isPreview: {
63
70
  type: BooleanConstructor;
@@ -2,6 +2,14 @@ import { defineComponent } from 'vue';
2
2
  import ComponentCommonMixin from '../mixins/component-common.mixin';
3
3
  import ImageModalMixin from '../mixins/image-modal.mixin';
4
4
  import cloneDeep from 'lodash.clonedeep';
5
+ // Number of slides on each side of the current slide to keep mounted with a
6
+ // real <img>. Slides outside this window render an empty placeholder so the
7
+ // browser does not request full-resolution images for the entire gallery on
8
+ // modal open — required to prevent mobile tab crashes on large galleries.
9
+ // 3 (= 7 slides total) is wide enough that a user dragging slowly across
10
+ // 2-3 slides never exposes a placeholder, while still capping decoded
11
+ // image memory well under mobile per-tab limits.
12
+ const IMAGE_RENDER_WINDOW = 3;
5
13
  export default defineComponent({
6
14
  mixins: [ComponentCommonMixin, ImageModalMixin],
7
15
  props: {
@@ -37,6 +45,7 @@ export default defineComponent({
37
45
  isImageModalLoading: false,
38
46
  carouselImages: [],
39
47
  showControl: true,
48
+ carouselComponentRef: 'image-gallery-carousel',
40
49
  };
41
50
  },
42
51
  computed: {
@@ -59,7 +68,7 @@ export default defineComponent({
59
68
  },
60
69
  swiperOptions() {
61
70
  return {
62
- initialSlide: 0,
71
+ initialSlide: this.selectedImageIndex ?? 0,
63
72
  loop: this.images.length > 1,
64
73
  slidesPerGroup: 1,
65
74
  slidesPerView: 1,
@@ -89,8 +98,6 @@ export default defineComponent({
89
98
  return;
90
99
  }
91
100
  this.isImageModalLoading = true;
92
- this.swiperOptions.initialSlide = newIndex;
93
- // this.$nextTick(() => this.checkImageModalImageComplete());
94
101
  },
95
102
  images: {
96
103
  deep: true,
@@ -131,5 +138,92 @@ export default defineComponent({
131
138
  onImageModalClose() {
132
139
  this.$emit('close');
133
140
  },
141
+ isSlideInRenderWindow(index) {
142
+ if (this.currentImageIndex === undefined) {
143
+ return false;
144
+ }
145
+ const total = this.images.length;
146
+ if (total === 0) {
147
+ return false;
148
+ }
149
+ const direct = Math.abs(index - this.currentImageIndex);
150
+ // For looped galleries, the shortest path between two slides may wrap
151
+ // around the end. Use whichever distance is smaller.
152
+ const wrapped = total - direct;
153
+ const distance = Math.min(direct, wrapped);
154
+ return distance <= IMAGE_RENDER_WINDOW;
155
+ },
156
+ onCarouselLoaded() {
157
+ // Reach through the Carousel ref to bind directly to the underlying
158
+ // Swiper instance — the shared Carousel doesn't emit slide-change
159
+ // events. Keeps `currentImageIndex` in sync with user navigation
160
+ // (arrows, swipes, keyboard) so the render window slides with the
161
+ // user.
162
+ //
163
+ // NOTE: `currentImageIndex` must not be bound back to Carousel's
164
+ // `:slide-index` prop. The shared Carousel watches that prop and
165
+ // calls `swiper.update()` + `swiper.slideTo()` on every change.
166
+ // With `slideChangeTransitionStart` updating currentImageIndex on
167
+ // every swipe, that creates a feedback loop where Swiper redoes a
168
+ // full layout recalculation on every user gesture — visible as
169
+ // jank and capable of crashing the tab on real mobile devices.
170
+ const carousel = this.$refs[this.carouselComponentRef];
171
+ const swiper = carousel?.swiper;
172
+ if (!swiper || typeof swiper.on !== 'function') {
173
+ return;
174
+ }
175
+ // Listen at the *start* of the transition so the incoming neighbour
176
+ // mounts and starts loading while the slide animation is still
177
+ // playing. Listening on `slideChange` (end of transition) leaves a
178
+ // gap during fast swipes where the next neighbour is still a
179
+ // placeholder when it reaches the viewport — visible as a flicker.
180
+ const handleSlideChange = () => {
181
+ // `realIndex` reflects the underlying slide index when loop mode
182
+ // duplicates slides; `activeIndex` would include those duplicates.
183
+ const next = typeof swiper.realIndex === 'number'
184
+ ? swiper.realIndex
185
+ : swiper.activeIndex;
186
+ if (typeof next === 'number' && next !== this.currentImageIndex) {
187
+ this.currentImageIndex = next;
188
+ }
189
+ };
190
+ swiper.on('slideChangeTransitionStart', handleSlideChange);
191
+ // Also handle instant jumps that bypass the transition (e.g. when
192
+ // navigation arrows trigger no-animation slides).
193
+ swiper.on('slideChange', handleSlideChange);
194
+ },
195
+ // Only the currently-viewed slide's load lifecycle should drive the
196
+ // modal's Loader. Neighbour FallbackImages mounted by the render window
197
+ // emit `image-loading` synchronously in their onMounted hook; without
198
+ // these gates that emission flips `isImageModalLoading` true mid-swipe,
199
+ // briefly flashing the spinner over the slide the user is actually on
200
+ // — the flicker reported on real mobile devices.
201
+ onSlideImageLoading(index) {
202
+ if (index === this.currentImageIndex) {
203
+ this.imageLoading();
204
+ }
205
+ },
206
+ onSlideImageLoaded(index) {
207
+ if (index === this.currentImageIndex) {
208
+ this.checkImageLoading(false);
209
+ }
210
+ },
211
+ onSlideImageError(index) {
212
+ if (index === this.currentImageIndex) {
213
+ this.checkImageLoading(true);
214
+ }
215
+ },
216
+ placeholderStyle(slide) {
217
+ // Sized so the placeholder occupies the exact space the loaded image
218
+ // would, preventing slide-height jumps when the render window swaps
219
+ // between placeholder and real image. Mirrors the image's own
220
+ // `max-width: 100%` + `max-height: 90vh` + intrinsic aspect ratio.
221
+ if (!slide?.width || !slide?.height) {
222
+ return {};
223
+ }
224
+ return {
225
+ aspectRatio: `${slide.width} / ${slide.height}`,
226
+ };
227
+ },
134
228
  },
135
229
  });
@@ -70,12 +70,16 @@ export default defineComponent({
70
70
  return navItem.relativePath === this.context.currentPageRelativePath;
71
71
  },
72
72
  getSubNavItemStyle(navItem) {
73
- const baseStyle = this.isCurrentPage(navItem)
73
+ const isActive = this.isCurrentPage(navItem);
74
+ const baseStyle = isActive
74
75
  ? this.selectedButtonStyle
75
76
  : this.defaultButtonStyle;
76
77
  return {
77
78
  ...baseStyle,
78
- paddingLeft: '32px', // 16px additional indentation (base is 16px)
79
+ paddingLeft: '32px',
80
+ backgroundColor: isActive
81
+ ? baseStyle.backgroundColor
82
+ : this.styles.hamburgerMenuStyle.subNavBackgroundColor ?? '#ffffff',
79
83
  };
80
84
  },
81
85
  closeSideMenu() {
@@ -245,7 +245,7 @@ export interface ContactFormContent extends Content {
245
245
  descriptionStyle?: TextStyleDeclaration;
246
246
  buttonTextStyle?: TextStyleDeclaration;
247
247
  backgroundStyle?: BrandPageCssStyle;
248
- messageTextColor?: BrandPageCssStyle;
248
+ successMessageStyle?: TextStyleDeclaration;
249
249
  cardStyle?: BrandPageCssStyle;
250
250
  colorReplacements?: ColorReplacement[];
251
251
  mediaType?: string;
@@ -5,6 +5,7 @@ export declare class NavigationMenuStyles {
5
5
  defaultButtonStyle: TextStyleDeclaration;
6
6
  selectedButtonStyle: BrandPageCssStyle;
7
7
  iconStyle: BrandPageCssStyle;
8
+ subNavBackgroundColor?: string;
8
9
  constructor(options: Partial<NavigationMenuStyles>, defaultOptions: Partial<NavigationMenuStyles>);
9
10
  }
10
11
  type NavigationStylesOptionType = Partial<Omit<NavigationDesktop | NavigationMobile, 'hamburgerMenuStyle'>> & {
@@ -17,6 +18,7 @@ declare abstract class NavigationStyles implements NavigationMenuStyles {
17
18
  defaultButtonStyle: TextStyleDeclaration;
18
19
  selectedButtonStyle: BrandPageCssStyle;
19
20
  iconStyle: BrandPageCssStyle;
21
+ subNavBackgroundColor?: string;
20
22
  isLogoVisible: boolean;
21
23
  hamburgerMenuStyle: NavigationMenuStyles;
22
24
  viewport: ViewportsType;
@@ -1,4 +1,4 @@
1
- import { DEFAULT_FONT_FAMILY_KEY, DEFAULT_FONT_STYLE, DEFAULT_TEXT_ALIGN, DEFAULT_TEXT_DECORATION, FONT_FAMILY_CONFIGS, FONT_SIZE_BODY, FONT_WEIGHT_NORMAL, defaultHamburgerNavigation, NAVIGATION_DISPLAY, } from '../constants';
1
+ import { DEFAULT_FONT_FAMILY_KEY, DEFAULT_FONT_STYLE, DEFAULT_TEXT_ALIGN, DEFAULT_TEXT_DECORATION, FONT_FAMILY_CONFIGS, FONT_SIZE_BODY, FONT_WEIGHT_NORMAL, STYLE_THEME_KEYS, defaultHamburgerNavigation, NAVIGATION_DISPLAY, } from '../constants';
2
2
  import { VIEWPORTS } from './index';
3
3
  import { TEXT_STYLE_TYPES } from './index';
4
4
  import cloneDeep from 'lodash.clonedeep';
@@ -6,18 +6,33 @@ export class NavigationMenuStyles {
6
6
  defaultButtonStyle;
7
7
  selectedButtonStyle;
8
8
  iconStyle;
9
+ subNavBackgroundColor;
9
10
  constructor(options, defaultOptions) {
10
11
  this.defaultButtonStyle = Object.assign({}, defaultOptions.defaultButtonStyle, options.defaultButtonStyle || {});
11
12
  this.selectedButtonStyle = Object.assign({}, defaultOptions.selectedButtonStyle, options.selectedButtonStyle || {});
12
13
  this.iconStyle = Object.assign({}, defaultOptions.iconStyle, options.iconStyle || {});
14
+ this.subNavBackgroundColor =
15
+ options.subNavBackgroundColor ?? defaultOptions.subNavBackgroundColor;
13
16
  }
14
17
  }
18
+ const getDefaultSubNavBackgroundColor = (defaultTextColor) => {
19
+ if (defaultTextColor === STYLE_THEME_KEYS.LogoTextColor ||
20
+ defaultTextColor === STYLE_THEME_KEYS.LogoTextMultiColor) {
21
+ return STYLE_THEME_KEYS.LogoBackgroundColor;
22
+ }
23
+ if (defaultTextColor === STYLE_THEME_KEYS.LogoBackgroundColor ||
24
+ defaultTextColor === STYLE_THEME_KEYS.LogoBackgroundMultiColor) {
25
+ return STYLE_THEME_KEYS.LogoTextColor;
26
+ }
27
+ return '#ffffff';
28
+ };
15
29
  class NavigationStyles {
16
30
  displayType;
17
31
  renderAfterLogo;
18
32
  defaultButtonStyle;
19
33
  selectedButtonStyle;
20
34
  iconStyle;
35
+ subNavBackgroundColor;
21
36
  isLogoVisible;
22
37
  hamburgerMenuStyle;
23
38
  viewport;
@@ -55,6 +70,9 @@ class NavigationStyles {
55
70
  borderColor: theme?.primaryColor,
56
71
  }, option?.selectedButtonStyle || {});
57
72
  this.iconStyle = Object.assign({}, option?.iconStyle || {});
73
+ this.subNavBackgroundColor =
74
+ option?.subNavBackgroundColor ??
75
+ getDefaultSubNavBackgroundColor(option?.defaultButtonStyle?.color);
58
76
  this.isLogoVisible = option?.isLogoVisible || true;
59
77
  this.hamburgerMenuStyle = new NavigationMenuStyles(option?.hamburgerMenuStyle || {}, {
60
78
  defaultButtonStyle: {
@@ -74,6 +92,7 @@ class NavigationStyles {
74
92
  color: theme?.secondaryColor,
75
93
  backgroundColor: theme?.primaryColor,
76
94
  },
95
+ subNavBackgroundColor: theme?.secondaryColor ?? '#ffffff',
77
96
  });
78
97
  }
79
98
  }
@@ -0,0 +1,2 @@
1
+ import type { MigrationData } from '../migration.util';
2
+ export declare const migration14: (migrationResult: MigrationData) => Promise<MigrationData>;
@@ -0,0 +1,16 @@
1
+ import { isContact } from '../model.util';
2
+ export const migration14 = async (migrationResult) => {
3
+ const { brandPageModel } = migrationResult;
4
+ brandPageModel.pages.forEach((page) => {
5
+ page.contents.forEach((content) => {
6
+ if (isContact(content)) {
7
+ const contactForm = content;
8
+ if ('messageTextColor' in contactForm) {
9
+ contactForm.successMessageStyle = contactForm.messageTextColor;
10
+ delete contactForm.messageTextColor;
11
+ }
12
+ }
13
+ });
14
+ });
15
+ return migrationResult;
16
+ };
@@ -0,0 +1,2 @@
1
+ import type { MigrationData } from '../migration.util';
2
+ export declare const migration15: (migrationResult: MigrationData) => Promise<MigrationData>;
@@ -0,0 +1,37 @@
1
+ import { STYLE_THEME_KEYS } from '../../constants';
2
+ const DEFAULT_SUB_NAV_BG_COLOR = '#ffffff';
3
+ const getSubNavBgColorFromTextColor = (textColor) => {
4
+ if (textColor === STYLE_THEME_KEYS.LogoTextColor ||
5
+ textColor === STYLE_THEME_KEYS.LogoTextMultiColor) {
6
+ return STYLE_THEME_KEYS.LogoBackgroundColor;
7
+ }
8
+ if (textColor === STYLE_THEME_KEYS.LogoBackgroundColor ||
9
+ textColor === STYLE_THEME_KEYS.LogoBackgroundMultiColor) {
10
+ return STYLE_THEME_KEYS.LogoTextColor;
11
+ }
12
+ return DEFAULT_SUB_NAV_BG_COLOR;
13
+ };
14
+ export const migration15 = async (migrationResult) => {
15
+ const { brandPageModel } = migrationResult;
16
+ const navigations = [
17
+ brandPageModel.pageHeaderDesktop?.navigation,
18
+ brandPageModel.pageHeaderMobile?.navigation,
19
+ brandPageModel.headerStyles?.navigation,
20
+ ];
21
+ for (const nav of navigations) {
22
+ if (!nav)
23
+ continue;
24
+ if (!nav.subNavBackgroundColor ||
25
+ nav.subNavBackgroundColor === DEFAULT_SUB_NAV_BG_COLOR) {
26
+ nav.subNavBackgroundColor = getSubNavBgColorFromTextColor(nav.defaultButtonStyle?.color);
27
+ }
28
+ if (nav.hamburgerMenuStyle) {
29
+ const hamburgerBg = nav.hamburgerMenuStyle.subNavBackgroundColor;
30
+ if (!hamburgerBg || hamburgerBg === DEFAULT_SUB_NAV_BG_COLOR) {
31
+ nav.hamburgerMenuStyle.subNavBackgroundColor =
32
+ getSubNavBgColorFromTextColor(nav.hamburgerMenuStyle.defaultButtonStyle?.color);
33
+ }
34
+ }
35
+ }
36
+ return migrationResult;
37
+ };
@@ -16,6 +16,8 @@ import { migration11 } from './migration/migration-11';
16
16
  import { migration12 } from './migration/migration-12';
17
17
  import { migration12_1 } from './migration/migration-12_1';
18
18
  import { migration13 } from './migration/migration-13';
19
+ import { migration14 } from './migration/migration-14';
20
+ import { migration15 } from './migration/migration-15';
19
21
  const MIGRATION_TABLE = [
20
22
  {
21
23
  version: 1,
@@ -103,6 +105,16 @@ const MIGRATION_TABLE = [
103
105
  migrateFn: migration13,
104
106
  description: 'Migrating old page navigation refererences to use page ids',
105
107
  },
108
+ {
109
+ version: 14,
110
+ migrateFn: migration14,
111
+ description: 'Renaming messageTextColor to successMessageStyle on contact form content',
112
+ },
113
+ {
114
+ version: 15,
115
+ migrateFn: migration15,
116
+ description: 'Set sub nav background color based on default text style color',
117
+ },
106
118
  ];
107
119
  export const GetLatestModelVersion = () => Math.max(...MIGRATION_TABLE.map((x) => x.version));
108
120
  export const migrateBrandPageModel = async (brandPageModel, options) => {
@@ -162,7 +162,14 @@ export const applyLogoThemeToBrandPageNavigationStyles = (logoTheme, navigation)
162
162
  : new NavigationDesktop();
163
163
  for (const [key, value] of Object.entries(navigation)) {
164
164
  if (typeof value === 'string' || typeof value === 'boolean') {
165
- newNavigation[key] = value;
165
+ if (typeof value === 'string') {
166
+ const output = colorMatchCssKeyValue(key, value, logoTheme);
167
+ newNavigation[key] = output.cssValue;
168
+ isModified = isModified || output.isModified;
169
+ }
170
+ else {
171
+ newNavigation[key] = value;
172
+ }
166
173
  }
167
174
  else {
168
175
  const output = applyLogoThemeToBrandPageStyleRecursive(logoTheme, key, value);
@@ -225,7 +232,14 @@ const CONTENT_STYLE_PROP_NAME_SUFFIX = [
225
232
  'Color',
226
233
  'Replacements',
227
234
  ];
228
- const RTE_ALLOWED_FIELDS = ['title', 'description', 'text', 'textItems'];
235
+ const RTE_ALLOWED_FIELDS = [
236
+ 'title',
237
+ 'description',
238
+ 'text',
239
+ 'textItems',
240
+ 'paragraph',
241
+ 'successMessage',
242
+ ];
229
243
  export const applyLogoThemeToContents = (logoTheme, pages) => {
230
244
  let isModified = false;
231
245
  const newPages = pages.map((page) => {
@@ -757,7 +757,7 @@ export declare const BRAND_SITE_SAMPLE_WITH_LOGO: {
757
757
  textStyleType: string;
758
758
  applyAutoScale: boolean;
759
759
  };
760
- messageTextColor: {};
760
+ successMessageStyle: {};
761
761
  }[];
762
762
  })[];
763
763
  styles: {
@@ -1455,7 +1455,7 @@ export const BRAND_SITE_SAMPLE_WITH_LOGO = {
1455
1455
  textStyleType: 'paragraphs',
1456
1456
  applyAutoScale: true,
1457
1457
  },
1458
- messageTextColor: {},
1458
+ successMessageStyle: {},
1459
1459
  },
1460
1460
  ],
1461
1461
  },
@@ -803,7 +803,7 @@ export const BRAND_SITE_TEMPLATE_SAMPLE_2 = [
803
803
  overflowWrap: 'anywhere',
804
804
  wordBreak: 'normal',
805
805
  },
806
- messageTextColor: {},
806
+ successMessageStyle: {},
807
807
  role: 'contact-form',
808
808
  buttonStyles: {
809
809
  style: {
@@ -964,6 +964,12 @@ declare const _default: import("vue").DefineComponent<{}, {
964
964
  style: BrandPageCssStyle;
965
965
  viewport: import("@brand-page").ViewportsType;
966
966
  }): void;
967
+ _setSubNavBackgroundColor({ displayType, section, value, viewport, }: {
968
+ displayType: import("@brand-page").NavigationDisplayType;
969
+ section: "footer" | "header";
970
+ value: string;
971
+ viewport: import("@brand-page").ViewportsType;
972
+ }): void;
967
973
  _setButtonStyles({ section, defaultButtonStyle, selectedButtonStyle, iconStyle, viewport, }: {
968
974
  section: "footer" | "header";
969
975
  defaultButtonStyle: import("@brand-page").TextStyleDeclaration;
@@ -978,7 +984,7 @@ declare const _default: import("vue").DefineComponent<{}, {
978
984
  }): void;
979
985
  setNavigationStyleOptionValue({ section, option, value, viewport, }: {
980
986
  section: "footer" | "header";
981
- option: "defaultBorderColor" | "selectedBorderColor" | "defaultTextStyle" | "defaultBackgroundColor" | "selectedTextColor" | "selectedBackgroundColor" | "iconColor" | "iconBackgroundColor";
987
+ option: "defaultBorderColor" | "selectedBorderColor" | "subNavBackgroundColor" | "defaultTextStyle" | "defaultBackgroundColor" | "selectedTextColor" | "selectedBackgroundColor" | "iconColor" | "iconBackgroundColor";
982
988
  value: any;
983
989
  viewport: import("@brand-page").ViewportsType;
984
990
  }): void;
@@ -387,7 +387,7 @@ export const useRichTextEditor = (model, props, emit, fontSettings, fontStyleDro
387
387
  const copyGlobalStyleSettings = (selectedTextStyle) => {
388
388
  const globalStyles = selectedTextStyle ?? selectedGlobalTextStyles.value?.style;
389
389
  if (globalStyles) {
390
- globalStyles.fontWeight && toggleBoldAll();
390
+ globalStyles.fontWeight === 'bold' && toggleBoldAll();
391
391
  globalStyles.fontStyle && toggleItalicAll();
392
392
  globalStyles.textDecoration?.includes('underline') &&
393
393
  toggleUnderlineAll();