@designcrowd/library.brand-page 6.0.6-tracker-1 → 6.0.6-undo-3

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 (93) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DD0OBnij.js → CreatedOnBrandCrowd-de-de-x7BcD7Sj.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DysrpsmM.js → CreatedOnBrandCrowd-en-us-CG-ThD_q.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-B6twGr9h.js → CreatedOnBrandCrowd-es-es-aab4_Re2.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-yxl0ih_4.js → CreatedOnBrandCrowd-fr-ca-Drl8X5uh.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-yxl0ih_4.js → CreatedOnBrandCrowd-fr-fr-Drl8X5uh.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-BtXDrIcx.js → CreatedOnBrandCrowd-pt-br-8Ib7T70i.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-BtXDrIcx.js → CreatedOnBrandCrowd-pt-pt-8Ib7T70i.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-ho_ROy1L.js → CreatedOnDcom-de-de-FJtydzc5.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-C91p9kls.js → CreatedOnDcom-en-us-BMiXru6P.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-B3FYmObE.js → CreatedOnDcom-es-es-B8Srdnku.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-D40m7fPx.js → CreatedOnDcom-fr-ca-tcXGiBNt.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-Cd57oYyc.js → CreatedOnDcom-fr-fr-nE1cuUEU.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-Du57mWxG.js → CreatedOnDcom-pt-br-DxCCXCg8.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-fYoPZWwr.js → CreatedOnDcom-pt-pt-Csabip9G.js} +1 -1
  15. package/lib/src/brand-page/utils/logo.util.d.ts +14 -0
  16. package/lib/src/brand-page/utils/logo.util.js +19 -0
  17. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +1 -1
  18. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +2 -2
  19. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +1 -1
  20. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +1 -1
  21. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +3 -3
  22. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +1 -1
  23. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +1 -1
  24. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +2 -2
  25. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +1 -1
  26. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +1 -1
  27. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +1 -1
  28. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +25 -4
  29. package/lib/src/brand-page-maker/composables/useUndoRedoFlag.d.ts +6 -7
  30. package/lib/src/brand-page-maker/composables/useUndoRedoFlag.js +7 -12
  31. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +1 -1
  32. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +12 -7
  33. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +7 -1
  34. package/lib/src/brand-page-maker/stores/history/history-store.js +11 -1
  35. package/lib/src/index.mjs +83 -84
  36. package/lib/src/{lib-lMNy66QO.js → lib-C_UlYMJy.js} +32835 -32458
  37. package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +13 -0
  38. package/lib/src/metadata-builder/builders/reorder-pages-builder.js +49 -0
  39. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +5 -0
  40. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +29 -0
  41. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +3 -3
  42. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -2
  43. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +1 -1
  44. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +2 -2
  45. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +5 -0
  46. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +1 -1
  47. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -67
  48. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.js +4 -6
  49. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +5 -0
  50. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +5 -0
  51. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +2 -0
  52. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +19 -0
  53. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1 -0
  54. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +18 -7
  55. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +5 -0
  56. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +5 -0
  57. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +5 -0
  58. package/lib/src/shared/content-settings/models.d.ts +11 -0
  59. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +1 -1
  60. package/lib/src/shared/content-settings/store/content-settings-store.js +15 -1
  61. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +1 -1
  62. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -2
  63. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +2 -2
  64. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +1 -1
  65. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +1 -1
  66. package/package.json +1 -16
  67. package/src/brand-page/utils/logo.util.test.ts +54 -1
  68. package/src/brand-page/utils/logo.util.ts +23 -0
  69. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +1 -1
  70. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +26 -5
  71. package/src/brand-page-maker/composables/useUndoRedoFlag.ts +7 -13
  72. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +53 -0
  73. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +13 -16
  74. package/src/brand-page-maker/stores/history/history-store.test.ts +51 -0
  75. package/src/brand-page-maker/stores/history/history-store.ts +19 -0
  76. package/src/metadata-builder/builders/reorder-pages-builder.ts +80 -0
  77. package/src/shared/content-settings/components/GenericTextInput.mixin.test.ts +119 -0
  78. package/src/shared/content-settings/components/GenericTextInput.mixin.ts +34 -0
  79. package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +10 -5
  80. package/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.ts +4 -7
  81. package/src/shared/content-settings/components/text-field/TextField.vue +2 -1
  82. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.test.ts +149 -0
  83. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +26 -0
  84. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +19 -11
  85. package/src/shared/content-settings/components/textarea-field/TextareaField.vue +2 -1
  86. package/src/shared/content-settings/models.ts +11 -0
  87. package/src/shared/content-settings/store/content-settings-store.test.ts +110 -0
  88. package/src/shared/content-settings/store/content-settings-store.ts +17 -0
  89. package/lib/src/tracker.d.ts +0 -2
  90. package/lib/src/tracker.js +0 -12
  91. package/lib/src/tracker.mjs +0 -12
  92. package/lib/src/useEventTracker-DmQ6AkNn.js +0 -356
  93. package/src/tracker.ts +0 -28
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as t } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as e } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as e } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as e } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as e } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as e } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as M } from "./lib-C_UlYMJy.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-lMNy66QO.js";
2
+ import { _ as M } from "./lib-C_UlYMJy.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -30,6 +30,20 @@ export declare const calculateOptimizedLogoDimensions: (logoData: {
30
30
  width: string;
