@designcrowd/library.brand-page 6.0.17 → 6.0.18-single-h1-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 (101) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-CRuM9pwt.js → CreatedOnBrandCrowd-de-de-DfogbXGp.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DiV7Qndt.js → CreatedOnBrandCrowd-en-us-BMLmkiYc.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-p3wHaNxy.js → CreatedOnBrandCrowd-es-es-Uk9iK_0j.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-lBe3GAaV.js → CreatedOnBrandCrowd-fr-ca-Cy51ZgX0.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-lBe3GAaV.js → CreatedOnBrandCrowd-fr-fr-Cy51ZgX0.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CYdNvtj_.js → CreatedOnBrandCrowd-pt-br-CEXgWjzj.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-CYdNvtj_.js → CreatedOnBrandCrowd-pt-pt-CEXgWjzj.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CkkOK8P7.js → CreatedOnDcom-de-de-QLEevsbN.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-vj6FbDx4.js → CreatedOnDcom-en-us-z1AQXwpB.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CY73pZR2.js → CreatedOnDcom-es-es-CRI1tyjM.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-D6tw2qnx.js → CreatedOnDcom-fr-ca-BvQdGFy0.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DbjyyrVQ.js → CreatedOnDcom-fr-fr-JzSzsXGi.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-C604XK7d.js → CreatedOnDcom-pt-br-CxE4X3lp.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-CSQ9xpbn.js → CreatedOnDcom-pt-pt-CPFY5hsH.js} +1 -1
  15. package/lib/src/brand-page/components/media/Media.mixin.d.ts +10 -1
  16. package/lib/src/brand-page/components/media/Media.mixin.js +13 -0
  17. package/lib/src/brand-page/components/page/Page.mixin.d.ts +5 -0
  18. package/lib/src/brand-page/components/page/Page.mixin.js +8 -1
  19. package/lib/src/brand-page/utils/index.d.ts +1 -0
  20. package/lib/src/brand-page/utils/index.js +1 -0
  21. package/lib/src/brand-page/utils/page-heading.util.d.ts +13 -0
  22. package/lib/src/brand-page/utils/page-heading.util.js +24 -0
  23. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -0
  24. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +5 -0
  25. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +1 -0
  26. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +1 -1
  27. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.js +4 -6
  28. package/lib/src/brand-page-maker/composables/useQuickLinkBarVisibility.d.ts +17 -0
  29. package/lib/src/brand-page-maker/composables/useQuickLinkBarVisibility.js +23 -0
  30. package/lib/src/{bundled-translations-Cbaxd_x-.js → bundled-translations-2HkRBbBD.js} +1 -1
  31. package/lib/src/{bundled-translations.de-DE-z4PUgnja.js → bundled-translations.de-DE-CL9ZEhU2.js} +1 -1
  32. package/lib/src/{bundled-translations.es-ES-sqDF-i7N.js → bundled-translations.es-ES-uj7Sliu0.js} +1 -1
  33. package/lib/src/{bundled-translations.fr-CA-CQvLC7Ws.js → bundled-translations.fr-CA-BMnBtr_w.js} +1 -1
  34. package/lib/src/{bundled-translations.fr-FR-BxL6wP_Y.js → bundled-translations.fr-FR-9PEZedzq.js} +1 -1
  35. package/lib/src/{bundled-translations.pt-BR-ByhGrCnc.js → bundled-translations.pt-BR-B3oNDkoe.js} +1 -1
  36. package/lib/src/{bundled-translations.pt-PT-DkyVsn4P.js → bundled-translations.pt-PT-DM7Vsf-h.js} +1 -1
  37. package/lib/src/bundles/bundled-translations.de-DE.json +2 -2
  38. package/lib/src/bundles/bundled-translations.es-ES.json +2 -2
  39. package/lib/src/bundles/bundled-translations.fr-CA.json +2 -2
  40. package/lib/src/bundles/bundled-translations.fr-FR.json +2 -2
  41. package/lib/src/bundles/bundled-translations.json +2 -2
  42. package/lib/src/bundles/bundled-translations.pt-BR.json +2 -2
  43. package/lib/src/bundles/bundled-translations.pt-PT.json +2 -2
  44. package/lib/src/css/library.brand-page-brandCrowd.min.css +152 -155
  45. package/lib/src/css/library.brand-page-brandPage.min.css +152 -155
  46. package/lib/src/css/library.brand-page-designCom.min.css +152 -155
  47. package/lib/src/css/library.brand-page-preview.min.css +152 -155
  48. package/lib/src/index.mjs +1 -1
  49. package/lib/src/{lib-A3BBQz0z.js → lib-B-AsdjHe.js} +12342 -12288
  50. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.js +6 -0
  51. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +1 -1
  52. package/package.json +1 -1
  53. package/src/brand-page/components/about-section/AboutSection.vue +1 -1
  54. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +11 -0
  55. package/src/brand-page/components/banner-section/BannerSection.vue +5 -5
  56. package/src/brand-page/components/booking-section/BookingSection.vue +1 -1
  57. package/src/brand-page/components/contact-form/ContactForm.vue +3 -3
  58. package/src/brand-page/components/mailing-list/MailingList.vue +1 -1
  59. package/src/brand-page/components/media/Media.mixin.ts +13 -0
  60. package/src/brand-page/components/media/Media.test.ts +65 -0
  61. package/src/brand-page/components/media/Media.vue +1 -1
  62. package/src/brand-page/components/page/Page.mixin.ts +8 -1
  63. package/src/brand-page/components/page/Page.vue +8 -0
  64. package/src/brand-page/components/page/Page.vue.test.ts +142 -0
  65. package/src/brand-page/components/payment/Payment.vue +1 -1
  66. package/src/brand-page/components/profile/Profile.vue +1 -1
  67. package/src/brand-page/components/social-links/SocialLinks.vue +1 -1
  68. package/src/brand-page/components/testimonial-section/TestimonialSection.vue +1 -1
  69. package/src/brand-page/components/text-media-section/TextMediaSection.vue +1 -1
  70. package/src/brand-page/components/text-wrapper/TextWrapper.vue +6 -1
  71. package/src/brand-page/utils/image.util.test.ts +25 -0
  72. package/src/brand-page/utils/index.ts +1 -0
  73. package/src/brand-page/utils/page-heading.util.test.ts +116 -0
  74. package/src/brand-page/utils/page-heading.util.ts +33 -0
  75. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +5 -0
  76. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +2 -2
  77. package/src/brand-page-maker/components/device/Device.vue +0 -1
  78. package/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.ts +4 -7
  79. package/src/brand-page-maker/composables/useQuickLinkBarVisibility.test.ts +81 -0
  80. package/src/brand-page-maker/composables/useQuickLinkBarVisibility.ts +25 -0
  81. package/src/bundles/bundled-translations.de-DE.json +2 -2
  82. package/src/bundles/bundled-translations.es-ES.json +2 -2
  83. package/src/bundles/bundled-translations.fr-CA.json +2 -2
  84. package/src/bundles/bundled-translations.fr-FR.json +2 -2
  85. package/src/bundles/bundled-translations.json +2 -2
  86. package/src/bundles/bundled-translations.pt-BR.json +2 -2
  87. package/src/bundles/bundled-translations.pt-PT.json +2 -2
  88. package/src/metadata-builder/builders/section-rules/banner-section.rules.ts +6 -0
  89. package/src/metadata-builder/parsers/section-tool-arguments.ts +7 -1
  90. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +13 -0
  91. package/src/shared/content-settings/components/content-settings/ContentSettings.vue +2 -1
  92. package/src/shared/content-settings/components/content-settings/ContentSettingsButton.vue +8 -6
  93. package/src/shared/content-settings/components/content-settings/i18n/content-settings.de-DE.json +2 -2
  94. package/src/shared/content-settings/components/content-settings/i18n/content-settings.es-ES.json +2 -2
  95. package/src/shared/content-settings/components/content-settings/i18n/content-settings.fr-CA.json +2 -2
  96. package/src/shared/content-settings/components/content-settings/i18n/content-settings.fr-FR.json +2 -2
  97. package/src/shared/content-settings/components/content-settings/i18n/content-settings.json +2 -2
  98. package/src/shared/content-settings/components/content-settings/i18n/content-settings.pt-BR.json +2 -2
  99. package/src/shared/content-settings/components/content-settings/i18n/content-settings.pt-PT.json +2 -2
  100. package/src/shared/page-settings/components/page-settings/PageElement.vue +1 -0
  101. package/src/shared/page-settings/components/page-settings/PageSettingMenu.vue +4 -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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as t } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as e } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as e } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as e } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as e } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as e } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as M } from "./lib-B-AsdjHe.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-A3BBQz0z.js";
