@designcrowd/library.brand-page 6.1.15 → 6.1.16
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.
- package/lib/src/{CreatedOnBrandCrowd-de-de-a7cNT5AA.js → CreatedOnBrandCrowd-de-de-CmNhDMIf.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-BpZ89I9T.js → CreatedOnBrandCrowd-en-us-DgplxxWa.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-Db0Ot-mQ.js → CreatedOnBrandCrowd-es-es-DFdhFOa1.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-Mbd7Hhxh.js → CreatedOnBrandCrowd-fr-ca-DjLCWBLB.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-Mbd7Hhxh.js → CreatedOnBrandCrowd-fr-fr-DjLCWBLB.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-B98aoT6y.js → CreatedOnBrandCrowd-pt-br-CI2XD0OS.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-B98aoT6y.js → CreatedOnBrandCrowd-pt-pt-CI2XD0OS.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-b_GUYmhX.js → CreatedOnDcom-de-de-CkLkBztx.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BtTIwekM.js → CreatedOnDcom-en-us-frnxBJJv.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-WbhHNEg-.js → CreatedOnDcom-es-es-CrqgiERj.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-DnQOAvS5.js → CreatedOnDcom-fr-ca-CPoEcusj.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-D7Q-aBNQ.js → CreatedOnDcom-fr-fr-BqrRH3dV.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-DnqkF_ve.js → CreatedOnDcom-pt-br-CpbVi3Sw.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-DNyyHF1o.js → CreatedOnDcom-pt-pt-s0XZ3c7y.js} +1 -1
- package/lib/src/brand-page/models/index.d.ts +4 -1
- package/lib/src/brand-page/models/index.js +4 -1
- package/lib/src/brand-page/utils/view-model.util.js +18 -2
- package/lib/src/brand-page/view-models.d.ts +2 -1
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +18 -0
- package/lib/src/{bundled-translations-BiFAlQdC.js → bundled-translations-B2q5GWTQ.js} +1 -1
- package/lib/src/{bundled-translations.de-DE-DuRWnOP-.js → bundled-translations.de-DE-FhH2H_rd.js} +5 -5
- package/lib/src/{bundled-translations.es-ES-CokHdZtW.js → bundled-translations.es-ES-_ZExxMi7.js} +5 -5
- package/lib/src/{bundled-translations.fr-CA-CJcMmubA.js → bundled-translations.fr-CA-Tg-ODIiC.js} +1 -1
- package/lib/src/{bundled-translations.fr-FR-DYPup8fJ.js → bundled-translations.fr-FR-C0sU51Mz.js} +1 -1
- package/lib/src/{bundled-translations.pt-BR-GSsp1kuV.js → bundled-translations.pt-BR-MYFIhA4u.js} +9 -9
- package/lib/src/{bundled-translations.pt-PT-DbkY8UQ3.js → bundled-translations.pt-PT-DeUBSzCB.js} +9 -9
- package/lib/src/bundles/bundled-translations.de-DE.json +1 -0
- package/lib/src/bundles/bundled-translations.es-ES.json +1 -0
- package/lib/src/bundles/bundled-translations.fr-CA.json +1 -0
- package/lib/src/bundles/bundled-translations.fr-FR.json +1 -0
- package/lib/src/bundles/bundled-translations.json +1 -0
- package/lib/src/bundles/bundled-translations.pt-BR.json +1 -0
- package/lib/src/bundles/bundled-translations.pt-PT.json +1 -0
- package/lib/src/css/library.brand-page-brandCrowd.min.css +1 -1
- package/lib/src/css/library.brand-page-brandPage.min.css +1 -1
- package/lib/src/css/library.brand-page-designCom.min.css +1 -1
- package/lib/src/css/library.brand-page-preview.min.css +1 -1
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-33AmrlUy.js → lib-O_eJgJHP.js} +8465 -8415
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -0
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +5 -0
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +25 -0
- package/lib/src/utils/minify-brand-page-metadata.d.ts +1 -0
- package/lib/src/utils/minify-brand-page-metadata.js +13 -3
- package/package.json +1 -1
- package/src/brand-page/models/index.ts +9 -2
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +18 -6
- package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +6 -2
- package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +12 -4
- package/src/brand-page/utils/view-model.util.test.ts +145 -1
- package/src/brand-page/utils/view-model.util.ts +27 -2
- package/src/brand-page/view-models.ts +2 -0
- package/src/bundles/bundled-translations.de-DE.json +1 -0
- package/src/bundles/bundled-translations.es-ES.json +1 -0
- package/src/bundles/bundled-translations.fr-CA.json +1 -0
- package/src/bundles/bundled-translations.fr-FR.json +1 -0
- package/src/bundles/bundled-translations.json +1 -0
- package/src/bundles/bundled-translations.pt-BR.json +1 -0
- package/src/bundles/bundled-translations.pt-PT.json +1 -0
- package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.test.ts +111 -0
- package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.vue +18 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.de-DE.json +1 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.es-ES.json +1 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.fr-CA.json +1 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.fr-FR.json +1 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.json +1 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.pt-BR.json +1 -0
- package/src/shared/page-settings/components/page-settings/i18n/page-settings.pt-PT.json +1 -0
- package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +33 -0
- package/src/utils/minify-brand-page-metadata.test.ts +70 -1
- package/src/utils/minify-brand-page-metadata.ts +19 -4
- package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +0 -13
- package/lib/src/metadata-builder/builders/reorder-pages-builder.js +0 -49
- package/src/metadata-builder/builders/reorder-pages-builder.ts +0 -80
|
@@ -1277,6 +1277,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
1277
1277
|
} | undefined;
|
|
1278
1278
|
logoImageBase64Url?: string | undefined;
|
|
1279
1279
|
backgroundStyle: {
|
|
1280
|
+
backgroundOpacity?: number | undefined;
|
|
1280
1281
|
aspectRatio?: string | undefined;
|
|
1281
1282
|
backgroundAttachment?: string | undefined;
|
|
1282
1283
|
background?: string | undefined;
|
|
@@ -2569,6 +2570,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
2569
2570
|
} | undefined;
|
|
2570
2571
|
logoImageBase64Url?: string | undefined;
|
|
2571
2572
|
backgroundStyle: {
|
|
2573
|
+
backgroundOpacity?: number | undefined;
|
|
2572
2574
|
aspectRatio?: string | undefined;
|
|
2573
2575
|
backgroundAttachment?: string | undefined;
|
|
2574
2576
|
background?: string | undefined;
|
|
@@ -1235,6 +1235,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
1235
1235
|
} | undefined;
|
|
1236
1236
|
logoImageBase64Url?: string | undefined;
|
|
1237
1237
|
backgroundStyle: {
|
|
1238
|
+
backgroundOpacity?: number | undefined;
|
|
1238
1239
|
aspectRatio?: string | undefined;
|
|
1239
1240
|
backgroundAttachment?: string | undefined;
|
|
1240
1241
|
background?: string | undefined;
|
|
@@ -2527,6 +2528,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
2527
2528
|
} | undefined;
|
|
2528
2529
|
logoImageBase64Url?: string | undefined;
|
|
2529
2530
|
backgroundStyle: {
|
|
2531
|
+
backgroundOpacity?: number | undefined;
|
|
2530
2532
|
aspectRatio?: string | undefined;
|
|
2531
2533
|
backgroundAttachment?: string | undefined;
|
|
2532
2534
|
background?: string | undefined;
|
|
@@ -4638,6 +4640,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
4638
4640
|
logoSliderMax(): number;
|
|
4639
4641
|
backgroundColor(): string;
|
|
4640
4642
|
isBackgroundColorEnabled(): boolean;
|
|
4643
|
+
backgroundOpacity(): number;
|
|
4644
|
+
showBackgroundOpacity(): boolean;
|
|
4641
4645
|
copyrightPlaceholder(): string;
|
|
4642
4646
|
copyrightText: {
|
|
4643
4647
|
get(): string;
|
|
@@ -4689,6 +4693,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
4689
4693
|
logoImageBase64Url?: string;
|
|
4690
4694
|
}): void;
|
|
4691
4695
|
onSelectColor(selectedColor: UpdateItemValuePayload<string>): void;
|
|
4696
|
+
onBackgroundOpacityChange(value: number | string): void;
|
|
4692
4697
|
onBackgroundEnable(enabled: UpdateItemValuePayload<boolean>): void;
|
|
4693
4698
|
onLogoVisibleChanged(showLogo: boolean): void;
|
|
4694
4699
|
onLogoVariationSelected(selectedLogoVariationIndex: number): void;
|
|
@@ -3,6 +3,7 @@ import { PAGE_SECTION_STYLE_OPTIONS } from '@brand-page-maker/models/page-sectio
|
|
|
3
3
|
import { PAGE_SECTIONS } from '../../models';
|
|
4
4
|
import { LOGO_SLIDER_DESKTOP_MAX, LOGO_SLIDER_DESKTOP_MIN, LOGO_SLIDER_MOBILE_MAX, LOGO_SLIDER_MOBILE_MIN, VIEWPORTS, getNavigationType, NAVIGATION_TYPE_DEFAULT_DISPLAY_TYPE, } from '@brand-page';
|
|
5
5
|
import { UI_DEVICE_MODES, UI_EVENT_SOURCES } from '../../../models';
|
|
6
|
+
import { isTransparentColour } from '@brand-page/utils/color.util';
|
|
6
7
|
import { useUiPageSettingsStore } from '../../store';
|
|
7
8
|
import { useUiNavigationStyleSettingsStore } from '../../../navigation-style-settings/store';
|
|
8
9
|
import { useUiStyleSettingsStore } from '../../../style-settings/store';
|
|
@@ -141,6 +142,15 @@ export default defineComponent({
|
|
|
141
142
|
return this.sections[this.sectionName][this.viewport]
|
|
142
143
|
.backgroundColorEnabled;
|
|
143
144
|
},
|
|
145
|
+
backgroundOpacity() {
|
|
146
|
+
// Real default: an un-constructed (JSON.parse'd) header never saw the constructor's default.
|
|
147
|
+
return (this.sections[this.sectionName][this.viewport].backgroundStyle
|
|
148
|
+
?.backgroundOpacity ?? 100);
|
|
149
|
+
},
|
|
150
|
+
showBackgroundOpacity() {
|
|
151
|
+
// isTransparentColour('') is false, so an unset color needs its own check.
|
|
152
|
+
return (!!this.backgroundColor && !isTransparentColour(this.backgroundColor));
|
|
153
|
+
},
|
|
144
154
|
copyrightPlaceholder() {
|
|
145
155
|
return commonTr(`copyrightTextPlaceholder`);
|
|
146
156
|
},
|
|
@@ -394,6 +404,21 @@ export default defineComponent({
|
|
|
394
404
|
viewport: this.viewport,
|
|
395
405
|
});
|
|
396
406
|
},
|
|
407
|
+
onBackgroundOpacityChange(value) {
|
|
408
|
+
// Clamped here: the Slider's text field can emit an out-of-range value mid-typing.
|
|
409
|
+
const clamped = Math.min(100, Math.max(0, Number(value) || 0));
|
|
410
|
+
// A variable, not an inline literal — backgroundOpacity isn't on BrandPageCssStyle.
|
|
411
|
+
const backgroundStyle = {
|
|
412
|
+
backgroundOpacity: clamped,
|
|
413
|
+
};
|
|
414
|
+
this.pageSettingsStore.setPageSettingsSectionValue({
|
|
415
|
+
sectionName: this.sectionName,
|
|
416
|
+
propName: 'backgroundStyle',
|
|
417
|
+
value: backgroundStyle,
|
|
418
|
+
merge: true,
|
|
419
|
+
viewport: this.viewport,
|
|
420
|
+
});
|
|
421
|
+
},
|
|
397
422
|
onBackgroundEnable(enabled) {
|
|
398
423
|
this.pageSettingsStore.setPageSettingsSectionValue({
|
|
399
424
|
sectionName: this.sectionName,
|
|
@@ -389,6 +389,18 @@ const minifyFooter = (footer, logoAssetKey) => {
|
|
|
389
389
|
: undefined,
|
|
390
390
|
};
|
|
391
391
|
};
|
|
392
|
+
// Fully opaque (100) is the default, so it's omitted to keep the AI payload small.
|
|
393
|
+
const minifyHeaderBackgroundStyle = (backgroundStyle) => {
|
|
394
|
+
const backgroundColor = backgroundStyle?.backgroundColor;
|
|
395
|
+
if (!backgroundColor)
|
|
396
|
+
return undefined;
|
|
397
|
+
const backgroundOpacity = backgroundStyle.backgroundOpacity;
|
|
398
|
+
return {
|
|
399
|
+
backgroundColor,
|
|
400
|
+
...(backgroundOpacity !== undefined &&
|
|
401
|
+
backgroundOpacity < 100 && { backgroundOpacity }),
|
|
402
|
+
};
|
|
403
|
+
};
|
|
392
404
|
const minifyHeader = (header, logoAssetKey) => {
|
|
393
405
|
if (!header)
|
|
394
406
|
return undefined;
|
|
@@ -399,9 +411,7 @@ const minifyHeader = (header, logoAssetKey) => {
|
|
|
399
411
|
logoImageHeight: header.logoImageHeight || undefined,
|
|
400
412
|
logoImageWidth: header.logoImageWidth || undefined,
|
|
401
413
|
...(logoAssetKey && { logoAssetKey }),
|
|
402
|
-
backgroundStyle: header.backgroundStyle
|
|
403
|
-
? { backgroundColor: header.backgroundStyle.backgroundColor }
|
|
404
|
-
: undefined,
|
|
414
|
+
backgroundStyle: minifyHeaderBackgroundStyle(header.backgroundStyle),
|
|
405
415
|
navigation: nav
|
|
406
416
|
? {
|
|
407
417
|
displayType: nav.displayType || undefined,
|
package/package.json
CHANGED
|
@@ -90,6 +90,10 @@ export type BackgroundStyle = Partial<
|
|
|
90
90
|
Omit<BrandPageCssStyle, 'backgroundColor'>
|
|
91
91
|
>;
|
|
92
92
|
|
|
93
|
+
export interface BackgroundColorStyle extends BrandPageCssStyle {
|
|
94
|
+
backgroundOpacity?: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
93
97
|
/**
|
|
94
98
|
* The complete default for a page's background media overlay. Seeded into
|
|
95
99
|
* metadata (constructor for new models, migration-20.5 for persisted partials) so
|
|
@@ -734,7 +738,7 @@ export abstract class AbstractPageHeaderStyles {
|
|
|
734
738
|
logoImage: LogoImageModel;
|
|
735
739
|
logoTemplateImage: LogoTemplateImageModel | undefined;
|
|
736
740
|
logoImageBase64Url?: string;
|
|
737
|
-
backgroundStyle:
|
|
741
|
+
backgroundStyle: BackgroundColorStyle;
|
|
738
742
|
style: BrandPageCssStyle;
|
|
739
743
|
viewport: ViewportsType;
|
|
740
744
|
|
|
@@ -771,7 +775,10 @@ export abstract class AbstractPageHeaderStyles {
|
|
|
771
775
|
this.logoVariation = options.logoVariation || 0;
|
|
772
776
|
|
|
773
777
|
this.style = options.style || {};
|
|
774
|
-
this.backgroundStyle =
|
|
778
|
+
this.backgroundStyle = {
|
|
779
|
+
...(options.backgroundStyle || {}),
|
|
780
|
+
backgroundOpacity: options.backgroundStyle?.backgroundOpacity ?? 100,
|
|
781
|
+
};
|
|
775
782
|
}
|
|
776
783
|
}
|
|
777
784
|
|
|
@@ -152,7 +152,9 @@ exports[`migration.util > Banner Contents - text Align and Font Family should no
|
|
|
152
152
|
"viewport": "mobile",
|
|
153
153
|
},
|
|
154
154
|
"pageHeaderDesktop": PageHeaderDesktop {
|
|
155
|
-
"backgroundStyle": {
|
|
155
|
+
"backgroundStyle": {
|
|
156
|
+
"backgroundOpacity": 100,
|
|
157
|
+
},
|
|
156
158
|
"displayStyle": "desktop-tab-vertical-stack-centered-logo-centered-menu",
|
|
157
159
|
"isLogoOptional": false,
|
|
158
160
|
"isLogoVisible": true,
|
|
@@ -225,7 +227,9 @@ exports[`migration.util > Banner Contents - text Align and Font Family should no
|
|
|
225
227
|
"viewport": "desktop",
|
|
226
228
|
},
|
|
227
229
|
"pageHeaderMobile": PageHeaderMobile {
|
|
228
|
-
"backgroundStyle": {
|
|
230
|
+
"backgroundStyle": {
|
|
231
|
+
"backgroundOpacity": 100,
|
|
232
|
+
},
|
|
229
233
|
"displayStyle": "mobile-tab-vertical-stack-centered-logo-centered-menu",
|
|
230
234
|
"isLogoOptional": false,
|
|
231
235
|
"isLogoVisible": true,
|
|
@@ -645,7 +649,9 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
|
|
|
645
649
|
"viewport": "mobile",
|
|
646
650
|
},
|
|
647
651
|
"pageHeaderDesktop": PageHeaderDesktop {
|
|
648
|
-
"backgroundStyle": {
|
|
652
|
+
"backgroundStyle": {
|
|
653
|
+
"backgroundOpacity": 100,
|
|
654
|
+
},
|
|
649
655
|
"displayStyle": "desktop-tab-vertical-stack-centered-logo-centered-menu",
|
|
650
656
|
"isLogoOptional": false,
|
|
651
657
|
"isLogoVisible": true,
|
|
@@ -718,7 +724,9 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
|
|
|
718
724
|
"viewport": "desktop",
|
|
719
725
|
},
|
|
720
726
|
"pageHeaderMobile": PageHeaderMobile {
|
|
721
|
-
"backgroundStyle": {
|
|
727
|
+
"backgroundStyle": {
|
|
728
|
+
"backgroundOpacity": 100,
|
|
729
|
+
},
|
|
722
730
|
"displayStyle": "mobile-tab-vertical-stack-centered-logo-centered-menu",
|
|
723
731
|
"isLogoOptional": false,
|
|
724
732
|
"isLogoVisible": true,
|
|
@@ -1122,7 +1130,9 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
|
|
|
1122
1130
|
"viewport": "mobile",
|
|
1123
1131
|
},
|
|
1124
1132
|
"pageHeaderDesktop": PageHeaderDesktop {
|
|
1125
|
-
"backgroundStyle": {
|
|
1133
|
+
"backgroundStyle": {
|
|
1134
|
+
"backgroundOpacity": 100,
|
|
1135
|
+
},
|
|
1126
1136
|
"displayStyle": "desktop-tab-vertical-stack-centered-logo-centered-menu",
|
|
1127
1137
|
"isLogoOptional": false,
|
|
1128
1138
|
"isLogoVisible": true,
|
|
@@ -1195,7 +1205,9 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
|
|
|
1195
1205
|
"viewport": "desktop",
|
|
1196
1206
|
},
|
|
1197
1207
|
"pageHeaderMobile": PageHeaderMobile {
|
|
1198
|
-
"backgroundStyle": {
|
|
1208
|
+
"backgroundStyle": {
|
|
1209
|
+
"backgroundOpacity": 100,
|
|
1210
|
+
},
|
|
1199
1211
|
"displayStyle": "mobile-tab-vertical-stack-centered-logo-centered-menu",
|
|
1200
1212
|
"isLogoOptional": false,
|
|
1201
1213
|
"isLogoVisible": true,
|
|
@@ -137,7 +137,9 @@ exports[`migration02.ts > migration02 should return converted letterspacing 1`]
|
|
|
137
137
|
"viewport": "mobile",
|
|
138
138
|
},
|
|
139
139
|
"pageHeaderDesktop": PageHeaderDesktop {
|
|
140
|
-
"backgroundStyle": {
|
|
140
|
+
"backgroundStyle": {
|
|
141
|
+
"backgroundOpacity": 100,
|
|
142
|
+
},
|
|
141
143
|
"displayStyle": "desktop-tab-vertical-stack-centered-logo-centered-menu",
|
|
142
144
|
"isLogoOptional": false,
|
|
143
145
|
"isLogoVisible": true,
|
|
@@ -211,7 +213,9 @@ exports[`migration02.ts > migration02 should return converted letterspacing 1`]
|
|
|
211
213
|
"viewport": "desktop",
|
|
212
214
|
},
|
|
213
215
|
"pageHeaderMobile": PageHeaderMobile {
|
|
214
|
-
"backgroundStyle": {
|
|
216
|
+
"backgroundStyle": {
|
|
217
|
+
"backgroundOpacity": 100,
|
|
218
|
+
},
|
|
215
219
|
"displayStyle": "mobile-tab-vertical-stack-centered-logo-centered-menu",
|
|
216
220
|
"isLogoOptional": false,
|
|
217
221
|
"isLogoVisible": true,
|
|
@@ -136,7 +136,9 @@ BrandPageModel {
|
|
|
136
136
|
"viewport": "mobile",
|
|
137
137
|
},
|
|
138
138
|
"pageHeaderDesktop": PageHeaderDesktop {
|
|
139
|
-
"backgroundStyle": {
|
|
139
|
+
"backgroundStyle": {
|
|
140
|
+
"backgroundOpacity": 100,
|
|
141
|
+
},
|
|
140
142
|
"displayStyle": "desktop-tab-vertical-stack-centered-logo-centered-menu",
|
|
141
143
|
"isLogoOptional": false,
|
|
142
144
|
"isLogoVisible": true,
|
|
@@ -210,7 +212,9 @@ BrandPageModel {
|
|
|
210
212
|
"viewport": "desktop",
|
|
211
213
|
},
|
|
212
214
|
"pageHeaderMobile": PageHeaderMobile {
|
|
213
|
-
"backgroundStyle": {
|
|
215
|
+
"backgroundStyle": {
|
|
216
|
+
"backgroundOpacity": 100,
|
|
217
|
+
},
|
|
214
218
|
"displayStyle": "mobile-tab-vertical-stack-centered-logo-centered-menu",
|
|
215
219
|
"isLogoOptional": false,
|
|
216
220
|
"isLogoVisible": true,
|
|
@@ -593,7 +597,9 @@ BrandPageModel {
|
|
|
593
597
|
"viewport": "mobile",
|
|
594
598
|
},
|
|
595
599
|
"pageHeaderDesktop": PageHeaderDesktop {
|
|
596
|
-
"backgroundStyle": {
|
|
600
|
+
"backgroundStyle": {
|
|
601
|
+
"backgroundOpacity": 100,
|
|
602
|
+
},
|
|
597
603
|
"displayStyle": "desktop-tab-vertical-stack-centered-logo-centered-menu",
|
|
598
604
|
"isLogoOptional": false,
|
|
599
605
|
"isLogoVisible": true,
|
|
@@ -667,7 +673,9 @@ BrandPageModel {
|
|
|
667
673
|
"viewport": "desktop",
|
|
668
674
|
},
|
|
669
675
|
"pageHeaderMobile": PageHeaderMobile {
|
|
670
|
-
"backgroundStyle": {
|
|
676
|
+
"backgroundStyle": {
|
|
677
|
+
"backgroundOpacity": 100,
|
|
678
|
+
},
|
|
671
679
|
"displayStyle": "mobile-tab-vertical-stack-centered-logo-centered-menu",
|
|
672
680
|
"isLogoOptional": false,
|
|
673
681
|
"isLogoVisible": true,
|
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
type ContactFormContent,
|
|
7
7
|
type ColorItem,
|
|
8
8
|
} from '../models';
|
|
9
|
-
import { BRAND_PAGE_TYPES, PageStyles } from '../models';
|
|
9
|
+
import { BRAND_PAGE_TYPES, PageHeaderDesktop, PageStyles } from '../models';
|
|
10
10
|
import {
|
|
11
11
|
mapToBannerSectionViewModel,
|
|
12
12
|
mapToContactFormViewModel,
|
|
13
13
|
mapToImageViewModel,
|
|
14
14
|
mapToMailingListViewModel,
|
|
15
|
+
mapToPageHeaderViewModel,
|
|
15
16
|
mapToProfileViewModel,
|
|
16
17
|
mapToTextViewModel,
|
|
17
18
|
mapToViewModel,
|
|
@@ -508,6 +509,149 @@ describe('view model util', () => {
|
|
|
508
509
|
expect(url.searchParams.has('w')).toBe(true);
|
|
509
510
|
expect(wParamValue).toBe('1080');
|
|
510
511
|
});
|
|
512
|
+
|
|
513
|
+
describe('mapToPageHeaderViewModel background opacity (BP-5851)', () => {
|
|
514
|
+
const mapHeader = (header: PageHeaderDesktop) =>
|
|
515
|
+
mapToPageHeaderViewModel(header, new PageStyles(), []);
|
|
516
|
+
|
|
517
|
+
test('constructing without an explicit backgroundOpacity defaults it to 100 and renders unchanged', () => {
|
|
518
|
+
const header = new PageHeaderDesktop({
|
|
519
|
+
backgroundStyle: { backgroundColor: '#ff0000' },
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
expect(header.backgroundStyle.backgroundOpacity).toBe(100);
|
|
523
|
+
|
|
524
|
+
const viewModel = mapHeader(header);
|
|
525
|
+
|
|
526
|
+
expect(viewModel.backgroundStyle).toEqual({ backgroundColor: '#ff0000' });
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
test('header constructed with no options still gets a concrete backgroundOpacity', () => {
|
|
530
|
+
expect(new PageHeaderDesktop().backgroundStyle.backgroundOpacity).toBe(
|
|
531
|
+
100,
|
|
532
|
+
);
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
test('un-constructed legacy header (parsed metadata that never ran the constructor) renders fully opaque', () => {
|
|
536
|
+
// The maker's live-preview path can hold the header JSON.parse'd verbatim.
|
|
537
|
+
const header = JSON.parse(
|
|
538
|
+
JSON.stringify(
|
|
539
|
+
new PageHeaderDesktop({
|
|
540
|
+
backgroundStyle: { backgroundColor: '#ff0000' },
|
|
541
|
+
}),
|
|
542
|
+
),
|
|
543
|
+
) as PageHeaderDesktop;
|
|
544
|
+
|
|
545
|
+
delete header.backgroundStyle.backgroundOpacity;
|
|
546
|
+
|
|
547
|
+
const viewModel = mapHeader(header);
|
|
548
|
+
|
|
549
|
+
expect(viewModel.backgroundStyle).toEqual({ backgroundColor: '#ff0000' });
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
test('a header with backgroundStyle itself absent renders fully opaque instead of throwing', () => {
|
|
553
|
+
const header = new PageHeaderDesktop();
|
|
554
|
+
|
|
555
|
+
delete (header as { backgroundStyle?: unknown }).backgroundStyle;
|
|
556
|
+
|
|
557
|
+
expect(() => mapHeader(header)).not.toThrow();
|
|
558
|
+
expect(mapHeader(header).backgroundStyle).toEqual({});
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
test('opacity 100 (default) leaves backgroundColor unchanged', () => {
|
|
562
|
+
const header = new PageHeaderDesktop({
|
|
563
|
+
backgroundStyle: { backgroundColor: '#ff0000', backgroundOpacity: 100 },
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
const viewModel = mapHeader(header);
|
|
567
|
+
|
|
568
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBe('#ff0000');
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
test('opacity 60 composites into the expected 8-digit hex backgroundColor', () => {
|
|
572
|
+
const header = new PageHeaderDesktop({
|
|
573
|
+
backgroundStyle: { backgroundColor: '#ff0000', backgroundOpacity: 60 },
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
const viewModel = mapHeader(header);
|
|
577
|
+
|
|
578
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBe('#ff000099');
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
test('opacity below 100 composites into an 8-digit hex backgroundColor', () => {
|
|
582
|
+
const header = new PageHeaderDesktop({
|
|
583
|
+
backgroundStyle: { backgroundColor: '#ff0000', backgroundOpacity: 50 },
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
const viewModel = mapHeader(header);
|
|
587
|
+
|
|
588
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBe('#ff000080');
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
test('opacity 0 composites to the transparent keyword', () => {
|
|
592
|
+
const header = new PageHeaderDesktop({
|
|
593
|
+
backgroundStyle: { backgroundColor: '#ff0000', backgroundOpacity: 0 },
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
const viewModel = mapHeader(header);
|
|
597
|
+
|
|
598
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBe('transparent');
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
test('a palette-matched (var(--palette-n)) backgroundColor is faded via color-mix, not handed back unfaded', () => {
|
|
602
|
+
const header = new PageHeaderDesktop({
|
|
603
|
+
backgroundStyle: {
|
|
604
|
+
backgroundColor: 'var(--palette-1)',
|
|
605
|
+
backgroundOpacity: 30,
|
|
606
|
+
},
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
const viewModel = mapHeader(header);
|
|
610
|
+
|
|
611
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBe(
|
|
612
|
+
'color-mix(in srgb, var(--palette-1) 30%, transparent)',
|
|
613
|
+
);
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
test('transparent backgroundColor is left unchanged regardless of opacity', () => {
|
|
617
|
+
const header = new PageHeaderDesktop({
|
|
618
|
+
backgroundStyle: {
|
|
619
|
+
backgroundColor: 'transparent',
|
|
620
|
+
backgroundOpacity: 40,
|
|
621
|
+
},
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
const viewModel = mapHeader(header);
|
|
625
|
+
|
|
626
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBe('transparent');
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
test('unset backgroundColor is left unchanged regardless of opacity', () => {
|
|
630
|
+
const header = new PageHeaderDesktop({
|
|
631
|
+
backgroundStyle: { backgroundOpacity: 40 },
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
const viewModel = mapHeader(header);
|
|
635
|
+
|
|
636
|
+
expect(viewModel.backgroundStyle.backgroundColor).toBeUndefined();
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
test.each([100, 30])(
|
|
640
|
+
'backgroundOpacity %i never leaks into the rendered style, and CSS opacity is never set (children must stay opaque)',
|
|
641
|
+
(backgroundOpacity) => {
|
|
642
|
+
const header = new PageHeaderDesktop({
|
|
643
|
+
backgroundStyle: { backgroundColor: '#ff0000', backgroundOpacity },
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
const viewModel = mapHeader(header);
|
|
647
|
+
|
|
648
|
+
expect(viewModel.backgroundStyle).not.toHaveProperty(
|
|
649
|
+
'backgroundOpacity',
|
|
650
|
+
);
|
|
651
|
+
expect(viewModel.backgroundStyle.opacity).toBeUndefined();
|
|
652
|
+
},
|
|
653
|
+
);
|
|
654
|
+
});
|
|
511
655
|
});
|
|
512
656
|
|
|
513
657
|
// The reCAPTCHA footnote colour is a raw colour anchored to the surface it sits on.
|
|
@@ -88,9 +88,10 @@ import type {
|
|
|
88
88
|
NavItemViewModel,
|
|
89
89
|
} from '../view-models';
|
|
90
90
|
import {
|
|
91
|
+
backgroundColorFromStyle,
|
|
91
92
|
isTransparentColour,
|
|
92
93
|
mutedTextForBackground,
|
|
93
|
-
|
|
94
|
+
withColorOpacity,
|
|
94
95
|
} from './color.util';
|
|
95
96
|
import { resolveColorReference } from './color-palette.util';
|
|
96
97
|
import {
|
|
@@ -1281,7 +1282,31 @@ export const mapToPageHeaderViewModel = (
|
|
|
1281
1282
|
hamburgerMenuStyle,
|
|
1282
1283
|
}),
|
|
1283
1284
|
style: pageHeader.style,
|
|
1284
|
-
backgroundStyle: pageHeader
|
|
1285
|
+
backgroundStyle: getHeaderBackgroundStyleWithOpacity(pageHeader),
|
|
1286
|
+
};
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
// Folds backgroundOpacity into backgroundColor's alpha so only the container's paint fades, not its children.
|
|
1290
|
+
const getHeaderBackgroundStyleWithOpacity = (
|
|
1291
|
+
pageHeader: PageHeaderDesktop | PageHeaderMobile,
|
|
1292
|
+
): BrandPageCssStyle => {
|
|
1293
|
+
// Real defaults: an un-constructed maker header, or metadata older than migration-11's backfill, can lack these entirely.
|
|
1294
|
+
const { backgroundOpacity = 100, ...backgroundStyle } =
|
|
1295
|
+
pageHeader.backgroundStyle ?? {};
|
|
1296
|
+
const { backgroundColor } = backgroundStyle;
|
|
1297
|
+
|
|
1298
|
+
if (
|
|
1299
|
+
backgroundOpacity >= 100 ||
|
|
1300
|
+
!backgroundColor ||
|
|
1301
|
+
isTransparentColour(backgroundColor)
|
|
1302
|
+
) {
|
|
1303
|
+
return backgroundStyle;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// withColorOpacity, not setRgbAlpha: fades a var(--palette-n) reference too.
|
|
1307
|
+
return {
|
|
1308
|
+
...backgroundStyle,
|
|
1309
|
+
backgroundColor: withColorOpacity(backgroundColor, backgroundOpacity / 100),
|
|
1285
1310
|
};
|
|
1286
1311
|
};
|
|
1287
1312
|
|
|
@@ -259,9 +259,11 @@ export interface PageHeaderViewModel extends Omit<
|
|
|
259
259
|
| 'logoTemplateImage'
|
|
260
260
|
| 'logoImageHeight'
|
|
261
261
|
| 'logoImageWidth'
|
|
262
|
+
| 'backgroundStyle'
|
|
262
263
|
> {
|
|
263
264
|
logo: LogoViewModel;
|
|
264
265
|
pages: PageViewModel[];
|
|
266
|
+
backgroundStyle: BrandPageCssStyle;
|
|
265
267
|
}
|
|
266
268
|
|
|
267
269
|
export interface PageFooterViewModel extends Omit<
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Kopfzeilen-Einstellungen",
|
|
1842
1842
|
"navigationSectionTitle": "Navigation",
|
|
1843
1843
|
"headerSectionTitle": "Header",
|
|
1844
|
+
"backgroundOpacity": "Hintergrunddeckkraft",
|
|
1844
1845
|
"buttonSectionTitle": "Schaltfläche",
|
|
1845
1846
|
"footerSettings": "Fußzeilen-Einstellungen",
|
|
1846
1847
|
"managePages": "Seiten verwalten",
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Configuración del encabezado",
|
|
1842
1842
|
"navigationSectionTitle": "Navegación",
|
|
1843
1843
|
"headerSectionTitle": "Encabezado",
|
|
1844
|
+
"backgroundOpacity": "Opacidad del fondo",
|
|
1844
1845
|
"buttonSectionTitle": "Botón",
|
|
1845
1846
|
"footerSettings": "Configuración del pie de página",
|
|
1846
1847
|
"managePages": "Gestionar páginas",
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Paramètres d'en-tête",
|
|
1842
1842
|
"navigationSectionTitle": "Navigation",
|
|
1843
1843
|
"headerSectionTitle": "En-tête",
|
|
1844
|
+
"backgroundOpacity": "Opacité de l'arrière-plan",
|
|
1844
1845
|
"buttonSectionTitle": "Bouton",
|
|
1845
1846
|
"footerSettings": "Paramètres de pied de page",
|
|
1846
1847
|
"managePages": "Gérer les pages",
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Paramètres d'en-tête",
|
|
1842
1842
|
"navigationSectionTitle": "Navigation",
|
|
1843
1843
|
"headerSectionTitle": "En-tête",
|
|
1844
|
+
"backgroundOpacity": "Opacité de l'arrière-plan",
|
|
1844
1845
|
"buttonSectionTitle": "Bouton",
|
|
1845
1846
|
"footerSettings": "Paramètres de pied de page",
|
|
1846
1847
|
"managePages": "Gérer les pages",
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Header Settings",
|
|
1842
1842
|
"navigationSectionTitle": "Navigation",
|
|
1843
1843
|
"headerSectionTitle": "Header",
|
|
1844
|
+
"backgroundOpacity": "Background opacity",
|
|
1844
1845
|
"buttonSectionTitle": "Button",
|
|
1845
1846
|
"footerSettings": "Footer Settings",
|
|
1846
1847
|
"managePages": "Manage Pages",
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Configurações do cabeçalho",
|
|
1842
1842
|
"navigationSectionTitle": "Navegação",
|
|
1843
1843
|
"headerSectionTitle": "Cabeçalho",
|
|
1844
|
+
"backgroundOpacity": "Opacidade do plano de fundo",
|
|
1844
1845
|
"buttonSectionTitle": "Botão",
|
|
1845
1846
|
"footerSettings": "Definições de rodapé",
|
|
1846
1847
|
"managePages": "Gerenciar páginas",
|
|
@@ -1841,6 +1841,7 @@
|
|
|
1841
1841
|
"headerSettings": "Definições de cabeçalho",
|
|
1842
1842
|
"navigationSectionTitle": "Navegação",
|
|
1843
1843
|
"headerSectionTitle": "Cabeçalho",
|
|
1844
|
+
"backgroundOpacity": "Opacidade do fundo",
|
|
1844
1845
|
"buttonSectionTitle": "Botão",
|
|
1845
1846
|
"footerSettings": "Definições de rodapé",
|
|
1846
1847
|
"managePages": "Gerir páginas",
|