31
31
  height: string;
32
32
  };
33
+ /**
34
+ * Resolves the "current" logo image from a brand-page MODEL (the raw,
35
+ * deserialized shape — not the live stores, whose contents are wrapped in
36
+ * `settings.content`).
37
+ *
38
+ * Brand-site keeps its logo in the page header; brand-page and brand-contact
39
+ * keep it as a logo CONTENT block on the home page — the same `isBrandSite ?
40
+ * header : content` split the logo-settings store getters/setter use. This is
41
+ * the single source of truth for model-level logo reads: initial load and
42
+ * history-restore both call it so the two paths can't drift. They previously
43
+ * hard-coded `=== brandPage`, which silently excluded brand-contact and read a
44
+ * stale header logo on undo.
45
+ */
46
+ export declare const getLogoImageFromModel: (model: BrandPageModel) => LogoImageModel | undefined;
33
47
  export declare const recalculateLogoContentDimensions: (pageData: any, editableLogoVariations: {
34
48
  variationId: number;
35
49
  width: number;
@@ -225,6 +225,25 @@ export const calculateOptimizedLogoDimensions = (logoData, currentWidth, current
225
225
  }
226
226
  return { width: currentWidth, height: currentHeight };
227
227
  };
228
+ /**
229
+ * Resolves the "current" logo image from a brand-page MODEL (the raw,
230
+ * deserialized shape — not the live stores, whose contents are wrapped in
231
+ * `settings.content`).
232
+ *
233
+ * Brand-site keeps its logo in the page header; brand-page and brand-contact
234
+ * keep it as a logo CONTENT block on the home page — the same `isBrandSite ?
235
+ * header : content` split the logo-settings store getters/setter use. This is
236
+ * the single source of truth for model-level logo reads: initial load and
237
+ * history-restore both call it so the two paths can't drift. They previously
238
+ * hard-coded `=== brandPage`, which silently excluded brand-contact and read a
239
+ * stale header logo on undo.
240
+ */
241
+ export const getLogoImageFromModel = (model) => {
242
+ if (model.brandPageType === BRAND_PAGE_TYPES.brandSite) {
243
+ return model.pageHeaderDesktop?.logoImage;
244
+ }
245
+ return model.pages?.[0]?.contents?.find(isLogoContent)?.logoImage;
246
+ };
228
247
  export const recalculateLogoContentDimensions = async (pageData, editableLogoVariations, logoImage, isPrePurchase) => {
229
248
  try {
230
249
  let logoData;
@@ -118,7 +118,7 @@ declare const _default: import("vue").DefineComponent<{}, {
118
118
  content: TContent;
119
119
  }>(payload: P): Promise<void>;
120
120
  _captureTemplateSwitchIfEnabled(): void;
121
- applyHistorySnapshot(snapshot: import("@brand-page/models").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
121
+ applyHistorySnapshot(snapshot: import("@brand-page/models").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
122
122
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page/models").BrandPageModel, logoEditsStr?: string): Promise<void>;
123
123
  _navigateToActivePage(activePageId?: string): void;
124
124
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page/models").BrandPageModel): void;
@@ -163,7 +163,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
163
163
  content: TContent;
164
164
  }>(payload: P): Promise<void>;
165
165
  _captureTemplateSwitchIfEnabled(): void;
166
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
166
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
167
167
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
168
168
  _navigateToActivePage(activePageId?: string): void;
169
169
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -843,7 +843,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
843
843
  pushMode(item: import("@shared/content-settings/store").ContentSettingsModeStackItem): void;
844
844
  resetMode(): void;
845
845
  updateItemValue(payload: import("../../../shared/content-settings/models").UpdateItemValuePayload<unknown>): void;
846
- updateMultipleItemValues({ id, name, value, }: import("../../../shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
846
+ updateMultipleItemValues({ id, name, value, isHydrationWrite, }: import("../../../shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
847
847
  updateTextStyleType({ id, name, value, }: import("../../../shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
848
848
  updateTextStyles({ id, name, value, }: import("../../../shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
849
849
  getTextStyles({ id, name }: {
@@ -196,7 +196,7 @@ export default defineComponent({
196
196
  this.brandPageMakerStore.setIsBrandPageLoaded(true);
197
197
  // Capture baseline for undo/redo when the feature is active for this
198
198
  // session — see useUndoRedoFlag.ts for the gate (LaunchDarkly flag +
199
- // brand-site + non-admin maker).
199
+ // non-admin maker; all three brands).
200
200
  if (useUndoRedoFlag().value) {
201
201
  useHistoryStore().captureBaseline();
202
202
  }
@@ -107,7 +107,7 @@ declare const _default: import("vue").DefineComponent<{}, {
107
107
  content: TContent;
108
108
  }>(payload: P): Promise<void>;
109
109
  _captureTemplateSwitchIfEnabled(): void;
110
- applyHistorySnapshot(snapshot: import("../../../lib").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
110
+ applyHistorySnapshot(snapshot: import("../../../lib").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
111
111
  _syncLogoSettingsFromSnapshot(snapshot: import("../../../lib").BrandPageModel, logoEditsStr?: string): Promise<void>;
112
112
  _navigateToActivePage(activePageId?: string): void;
113
113
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../lib").BrandPageModel): void;
@@ -433,7 +433,7 @@ declare const _default: import("vue").DefineComponent<{}, {
433
433
  pushMode(item: import("@shared/content-settings/store").ContentSettingsModeStackItem): void;
434
434
  resetMode(): void;
435
435
  updateItemValue(payload: import("@shared/content-settings/models").UpdateItemValuePayload<unknown>): void;
436
- updateMultipleItemValues({ id, name, value, }: import("@shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
436
+ updateMultipleItemValues({ id, name, value, isHydrationWrite, }: import("@shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
437
437
  updateTextStyleType({ id, name, value, }: import("@shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
438
438
  updateTextStyles({ id, name, value, }: import("@shared/content-settings/models").UpdateMultipleItemValuesPayload<any>): void;
439
439
  getTextStyles({ id, name }: {
@@ -626,7 +626,7 @@ declare const _default: import("vue").DefineComponent<{}, {
626
626
  content: TContent;
627
627
  }>(payload: P): Promise<void>;
628
628
  _captureTemplateSwitchIfEnabled(): void;
629
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
629
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
630
630
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
631
631
  _navigateToActivePage(activePageId?: string): void;
632
632
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -1250,7 +1250,7 @@ declare const _default: import("vue").DefineComponent<{}, {
1250
1250
  reset: () => void;
1251
1251
  getCurrentSizeBytes: () => number;
1252
1252
  getCurrentEntryCount: () => number;
1253
- }, "reset" | "undo" | "redo" | "captureBaseline" | "capture" | "captureTemplateSwitch" | "captureAiChangeset" | "mergeNextMutation" | "getCurrentSizeBytes" | "getCurrentEntryCount">>;
1253
+ }, "reset" | "captureBaseline" | "capture" | "captureTemplateSwitch" | "captureAiChangeset" | "mergeNextMutation" | "undo" | "redo" | "getCurrentSizeBytes" | "getCurrentEntryCount">>;
1254
1254
  }, {
1255
1255
  isDraggingContent: boolean;
1256
1256
  isContentSelected: boolean;
@@ -113,7 +113,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
113
113
  content: TContent;
114
114
  }>(payload: P): Promise<void>;
115
115
  _captureTemplateSwitchIfEnabled(): void;
116
- applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
116
+ applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
117
117
  _syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
118
118
  _navigateToActivePage(activePageId?: string): void;
119
119
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
@@ -93,8 +93,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
93
93
  default: undefined;
94
94
  };
95
95
  }>> & Readonly<{}>, {
96
- deviceMode: "desktop" | "mobile";
97
96
  runtimeEnvironment: string;
97
+ deviceMode: "desktop" | "mobile";
98
98
  }, {}, {
99
99
  HelloBar: any;
100
100
  BrandPageMakerPage: import("vue").DefineComponent<{}, {}, any>;
@@ -391,7 +391,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
391
391
  content: TContent;
392
392
  }>(payload: P): Promise<void>;
393
393
  _captureTemplateSwitchIfEnabled(): void;
394
- applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
394
+ applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
395
395
  _syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
396
396
  _navigateToActivePage(activePageId?: string): void;
397
397
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
@@ -481,8 +481,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
481
481
  "onUpdate-settings"?: ((...args: any[]) => any) | undefined;
482
482
  }>, {
483
483
  pageTitle: string;
484
- brandPageType: string;
485
484
  designDraftToken: string;
485
+ brandPageType: string;
486
486
  pageDescription: string;
487
487
  isMaker: boolean;
488
488
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -392,7 +392,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
392
392
  content: TContent;
393
393
  }>(payload: P): Promise<void>;
394
394
  _captureTemplateSwitchIfEnabled(): void;
395
- applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
395
+ applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
396
396
  _syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
397
397
  _navigateToActivePage(activePageId?: string): void;
398
398
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
@@ -123,7 +123,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
123
123
  content: TContent;
124
124
  }>(payload: P): Promise<void>;
125
125
  _captureTemplateSwitchIfEnabled(): void;
126
- applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
126
+ applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
127
127
  _syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
128
128
  _navigateToActivePage(activePageId?: string): void;
129
129
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
@@ -441,7 +441,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
441
441
  content: TContent;
442
442
  }>(payload: P): Promise<void>;
443
443
  _captureTemplateSwitchIfEnabled(): void;
444
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
444
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
445
445
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
446
446
  _navigateToActivePage(activePageId?: string): void;
447
447
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -74,9 +74,6 @@ export const useExternalRichTextEditor = () => {
74
74
  };
75
75
  export const useRichTextEditor = (model, props, emit, fontSettings, fontStyleDropdownRef, selectedGlobalTextStyles, onSelectTextStyleType, updateRichTextEditor, textStyleTypeOptions, markedText, isHyperlinkPopupOpen, selectedLinkTypeValue) => {
76
76
  const historyStore = useHistoryStore();
77
- // TipTap rehydrates and writes back canonical HTML on mount — fold
78
- // that into the current head instead of pushing a phantom entry.
79
- historyStore.mergeNextMutation();
80
77
  const editor = new Editor({
81
78
  content: model.value ?? '',
82
79
  editable: !props.readOnly,
@@ -257,6 +254,13 @@ export const useRichTextEditor = (model, props, emit, fontSettings, fontStyleDro
257
254
  }
258
255
  });
259
256
  editor.on('transaction', ({ transaction }) => {
257
+ // Style detection only makes sense for user styling — an unfocused
258
+ // editor's transactions are mount rehydration / programmatic setContent
259
+ // churn, and clearing textStyleType from those would push a phantom
260
+ // style write into the model (BP-5810 family).
261
+ if (!editor.isFocused) {
262
+ return;
263
+ }
260
264
  if (isStyleChanged(transaction) && props.styles.textStyleType) {
261
265
  onSelectTextStyleType({
262
266
  label: 'None',
@@ -266,7 +270,24 @@ export const useRichTextEditor = (model, props, emit, fontSettings, fontStyleDro
266
270
  // Update model when editor content changes
267
271
  editor.on('update', () => {
268
272
  const sanitizedData = sanitiseClientSideRTE(editor.getHTML());
269
- emit('update:modelValue', sanitizedData.sanitizedHtml);
273
+ // An update fired while the editor is unfocused is TipTap rewriting the
274
+ // model back into its canonical HTML during mount rehydration or a
275
+ // programmatic setContent — not a user edit. Tag the emit so the write
276
+ // folds into the current undo head instead of pushing a phantom entry
277
+ // (BP-5810). The flag travels WITH the value through the debounced
278
+ // field → store chain and arms the history merge at the moment of the
279
+ // store write — arming here at emit time would lapse before the
280
+ // debounce fires. Genuine edits happen while focused and commit
281
+ // normally.
282
+ //
283
+ // Known limitation: a programmatic toolbar command run on an editor the
284
+ // user hasn't focused yet would also merge (losing that undo step). Today
285
+ // the RTE only mounts inside an already-open settings drawer and the user
286
+ // focuses it before formatting, so this doesn't occur — revisit if a
287
+ // consumer ever drives toolbar actions on an unfocused editor.
288
+ emit('update:modelValue', sanitizedData.sanitizedHtml, {
289
+ isHydration: !editor.isFocused,
290
+ });
270
291
  });
271
292
  editor.on('selectionUpdate', () => {
272
293
  // Skip while a history snapshot is being applied — `setContent` fires
@@ -1,16 +1,15 @@
1
1
  import { type ComputedRef } from 'vue';
2
2
  /**
3
- * Returns whether undo/redo is active for the current maker session. All
4
- * three conditions must hold:
3
+ * Returns whether undo/redo is active for the current maker session. Both
4
+ * conditions must hold:
5
5
  *
6
6
  * 1. `userStore.features.canUseUndoRedo` is true. The flag is populated by
7
7
  * the consumer (BrandCrowd.Net / web-renderer) via the
8
8
  * `WebsiteDesignUserFeatures.CanUseUndoRedo` boolean on the ViewModel —
9
- * same precedent as RichTextEditor / GettyVideos / AITextGenerator.
10
- * 2. The maker is a brand-site (Website Maker). V1 scope is brand-site
11
- * only; brand-page (single-page profile) and brand-contact (vCard) are
12
- * out of scope.
13
- * 3. The session is NOT in admin-maker mode (`userStore.isAdmin`). The
9
+ * same precedent as RichTextEditor / GettyVideos / AITextGenerator. The
10
+ * one flag governs all three brands (brand-site, brand-page,
11
+ * brand-contact) there is no per-brand gating.
12
+ * 2. The session is NOT in admin-maker mode (`userStore.isAdmin`). The
14
13
  * admin maker uses the same components but a different editing flow
15
14
  * (template authoring) where undo/redo is out of scope.
16
15
  */
@@ -1,25 +1,20 @@
1
1
  import { computed } from 'vue';
2
2
  import { useBrandPageMakerUserStore } from '@brand-page-maker/stores/user';
3
- import { useBrandPageMakerStore } from '@brand-page-maker/stores/brandpage-maker/brandpage-maker-store';
4
3
  /**
5
- * Returns whether undo/redo is active for the current maker session. All
6
- * three conditions must hold:
4
+ * Returns whether undo/redo is active for the current maker session. Both
5
+ * conditions must hold:
7
6
  *
8
7
  * 1. `userStore.features.canUseUndoRedo` is true. The flag is populated by
9
8
  * the consumer (BrandCrowd.Net / web-renderer) via the
10
9
  * `WebsiteDesignUserFeatures.CanUseUndoRedo` boolean on the ViewModel —
11
- * same precedent as RichTextEditor / GettyVideos / AITextGenerator.
12
- * 2. The maker is a brand-site (Website Maker). V1 scope is brand-site
13
- * only; brand-page (single-page profile) and brand-contact (vCard) are
14
- * out of scope.
15
- * 3. The session is NOT in admin-maker mode (`userStore.isAdmin`). The
10
+ * same precedent as RichTextEditor / GettyVideos / AITextGenerator. The
11
+ * one flag governs all three brands (brand-site, brand-page,
12
+ * brand-contact) there is no per-brand gating.
13
+ * 2. The session is NOT in admin-maker mode (`userStore.isAdmin`). The
16
14
  * admin maker uses the same components but a different editing flow
17
15
  * (template authoring) where undo/redo is out of scope.
18
16
  */
19
17
  export function useUndoRedoFlag() {
20
18
  const userStore = useBrandPageMakerUserStore();
21
- const brandPageMakerStore = useBrandPageMakerStore();
22
- return computed(() => userStore.features.canUseUndoRedo &&
23
- brandPageMakerStore.isBrandSite &&
24
- !userStore.isAdmin);
19
+ return computed(() => userStore.features.canUseUndoRedo && !userStore.isAdmin);
25
20
  }
@@ -211,7 +211,7 @@ export declare const useBrandPageMakerStore: import("pinia").StoreDefinition<"br
211
211
  * feature flag is on — see `BrandPageMaker.mixin.ts`).
212
212
  */
213
213
  _captureTemplateSwitchIfEnabled(): void;
214
- applyHistorySnapshot(snapshot: BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
214
+ applyHistorySnapshot(snapshot: BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
215
215
  _syncLogoSettingsFromSnapshot(snapshot: BrandPageModel, logoEditsStr?: string): Promise<void>;
216
216
  /**
217
217
  * Restore the active page after a history apply. The id passed in is
@@ -494,7 +494,7 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
494
494
  return;
495
495
  historyStore.captureTemplateSwitch();
496
496
  },
497
- async applyHistorySnapshot(snapshot, activePageId, logoEditsStr) {
497
+ async applyHistorySnapshot(snapshot, activePageId, logoEditsStr, selectedTemplateId) {
498
498
  const styleSettingsStore = useUiStyleSettingsStore();
499
499
  const navigationStyleSettingsStore = useUiNavigationStyleSettingsStore();
500
500
  const backgroundSettingsStore = useUiBackgroundSettingsStore();
@@ -574,6 +574,15 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
574
574
  this.ogDescription = snapshot.ogDescription;
575
575
  this.cookieOptions = snapshot.cookieOptions;
576
576
  this.saveContactSettings = snapshot.saveContactSettings;
577
+ // 7b. Restore the selected-template pointer that drives the templates
578
+ // sidebar highlight. It's a UI pointer, not part of the persisted
579
+ // model, so it rides along as a history-entry sidecar (like
580
+ // `activePageId`). Its watchers only reset scroll position (no
581
+ // template re-application), so setting it here is safe during apply.
582
+ // (BP-5813)
583
+ if (selectedTemplateId !== undefined) {
584
+ this.setSelectedTemplateId({ templateId: selectedTemplateId });
585
+ }
577
586
  // 8. Re-sync the logo-settings sidebar's `selectedLogoImage` from the
578
587
  // restored header logo. The preview rehydrates via the page contents,
579
588
  // but `uiLogoSettings` holds its own copy that drives the sidebar
@@ -622,9 +631,7 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
622
631
  console.error('brandpage-maker-store: failed to restore logoEdits', error);
623
632
  }
624
633
  }
625
- const logoImage = snapshot.brandPageType === BRAND_PAGE_TYPES.default
626
- ? snapshot.pages?.[0]?.contents?.find((c) => c.type === 'logo')?.logoImage
627
- : snapshot.pageHeaderDesktop?.logoImage;
634
+ const logoImage = logoUtil.getLogoImageFromModel(snapshot);
628
635
  if (!logoImage)
629
636
  return;
630
637
  logoSettingsStore.setState({
@@ -848,9 +855,7 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
848
855
  this.setBrandPageType({
849
856
  brandPageType: _brandPageType,
850
857
  });
851
- let logoImage = brandPageModel.brandPageType === BRAND_PAGE_TYPES.default
852
- ? brandPageModel.pages?.[0].contents.find((c) => c.type === 'logo')?.logoImage
853
- : brandPageModel.pageHeaderDesktop?.logoImage;
858
+ let logoImage = logoUtil.getLogoImageFromModel(brandPageModel);
854
859
  if (!logoImage?.logoDraftToken) {
855
860
  logoImage = logoUtil.safeGetLogoImageFromLogoImageUrl(logoVariationImageUrls[0]);
856
861
  }
@@ -16,6 +16,12 @@ export interface HistoryEntry {
16
16
  activePageId: string;
17
17
  /** JSON-stringified `editableLogoStore.logoEdits`. Undefined if logo tab never opened. */
18
18
  logoEdits?: string;
19
+ /**
20
+ * Selected template id at capture time — drives the templates sidebar
21
+ * highlight. `false` when no template is selected. Sidecar to
22
+ * `brandPageData` (not part of the persisted model), like `activePageId`.
23
+ */
24
+ selectedTemplateId?: string | false;
19
25
  }
20
26
  export declare const useHistoryStore: import("pinia").StoreDefinition<"history", Pick<{
21
27
  entries: import("vue").ShallowRef<HistoryEntry[], HistoryEntry[]>;
@@ -83,4 +89,4 @@ export declare const useHistoryStore: import("pinia").StoreDefinition<"history",
83
89
  reset: () => void;
84
90
  getCurrentSizeBytes: () => number;
85
91
  getCurrentEntryCount: () => number;
86
- }, "reset" | "undo" | "redo" | "captureBaseline" | "capture" | "captureTemplateSwitch" | "captureAiChangeset" | "mergeNextMutation" | "getCurrentSizeBytes" | "getCurrentEntryCount">>;
92
+ }, "reset" | "captureBaseline" | "capture" | "captureTemplateSwitch" | "captureAiChangeset" | "mergeNextMutation" | "undo" | "redo" | "getCurrentSizeBytes" | "getCurrentEntryCount">>;
@@ -97,6 +97,9 @@ export const useHistoryStore = defineStore('history', () => {
97
97
  function getCurrentActivePageId() {
98
98
  return usePageNavigationStore().activePageId ?? '';
99
99
  }
100
+ function getCurrentSelectedTemplateId() {
101
+ return useBrandPageMakerStore().selectedTemplateId;
102
+ }
100
103
  function serializeCurrentLogoEdits() {
101
104
  try {
102
105
  const editableLogoStore = useUiEditableLogoStore();
@@ -150,6 +153,7 @@ export const useHistoryStore = defineStore('history', () => {
150
153
  sizeBytes: args.snapshot.length,
151
154
  activePageId: args.activePageId,
152
155
  logoEdits: args.logoEdits,
156
+ selectedTemplateId: args.selectedTemplateId,
153
157
  };
154
158
  // FR-11: truncate redo tail, then append.
155
159
  const next = entries.value.slice(0, currentIndex.value + 1);
@@ -209,6 +213,7 @@ export const useHistoryStore = defineStore('history', () => {
209
213
  return;
210
214
  const activePageId = getCurrentActivePageId();
211
215
  const logoEdits = serializeCurrentLogoEdits();
216
+ const selectedTemplateId = getCurrentSelectedTemplateId();
212
217
  // Settle window: fold post-init reactive cascades back into the
213
218
  // baseline so undo doesn't light up before the user has done
214
219
  // anything.
@@ -228,6 +233,7 @@ export const useHistoryStore = defineStore('history', () => {
228
233
  sizeBytes: snapshot.length,
229
234
  activePageId,
230
235
  logoEdits,
236
+ selectedTemplateId,
231
237
  },
232
238
  ];
233
239
  return;
@@ -241,6 +247,7 @@ export const useHistoryStore = defineStore('history', () => {
241
247
  sizeBytes: snapshot.length,
242
248
  activePageId,
243
249
  logoEdits,
250
+ selectedTemplateId,
244
251
  };
245
252
  entries.value = next;
246
253
  return;
@@ -251,6 +258,7 @@ export const useHistoryStore = defineStore('history', () => {
251
258
  actor: 'user',
252
259
  activePageId,
253
260
  logoEdits,
261
+ selectedTemplateId,
254
262
  });
255
263
  };
256
264
  // Monotonic — first mutation arms; subsequent ones inside the window
@@ -299,6 +307,7 @@ export const useHistoryStore = defineStore('history', () => {
299
307
  sizeBytes: snapshot.length,
300
308
  activePageId: getCurrentActivePageId(),
301
309
  logoEdits: serializeCurrentLogoEdits(),
310
+ selectedTemplateId: getCurrentSelectedTemplateId(),
302
311
  },
303
312
  ];
304
313
  currentIndex.value = 0;
@@ -318,6 +327,7 @@ export const useHistoryStore = defineStore('history', () => {
318
327
  snapshot,
319
328
  activePageId: getCurrentActivePageId(),
320
329
  logoEdits: serializeCurrentLogoEdits(),
330
+ selectedTemplateId: getCurrentSelectedTemplateId(),
321
331
  ...args,
322
332
  });
323
333
  }
@@ -393,7 +403,7 @@ export const useHistoryStore = defineStore('history', () => {
393
403
  pendingTimerIsMerge = false;
394
404
  cancelPendingAutoCapture();
395
405
  try {
396
- await brandPageMakerStore.applyHistorySnapshot(snapshot, resolvedActivePageId, targetEntry?.logoEdits);
406
+ await brandPageMakerStore.applyHistorySnapshot(snapshot, resolvedActivePageId, targetEntry?.logoEdits, targetEntry?.selectedTemplateId);
397
407
  }
398
408
  finally {
399
409
  isApplyingSnapshot.value = false;