2
+ import { _ as M } from "./lib-B-AsdjHe.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -68,7 +68,16 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
68
68
  }>, {}, {
69
69
  type: string | undefined;
70
70
  isImageBroken: boolean;
71
- }, {}, {
71
+ }, {
72
+ /**
73
+ * BP-5866: content images must never emit an empty `alt`. Reuses the
74
+ * shared alt fallback (author title → "{business}'s image" → "image") so
75
+ * a caller that passes no `alt-text` still renders descriptive text.
76
+ * Only consumed by the content `<FallbackImage>`; decorative/background
77
+ * images (rendered via `media`) and shapes never reach this path.
78
+ */
79
+ effectiveAltText(): string;
80
+ }, {
72
81
  onImageError(): void;
73
82
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
74
83
  mediaType: {
@@ -1,4 +1,5 @@
1
1
  import { defineComponent } from 'vue';
2
+ import { getImageAltText } from '@brand-page/utils';
2
3
  export default defineComponent({
3
4
  props: {
4
5
  mediaType: {
@@ -71,6 +72,18 @@ export default defineComponent({
71
72
  isImageBroken: false,
72
73
  };
73
74
  },
75
+ computed: {
76
+ /**
77
+ * BP-5866: content images must never emit an empty `alt`. Reuses the
78
+ * shared alt fallback (author title → "{business}'s image" → "image") so
79
+ * a caller that passes no `alt-text` still renders descriptive text.
80
+ * Only consumed by the content `<FallbackImage>`; decorative/background
81
+ * images (rendered via `media`) and shapes never reach this path.
82
+ */
83
+ effectiveAltText() {
84
+ return getImageAltText({ imageTitle: this.altText }, this.context);
85
+ },
86
+ },
74
87
  methods: {
75
88
  onImageError() {
76
89
  this.isImageBroken = true;
@@ -75,6 +75,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
75
75
  bpShowTopNavigationMobile(): boolean;
76
76
  bpShowTopNavigationDesktop(): boolean;
77
77
  slug(): string;
78
+ /**
79
+ * Text for the single page-level `<h1>` (BP-5866). Sourced from the
80
+ * business/site name + page name so it mirrors the SSR document `<title>`.
81
+ */
82
+ pageHeadingText(): string;
78
83
  shouldShowSaveContactWidget(): boolean;
79
84
  isPremiumSubscription(): boolean;
80
85
  shouldShowPopupBranding(): boolean;
@@ -1,6 +1,6 @@
1
1
  import { defineComponent } from 'vue';
2
2
  import { DEFAULT_FONT_FAMILY_KEY, FALLBACK_FONT_FAMILIES, FONT_FAMILY_CONFIGS, } from '../../constants';
3
- import { getSlugFromContext } from '@brand-page/utils';
3
+ import { getSlugFromContext, getPageHeadingText } from '@brand-page/utils';
4
4
  import { findNavItemByRelativePath } 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';
@@ -292,6 +292,13 @@ export default defineComponent({
292
292
  slug() {
293
293
  return getSlugFromContext(this.context);
294
294
  },
295
+ /**
296
+ * Text for the single page-level `<h1>` (BP-5866). Sourced from the
297
+ * business/site name + page name so it mirrors the SSR document `<title>`.
298
+ */
299
+ pageHeadingText() {
300
+ return getPageHeadingText(this.context);
301
+ },
295
302
  shouldShowSaveContactWidget() {
296
303
  try {
297
304
  if ((!this.context.isPreview &&
@@ -6,6 +6,7 @@ export * from './model.util';
6
6
  export * from './validation.util';
7
7
  export * from './payment.util';
8
8
  export * from './image.util';
9
+ export * from './page-heading.util';
9
10
  export * from './font-loader.util';
10
11
  export * from './aspect-ratio.util';
11
12
  export * from './context.util';
@@ -6,6 +6,7 @@ export * from './model.util';
6
6
  export * from './validation.util';
7
7
  export * from './payment.util';
8
8
  export * from './image.util';
9
+ export * from './page-heading.util';
9
10
  export * from './font-loader.util';
10
11
  export * from './aspect-ratio.util';
11
12
  export * from './context.util';
@@ -0,0 +1,13 @@
1
+ import type { BrandPageContext } from '../models';
2
+ /**
3
+ * Resolves the text for the single page-level `<h1>` a published site renders
4
+ * (BP-5866 — Bing rejected indexing because every section emitted its own
5
+ * `<h1>`; the page now owns exactly one).
6
+ *
7
+ * Mirrors the SSR `<title>` rule so the crawlable heading matches the document
8
+ * title: a sub-page reads `"{business} - {page}"`, while the home/root page
9
+ * reads just the business/site name — never the weak, non-descriptive literal
10
+ * "Home". Falls back to the page name, then the slug, when the business name
11
+ * is unset.
12
+ */
13
+ export declare const getPageHeadingText: (context: BrandPageContext) => string;
@@ -0,0 +1,24 @@
1
+ import { findNavItemByRelativePath } from './route.util';
2
+ /**
3
+ * Resolves the text for the single page-level `<h1>` a published site renders
4
+ * (BP-5866 — Bing rejected indexing because every section emitted its own
5
+ * `<h1>`; the page now owns exactly one).
6
+ *
7
+ * Mirrors the SSR `<title>` rule so the crawlable heading matches the document
8
+ * title: a sub-page reads `"{business} - {page}"`, while the home/root page
9
+ * reads just the business/site name — never the weak, non-descriptive literal
10
+ * "Home". Falls back to the page name, then the slug, when the business name
11
+ * is unset.
12
+ */
13
+ export const getPageHeadingText = (context) => {
14
+ const businessName = (context.pageTitle || '').trim();
15
+ const navItem = findNavItemByRelativePath(context.nav?.navItems || [], context.currentPageRelativePath || '');
16
+ const pageName = (navItem?.displayName || '').trim();
17
+ const isSubPage = Boolean(navItem && !navItem.isRoot && pageName);
18
+ if (businessName) {
19
+ return isSubPage ? `${businessName} - ${pageName}` : businessName;
20
+ }
21
+ // No business name: use the sub-page's name, else the slug — never the
22
+ // root page's own display name (usually the literal "Home").
23
+ return (isSubPage ? pageName : '') || context.brandPageSlug || '';
24
+ };
@@ -50,6 +50,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
50
50
  isSaving: import("vue").ComputedRef<boolean>;
51
51
  isPublishing: import("vue").ComputedRef<boolean>;
52
52
  isPublished: import("vue").ComputedRef<boolean>;
53
+ shouldShowQuickLinkBar: import("vue").ComputedRef<boolean>;
53
54
  isBrandPageOrIsBrandContact: import("vue").ComputedRef<boolean>;
54
55
  brandPageViewModel: import("vue").ComputedRef<import("@brand-page").BrandPageViewModel>;
55
56
  backUrl: import("vue").ComputedRef<string>;
@@ -13,6 +13,7 @@ import { UI_DEVICE_MODES, UI_SCREENSIZE_MODES, } from '@shared/models';
13
13
  import { useBrandPageMakerStore, useBrandPageMakerUserStore, useLocalisedRouteStore, useUiStore, useSnapshotStore, useVideoStore, } from '@brand-page-maker/stores';
14
14
  import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
15
15
  import { useUndoRedoFlag } from '@brand-page-maker/composables/useUndoRedoFlag';
16
+ import { useQuickLinkBarVisibility } from '@brand-page-maker/composables/useQuickLinkBarVisibility';
16
17
  import { useUiContentSettingsStore } from '@shared/content-settings/store';
17
18
  import { useUiTemplateSettingsStore } from '@shared/template-settings/store';
18
19
  import { useUiPageSettingsStore } from '@shared/page-settings/store';
@@ -73,6 +74,10 @@ export default defineComponent({
73
74
  isSaving: computed(() => brandPageMakerStore.isSaving),
74
75
  isPublishing: computed(() => brandPageMakerStore.isPublishing),
75
76
  isPublished: computed(() => brandPageMakerStore.isPublished),
77
+ // Whether the QuickLinkBar renders — used to offset the preview (Device)
78
+ // and SideBar clear of the fixed bar on mobile. Must match the bar's own
79
+ // render condition, so it shares the same predicate.
80
+ shouldShowQuickLinkBar: useQuickLinkBarVisibility(),
76
81
  isBrandPageOrIsBrandContact: computed(() => brandPageMakerStore.isBrandPageOrIsBrandContact),
77
82
  brandPageViewModel: computed(() => brandPageMakerStore.brandPageViewModel),
78
83
  backUrl: computed(() => localisedRouteStore.backToWebsiteManageUrlPath),
@@ -1347,6 +1347,7 @@ declare const _default: import("vue").DefineComponent<{}, {
1347
1347
  bpShowTopNavigationMobile(): boolean;
1348
1348
  bpShowTopNavigationDesktop(): boolean;
1349
1349
  slug(): string;
1350
+ pageHeadingText(): string;
1350
1351
  shouldShowSaveContactWidget(): boolean;
1351
1352
  isPremiumSubscription(): boolean;
1352
1353
  shouldShowPopupBranding(): boolean;
@@ -292,11 +292,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
292
292
  pushManageWebPageUnpublishClickEvent(): Promise<void>;
293
293
  }>;
294
294
  undoRedoEnabled: import("vue").ComputedRef<boolean>;
295
+ shouldShowBar: import("vue").ComputedRef<boolean>;
295
296
  }, {
296
297
  copied: boolean;
297
298
  }, {
298
299
  isPublished(): boolean;
299
- shouldShowBar(): boolean;
300
300
  brandPageUrl(): string;
301
301
  copyButtonLabel(): string;
302
302
  }, {
@@ -2,6 +2,7 @@ import { defineComponent } from 'vue';
2
2
  import { CUSTOM_DOMAIN_STATUSES } from '@brand-page-maker/constants';
3
3
  import { useBrandPageContainerStore, useEventManagerStore, } from '@brand-page-maker/stores';
4
4
  import { useUndoRedoFlag } from '@brand-page-maker/composables/useUndoRedoFlag';
5
+ import { useQuickLinkBarVisibility } from '@brand-page-maker/composables/useQuickLinkBarVisibility';
5
6
  import { quickLinkBarTr } from '@src/composables/useTranslate';
6
7
  export default defineComponent({
7
8
  props: {
@@ -19,6 +20,9 @@ export default defineComponent({
19
20
  brandPageContainerStore: useBrandPageContainerStore(),
20
21
  eventManagerStore: useEventManagerStore(),
21
22
  undoRedoEnabled: useUndoRedoFlag(),
23
+ // Single source of truth for whether the bar renders — shared with the
24
+ // layout components (Device, SideBar) that offset content clear of it.
25
+ shouldShowBar: useQuickLinkBarVisibility(),
22
26
  };
23
27
  },
24
28
  data() {
@@ -30,12 +34,6 @@ export default defineComponent({
30
34
  isPublished() {
31
35
  return this.brandPageContainerStore.isPublished;
32
36
  },
33
- // Only render the bar when at least one inner cluster has something to
34
- // show. Otherwise we'd render an empty white strip — e.g. on an
35
- // unpublished page with the undo flag off.
36
- shouldShowBar() {
37
- return Boolean(this.undoRedoEnabled) || this.isPublished;
38
- },
39
37
  brandPageUrl() {
40
38
  if (this.brandPageContainerStore.isCustomDomainEnabled &&
41
39
  this.brandPageContainerStore.customDomain &&
@@ -0,0 +1,17 @@
1
+ import { type ComputedRef } from 'vue';
2
+ /**
3
+ * Whether the QuickLinkBar is rendered in the maker.
4
+ *
5
+ * The bar shows when at least one of its inner clusters has something to
6
+ * display: the undo/redo controls (flag on, non-admin — see
7
+ * {@link useUndoRedoFlag}) OR the published-URL cluster (page published).
8
+ *
9
+ * This is the single source of truth shared by the bar itself
10
+ * (`QuickLinkBar`) and the layout components that offset their content to sit
11
+ * clear of the fixed bar on mobile (`Device`, `SideBar`). Keeping the offset
12
+ * bound to the same predicate the bar renders on prevents the two from
13
+ * drifting — a drift where the bar showed for the undo/redo reason but the
14
+ * offset only accounted for the published reason caused the bar to overlap
15
+ * the mobile preview.
16
+ */
17
+ export declare function useQuickLinkBarVisibility(): ComputedRef<boolean>;
@@ -0,0 +1,23 @@
1
+ import { computed } from 'vue';
2
+ import { useBrandPageContainerStore } from '@brand-page-maker/stores';
3
+ import { useUndoRedoFlag } from './useUndoRedoFlag';
4
+ /**
5
+ * Whether the QuickLinkBar is rendered in the maker.
6
+ *
7
+ * The bar shows when at least one of its inner clusters has something to
8
+ * display: the undo/redo controls (flag on, non-admin — see
9
+ * {@link useUndoRedoFlag}) OR the published-URL cluster (page published).
10
+ *
11
+ * This is the single source of truth shared by the bar itself
12
+ * (`QuickLinkBar`) and the layout components that offset their content to sit
13
+ * clear of the fixed bar on mobile (`Device`, `SideBar`). Keeping the offset
14
+ * bound to the same predicate the bar renders on prevents the two from
15
+ * drifting — a drift where the bar showed for the undo/redo reason but the
16
+ * offset only accounted for the published reason caused the bar to overlap
17
+ * the mobile preview.
18
+ */
19
+ export function useQuickLinkBarVisibility() {
20
+ const containerStore = useBrandPageContainerStore();
21
+ const undoRedoEnabled = useUndoRedoFlag();
22
+ return computed(() => undoRedoEnabled.value || containerStore.isPublished);
23
+ }