@designcrowd/library.brand-page 6.0.21 → 6.0.22

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 (82) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-C52IyXZu.js → CreatedOnBrandCrowd-de-de-BS8dQhaZ.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DhTy_dEV.js → CreatedOnBrandCrowd-en-us-45ZyXSxn.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BJelIAQ4.js → CreatedOnBrandCrowd-es-es-B1K3Ojw-.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-DwJohy0T.js → CreatedOnBrandCrowd-fr-ca-4v9c20Q9.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-DwJohy0T.js → CreatedOnBrandCrowd-fr-fr-4v9c20Q9.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CMzKbxdG.js → CreatedOnBrandCrowd-pt-br-BdDmm1GE.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-CMzKbxdG.js → CreatedOnBrandCrowd-pt-pt-BdDmm1GE.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DAy1GHrw.js → CreatedOnDcom-de-de-Dc8rOxAE.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CgBDAkJN.js → CreatedOnDcom-en-us-Bq6rusW6.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-Ds9d5rem.js → CreatedOnDcom-es-es-C5gNEuoi.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CZL0BQ-u.js → CreatedOnDcom-fr-ca-NL2KoADg.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-BVYh5Wvo.js → CreatedOnDcom-fr-fr-DZaLN0j-.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-1hsWNXfq.js → CreatedOnDcom-pt-br-DXZvo45o.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-DvM0N-3M.js → CreatedOnDcom-pt-pt-GUJ4aTM2.js} +1 -1
  15. package/lib/src/brand-page/components/collapsible/Collapsible.mixin.d.ts +11 -0
  16. package/lib/src/brand-page/components/collapsible/Collapsible.mixin.js +13 -1
  17. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +1 -0
  18. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +12 -3
  19. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +5 -0
  20. package/lib/src/brand-page/components/payment/Payment.mixin.js +5 -0
  21. package/lib/src/brand-page/models/index.d.ts +1 -0
  22. package/lib/src/brand-page/models/payment.model.d.ts +2 -0
  23. package/lib/src/brand-page/utils/button.util.d.ts +5 -0
  24. package/lib/src/brand-page/utils/button.util.js +13 -0
  25. package/lib/src/brand-page/utils/migration/migration-19.d.ts +2 -0
  26. package/lib/src/brand-page/utils/migration/migration-19.js +41 -0
  27. package/lib/src/brand-page/utils/migration.util.js +11 -0
  28. package/lib/src/brand-page/utils/view-model.util.js +1 -0
  29. package/lib/src/brand-page-maker/assessors/contact-form-visibility.assessor.d.ts +1 -0
  30. package/lib/src/brand-page-maker/assessors/contact-form-visibility.assessor.js +16 -7
  31. package/lib/src/brand-page-maker/constants/config-settings-constant.js +40 -3
  32. package/lib/src/brand-page-maker/default-getters/contact-form-card-color.default-getter.d.ts +8 -0
  33. package/lib/src/brand-page-maker/default-getters/contact-form-card-color.default-getter.js +16 -0
  34. package/lib/src/brand-page-maker/default-getters/index.d.ts +1 -0
  35. package/lib/src/brand-page-maker/default-getters/index.js +1 -0
  36. package/lib/src/brand-page-maker/models/button-styles-config.js +15 -3
  37. package/lib/src/brand-page-maker/models/content-settings-configs.d.ts +2 -1
  38. package/lib/src/brand-page-maker/models/content-settings.js +15 -3
  39. package/lib/src/css/library.brand-page-brandCrowd.min.css +96 -68
  40. package/lib/src/css/library.brand-page-brandPage.min.css +96 -68
  41. package/lib/src/css/library.brand-page-designCom.min.css +96 -68
  42. package/lib/src/css/library.brand-page-preview.min.css +96 -68
  43. package/lib/src/index.mjs +1 -1
  44. package/lib/src/{lib-CK2FPBv5.js → lib-Dh4vrmod.js} +18439 -18090
  45. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +5 -0
  46. package/lib/src/shared/content-settings/models.d.ts +1 -0
  47. package/lib/src/shared/content-settings/store/content-settings-store.js +3 -0
  48. package/package.json +2 -2
  49. package/src/brand-page/components/button/ButtonStyleWrapper.vue +112 -44
  50. package/src/brand-page/components/button/ButtonStyleWrapper.vue.test.ts +167 -0
  51. package/src/brand-page/components/collapsible/Collapsible.mixin.ts +14 -1
  52. package/src/brand-page/components/contact-form/ContactForm.mixin.test.ts +18 -0
  53. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +15 -3
  54. package/src/brand-page/components/contact-form/ContactForm.vue +97 -36
  55. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +6 -0
  56. package/src/brand-page/components/mailing-list/MailingList.vue +18 -10
  57. package/src/brand-page/components/payment/Payment.mixin.ts +6 -0
  58. package/src/brand-page/components/payment/Payment.vue +43 -24
  59. package/src/brand-page/components/payment/RequestPaymentStripe.vue +26 -22
  60. package/src/brand-page/components/shop/Shop.vue +15 -6
  61. package/src/brand-page/models/index.ts +1 -0
  62. package/src/brand-page/models/payment.model.ts +2 -0
  63. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
  64. package/src/brand-page/utils/button.util.ts +17 -0
  65. package/src/brand-page/utils/migration/migration-19.test.ts +172 -0
  66. package/src/brand-page/utils/migration/migration-19.ts +65 -0
  67. package/src/brand-page/utils/migration.util.ts +12 -0
  68. package/src/brand-page/utils/view-model.util.ts +1 -0
  69. package/src/brand-page-maker/assessors/contact-form-visibility.assessor.ts +34 -26
  70. package/src/brand-page-maker/constants/config-settings-constant.ts +43 -2
  71. package/src/brand-page-maker/default-getters/contact-form-card-color.default-getter.ts +23 -0
  72. package/src/brand-page-maker/default-getters/index.ts +1 -0
  73. package/src/brand-page-maker/models/button-styles-config.ts +15 -3
  74. package/src/brand-page-maker/models/content-settings-configs.ts +4 -1
  75. package/src/brand-page-maker/models/content-settings.ts +16 -3
  76. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +6 -0
  77. package/src/shared/content-settings/models.ts +3 -0
  78. package/src/shared/content-settings/store/content-settings-store.ts +3 -0
  79. package/src/shared/style-settings/components/StyleSettings.vue +1 -0
  80. package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +0 -13
  81. package/lib/src/metadata-builder/builders/reorder-pages-builder.js +0 -49
  82. package/src/metadata-builder/builders/reorder-pages-builder.ts +0 -80
@@ -0,0 +1,172 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { migration19 } from './migration-19';
3
+ import type { MigrationData } from '../migration.util';
4
+ import { BRAND_PAGE_TYPES } from '../../models';
5
+
6
+ const BUTTON_FILL = 'rgb(255, 222, 89)';
7
+ const USER_CARD = 'rgb(1, 2, 3)';
8
+
9
+ const createMigrationData = (brandPageModel: any): MigrationData => ({
10
+ brandPageModel,
11
+ useOldLogoRenderSize: false,
12
+ });
13
+
14
+ const modelWith = (
15
+ contents: any[],
16
+ buttonFill: string | undefined = BUTTON_FILL,
17
+ brandPageType: string = BRAND_PAGE_TYPES.default,
18
+ ) => ({
19
+ brandPageType,
20
+ styles: { buttonStyles: { style: { backgroundColor: buttonFill } } },
21
+ pages: [{ contents }],
22
+ });
23
+
24
+ describe('migration19', () => {
25
+ test('seeds backgroundColor from the button fill for each container-backed block when unset', async () => {
26
+ const model = modelWith([
27
+ { type: 'mailing-list' },
28
+ { type: 'request-payment' },
29
+ { type: 'support-me' },
30
+ ]);
31
+
32
+ const result = await migration19(createMigrationData(model));
33
+
34
+ (result.brandPageModel as any).pages[0].contents.forEach((c: any) => {
35
+ expect(c.backgroundStyle.backgroundColor).toBe(BUTTON_FILL);
36
+ });
37
+ });
38
+
39
+ test('does not override a backgroundColor that is already set', async () => {
40
+ const model = modelWith([
41
+ {
42
+ type: 'mailing-list',
43
+ backgroundStyle: { backgroundColor: 'rgb(1, 2, 3)' },
44
+ },
45
+ ]);
46
+
47
+ const result = await migration19(createMigrationData(model));
48
+
49
+ expect(
50
+ (result.brandPageModel as any).pages[0].contents[0].backgroundStyle
51
+ .backgroundColor,
52
+ ).toBe('rgb(1, 2, 3)');
53
+ });
54
+
55
+ test('seeds contact-form via cardStyle (not backgroundStyle) so its container colour is detached from the button', async () => {
56
+ const model = modelWith([{ type: 'contact-form' }]);
57
+
58
+ const result = await migration19(createMigrationData(model));
59
+
60
+ const block = (result.brandPageModel as any).pages[0].contents[0];
61
+
62
+ expect(block.backgroundStyle).toBeUndefined();
63
+ expect(block.cardStyle.backgroundColor).toBe(BUTTON_FILL);
64
+ });
65
+
66
+ test('still seeds mailing-list on brand-site (button-fill container on every type)', async () => {
67
+ const model = modelWith(
68
+ [{ type: 'mailing-list' }],
69
+ BUTTON_FILL,
70
+ BRAND_PAGE_TYPES.brandSite,
71
+ );
72
+
73
+ const result = await migration19(createMigrationData(model));
74
+
75
+ expect(
76
+ (result.brandPageModel as any).pages[0].contents[0].backgroundStyle
77
+ .backgroundColor,
78
+ ).toBe(BUTTON_FILL);
79
+ });
80
+
81
+ test('leaves out-of-scope content types untouched', async () => {
82
+ const model = modelWith([{ type: 'banner-section' }, { type: 'text' }]);
83
+
84
+ const result = await migration19(createMigrationData(model));
85
+
86
+ (result.brandPageModel as any).pages[0].contents.forEach((c: any) => {
87
+ expect(c.backgroundStyle).toBeUndefined();
88
+ });
89
+ });
90
+
91
+ test('is a no-op when the button fill colour is undefined', async () => {
92
+ const model = {
93
+ styles: { buttonStyles: { style: {} } },
94
+ pages: [{ contents: [{ type: 'mailing-list' }] }],
95
+ };
96
+
97
+ const result = await migration19(createMigrationData(model));
98
+
99
+ expect(
100
+ (result.brandPageModel as any).pages[0].contents[0].backgroundStyle,
101
+ ).toBeUndefined();
102
+ });
103
+
104
+ test('preserves other backgroundStyle keys when seeding', async () => {
105
+ const model = modelWith([
106
+ { type: 'mailing-list', backgroundStyle: { opacity: '0.5' } },
107
+ ]);
108
+
109
+ const result = await migration19(createMigrationData(model));
110
+
111
+ const bg = (result.brandPageModel as any).pages[0].contents[0]
112
+ .backgroundStyle;
113
+
114
+ expect(bg.backgroundColor).toBe(BUTTON_FILL);
115
+ expect(bg.opacity).toBe('0.5');
116
+ });
117
+
118
+ test('seeds contact-form cardStyle from the button fill on brand-contact', async () => {
119
+ const model = modelWith(
120
+ [{ type: 'contact-form' }],
121
+ BUTTON_FILL,
122
+ BRAND_PAGE_TYPES.brandContact,
123
+ );
124
+
125
+ const result = await migration19(createMigrationData(model));
126
+
127
+ expect(
128
+ (result.brandPageModel as any).pages[0].contents[0].cardStyle
129
+ .backgroundColor,
130
+ ).toBe(BUTTON_FILL);
131
+ });
132
+
133
+ test('is idempotent — does NOT overwrite a contact-form cardStyle colour that is already set', async () => {
134
+ const model = modelWith([
135
+ { type: 'contact-form', cardStyle: { backgroundColor: USER_CARD } },
136
+ ]);
137
+
138
+ const result = await migration19(createMigrationData(model));
139
+
140
+ expect(
141
+ (result.brandPageModel as any).pages[0].contents[0].cardStyle
142
+ .backgroundColor,
143
+ ).toBe(USER_CARD);
144
+ });
145
+
146
+ test('preserves other cardStyle keys while seeding the contact-form colour', async () => {
147
+ const model = modelWith([
148
+ { type: 'contact-form', cardStyle: { borderRadius: '8px' } },
149
+ ]);
150
+
151
+ const result = await migration19(createMigrationData(model));
152
+
153
+ const card = (result.brandPageModel as any).pages[0].contents[0].cardStyle;
154
+
155
+ expect(card.backgroundColor).toBe(BUTTON_FILL);
156
+ expect(card.borderRadius).toBe('8px');
157
+ });
158
+
159
+ test('does NOT touch contact forms on brand-site (keeps its own layout/card behaviour)', async () => {
160
+ const model = modelWith(
161
+ [{ type: 'contact-form' }],
162
+ BUTTON_FILL,
163
+ BRAND_PAGE_TYPES.brandSite,
164
+ );
165
+
166
+ const result = await migration19(createMigrationData(model));
167
+
168
+ expect(
169
+ (result.brandPageModel as any).pages[0].contents[0].cardStyle,
170
+ ).toBeUndefined();
171
+ });
172
+ });
@@ -0,0 +1,65 @@
1
+ import type { MigrationData } from '../migration.util';
2
+ import { BRAND_PAGE_TYPES } from '../../models';
3
+
4
+ const CONTAINER_BACKGROUND_TYPES = new Set<string>([
5
+ 'mailing-list',
6
+ 'request-payment',
7
+ 'support-me',
8
+ ]);
9
+
10
+ type WithBackgroundStyle = {
11
+ backgroundStyle?: { backgroundColor?: string };
12
+ };
13
+
14
+ type WithCardStyle = {
15
+ cardStyle?: { backgroundColor?: string };
16
+ };
17
+
18
+ export const migration19 = async (
19
+ migrationResult: MigrationData,
20
+ ): Promise<MigrationData> => {
21
+ const { brandPageModel } = migrationResult;
22
+
23
+ const buttonFill =
24
+ brandPageModel.styles?.buttonStyles?.style?.backgroundColor;
25
+
26
+ if (buttonFill === undefined) {
27
+ return migrationResult;
28
+ }
29
+
30
+ const isBrandSite =
31
+ brandPageModel.brandPageType === BRAND_PAGE_TYPES.brandSite;
32
+
33
+ brandPageModel.pages.forEach((page) => {
34
+ page.contents.forEach((content) => {
35
+ // Container-backed blocks: seed their own backgroundStyle on every type.
36
+ if (CONTAINER_BACKGROUND_TYPES.has(content.type)) {
37
+ const block = content as WithBackgroundStyle;
38
+
39
+ if (block.backgroundStyle?.backgroundColor === undefined) {
40
+ block.backgroundStyle = {
41
+ ...block.backgroundStyle,
42
+ backgroundColor: buttonFill,
43
+ };
44
+ }
45
+
46
+ return;
47
+ }
48
+
49
+ // Contact form: colour moves to cardStyle — skip on brand-site, which
50
+ // keeps its own layout/card behaviour.
51
+ if (content.type === 'contact-form' && !isBrandSite) {
52
+ const block = content as WithCardStyle;
53
+
54
+ if (block.cardStyle?.backgroundColor === undefined) {
55
+ block.cardStyle = {
56
+ ...block.cardStyle,
57
+ backgroundColor: buttonFill,
58
+ };
59
+ }
60
+ }
61
+ });
62
+ });
63
+
64
+ return migrationResult;
65
+ };
@@ -21,6 +21,7 @@ import { migration15 } from './migration/migration-15';
21
21
  import { migration16 } from './migration/migration-16';
22
22
  import { migration17 } from './migration/migration-17';
23
23
  import { migration18 } from './migration/migration-18';
24
+ import { migration19 } from './migration/migration-19';
24
25
 
25
26
  export interface MigrationData {
26
27
  brandPageModel: BrandPageModel;
@@ -167,6 +168,17 @@ const MIGRATION_TABLE = [
167
168
  description:
168
169
  'BP-5603: backfill stable item ids on all nested items (gallery/section/testimonial/text items, section + footer social links) — the item id is now non-nullable',
169
170
  },
171
+ {
172
+ version: 19,
173
+ migrateFn: migration19,
174
+ // runAlways: re-apply on every load so already-published sites pick up the seed
175
+ // without a version bump. Idempotent — only seeds a colour when unset, so a user
176
+ // colour is never clobbered. Single pass over the model seeds both container types
177
+ // and the contact form.
178
+ runAlways: true,
179
+ description:
180
+ 'BP-5800: seed the button fill colour as each block’s own container colour so it is independent of the site button (existing sites render unchanged) — backgroundStyle for mailing-list, request-payment and support-me (all types); cardStyle for the BP/BC contact form (skipped on brand-site)',
181
+ },
170
182
  ] as MigrationTableItem[];
171
183
 
172
184
  export const GetLatestModelVersion = () =>
@@ -887,6 +887,7 @@ const mapToShopViewModel = (
887
887
  styles: PageStyles,
888
888
  ): ShopViewModel => {
889
889
  const buttonStyles = new ButtonStyles({
890
+ selectedButtonStyleId: styles.buttonStyles.selectedButtonStyleId,
890
891
  style: {
891
892
  ...styles.buttonStyles.style,
892
893
  },
@@ -11,50 +11,58 @@ import {
11
11
 
12
12
  export const contactCardDisplayTypeVisibilityAssessor: VisibilityAssessor<
13
13
  ContactFormContent | undefined
14
+ > = (content, context) => {
15
+ return Boolean(
16
+ content?.layoutStyle &&
17
+ [
18
+ ALIGN_CARD_CENTER_IMAGE,
19
+ ALIGN_CARD_CENTER,
20
+ ALIGN_LEFT_FULL_IMAGE,
21
+ ALIGN_RIGHT_FULL_IMAGE,
22
+ ].includes(content?.layoutStyle) &&
23
+ context?.isBrandSite,
24
+ );
25
+ };
26
+
27
+ // Card colour picker: on brand-page/brand-contact it's the collapsible container
28
+ // colour (shown for every layout); on brand-site it's the card in card layouts.
29
+ export const contactCardColorVisibilityAssessor: VisibilityAssessor<
30
+ ContactFormContent | undefined
14
31
  > = (content, context) => {
15
32
  return (
16
- Boolean(
17
- content?.layoutStyle &&
18
- [
19
- ALIGN_CARD_CENTER_IMAGE,
20
- ALIGN_CARD_CENTER,
21
- ALIGN_LEFT_FULL_IMAGE,
22
- ALIGN_RIGHT_FULL_IMAGE,
23
- ].includes(content?.layoutStyle),
24
- ) && context!.isBrandSite
33
+ !context?.isBrandSite ||
34
+ contactCardDisplayTypeVisibilityAssessor(content, context)
25
35
  );
26
36
  };
27
37
 
28
38
  export const displayTypeVisibilityAssessor: VisibilityAssessor<
29
39
  ContactFormContent | undefined
30
40
  > = (content, context) => {
31
- return Boolean(content?.layoutStyle === '' || context!.isBrandPage);
41
+ return Boolean(content?.layoutStyle === '' || context?.isBrandPage);
32
42
  };
33
43
 
34
44
  export const imageUrlVisibilityAssessor: VisibilityAssessor<
35
45
  ContactFormContent | undefined
36
46
  > = (content, context) => {
37
- return (
38
- Boolean(
39
- content?.layoutStyle &&
40
- [
41
- ALIGN_CARD_CENTER_IMAGE,
42
- ALIGN_LEFT_FULL_IMAGE,
43
- ALIGN_RIGHT_FULL_IMAGE,
44
- ].includes(content?.layoutStyle),
45
- ) && context!.isBrandSite
47
+ return Boolean(
48
+ content?.layoutStyle &&
49
+ [
50
+ ALIGN_CARD_CENTER_IMAGE,
51
+ ALIGN_LEFT_FULL_IMAGE,
52
+ ALIGN_RIGHT_FULL_IMAGE,
53
+ ].includes(content?.layoutStyle) &&
54
+ context?.isBrandSite,
46
55
  );
47
56
  };
48
57
 
49
58
  export const contactBackgroundDisplayTypeVisibilityAssessor: VisibilityAssessor<
50
59
  ContactFormContent | undefined
51
60
  > = (content, context) => {
52
- return (
53
- Boolean(
54
- content?.layoutStyle &&
55
- [ALIGN_CARD_CENTER, ALIGN_CENTERED, TEXT_ONLY].includes(
56
- content?.layoutStyle,
57
- ),
58
- ) && context!.isBrandSite
61
+ return Boolean(
62
+ content?.layoutStyle &&
63
+ [ALIGN_CARD_CENTER, ALIGN_CENTERED, TEXT_ONLY].includes(
64
+ content?.layoutStyle,
65
+ ) &&
66
+ context?.isBrandSite,
59
67
  );
60
68
  };
@@ -129,7 +129,7 @@ import {
129
129
  colorReplacementProfileVisibilityTypeAssessor,
130
130
  colorReplacementIconVisibilityTypeAssessor,
131
131
  imagesSectionCardStyleVisibilityAssessor,
132
- contactCardDisplayTypeVisibilityAssessor,
132
+ contactCardColorVisibilityAssessor,
133
133
  imageUrlVisibilityAssessor,
134
134
  displayTypeVisibilityAssessor,
135
135
  logoFieldVisibilityAssessor,
@@ -139,6 +139,7 @@ import {
139
139
  personalisationOverrideVisibility,
140
140
  } from '../assessors';
141
141
  import {
142
+ contactFormCardColorDefaultGetter,
142
143
  logoBackgroundColorDefaultGetter,
143
144
  paymentFillColorFieldDefaultGetter,
144
145
  paymentTextAndBorderColorFieldDefaultGetter,
@@ -716,6 +717,10 @@ const testimonialReplaceImageSettings =
716
717
  mediaType: MEDIA_TYPES.image,
717
718
  });
718
719
 
720
+ const disableTransparentOffBrandSite = (
721
+ brandPageType: BrandPageType,
722
+ ): boolean => brandPageType !== BRAND_PAGE_TYPES.brandSite;
723
+
719
724
  export const LOGO_SETTINGS_CONFIG = (): ContentSettingsConfig<
720
725
  Omit<
721
726
  LogoContent,
@@ -1824,6 +1829,17 @@ export const MAILING_LIST_CONTENT_SETTINGS_CONFIG =
1824
1829
  titleStyle: DEFAULT_TITLE_STYLE_SETTINGS_FILED_WITH_TITLE(),
1825
1830
  buttonTextStyle: DEFAULT_BUTTON_TEXT_STYLE_FIELD(),
1826
1831
  ...PADDING_CONTROL_FIELDS(SETTINGS_STYLE_FIELD_GROUP_IDS.style),
1832
+ backgroundStyle: {
1833
+ type: 'color',
1834
+ groupId: SETTINGS_STYLE_FIELD_GROUP_IDS.style,
1835
+ defaultValue: {},
1836
+ isInline: true,
1837
+ showToggle: false,
1838
+ title: contentSettingsTr(`backgroundColorTitle`),
1839
+ disableTransparent: true,
1840
+ valueConvertor: backgroundColorConvertor,
1841
+ defaultGetter: paymentFillColorFieldDefaultGetter,
1842
+ },
1827
1843
  },
1828
1844
  isEnabled: true,
1829
1845
  isLocked: false,
@@ -2009,6 +2025,17 @@ export const REQUEST_PAYMENT_CONTENT_SETTINGS_CONFIG =
2009
2025
  label: contentSettingsTr(`buttonTextStyleLabel`),
2010
2026
  },
2011
2027
  ...PADDING_CONTROL_FIELDS(REQUEST_PAYMENT_GROUPS.style),
2028
+ backgroundStyle: {
2029
+ type: 'color',
2030
+ groupId: REQUEST_PAYMENT_GROUPS.style,
2031
+ defaultValue: {},
2032
+ isInline: true,
2033
+ showToggle: false,
2034
+ title: contentSettingsTr(`backgroundColorTitle`),
2035
+ disableTransparent: true,
2036
+ valueConvertor: backgroundColorConvertor,
2037
+ defaultGetter: paymentFillColorFieldDefaultGetter,
2038
+ },
2012
2039
  },
2013
2040
  isEnabled: (features) => features.canAddRequestPaymentContents,
2014
2041
  isLocked: false,
@@ -2077,6 +2104,17 @@ export const SUPPORT_ME_CONTENT_SETTINGS_CONFIG =
2077
2104
  },
2078
2105
  buttonTextStyle: DEFAULT_BUTTON_TEXT_STYLE_FIELD(),
2079
2106
  ...PADDING_CONTROL_FIELDS(SETTINGS_STYLE_FIELD_GROUP_IDS.style),
2107
+ backgroundStyle: {
2108
+ type: 'color',
2109
+ groupId: SETTINGS_STYLE_FIELD_GROUP_IDS.style,
2110
+ defaultValue: {},
2111
+ isInline: true,
2112
+ showToggle: false,
2113
+ title: contentSettingsTr(`backgroundColorTitle`),
2114
+ disableTransparent: true,
2115
+ valueConvertor: backgroundColorConvertor,
2116
+ defaultGetter: paymentFillColorFieldDefaultGetter,
2117
+ },
2080
2118
  },
2081
2119
  isEnabled: (features) => features.canAddRequestPaymentContents,
2082
2120
  isLocked: false,
@@ -2222,7 +2260,8 @@ export const CONTACT_FORM_SETTINGS_CONFIG =
2222
2260
  disableTransparent: true,
2223
2261
  title: contentSettingsTr(`cardColorTitle`),
2224
2262
  valueConvertor: backgroundColorConvertor,
2225
- visibilityAssessor: contactCardDisplayTypeVisibilityAssessor,
2263
+ visibilityAssessor: contactCardColorVisibilityAssessor,
2264
+ defaultGetter: contactFormCardColorDefaultGetter,
2226
2265
  },
2227
2266
  backgroundStyle: {
2228
2267
  type: 'color',
@@ -2231,7 +2270,9 @@ export const CONTACT_FORM_SETTINGS_CONFIG =
2231
2270
  isInline: true,
2232
2271
  showToggle: false,
2233
2272
  title: contentSettingsTr(`backgroundColorTitle`),
2273
+ disableTransparent: disableTransparentOffBrandSite,
2234
2274
  valueConvertor: backgroundColorConvertor,
2275
+ visibilityAssessor: brandSiteTypeVisibilityAssessor,
2235
2276
  },
2236
2277
  },
2237
2278
  isEnabled: true,
@@ -0,0 +1,23 @@
1
+ import { RGBAtoHex } from '@utils/helpers';
2
+ import { BRAND_PAGE_TYPES } from '@brand-page';
3
+ import type { DefaultGetter } from '../models';
4
+
5
+ /**
6
+ * Contact-form "Card color" default (BP-5800). On brand-page/brand-contact the
7
+ * collapsible container takes the button fill, so default the Card color picker to
8
+ * it. On brand-site the Card color applies to the card in card layouts and keeps its
9
+ * own seeded default — so no default here.
10
+ */
11
+ export const contactFormCardColorDefaultGetter: DefaultGetter<
12
+ BrandPageCssStyle
13
+ > = (brandPage): BrandPageCssStyle => {
14
+ if (brandPage.brandPageType === BRAND_PAGE_TYPES.brandSite) {
15
+ return {};
16
+ }
17
+
18
+ return {
19
+ backgroundColor: RGBAtoHex(
20
+ brandPage.styles.buttonStyles.style.backgroundColor,
21
+ ),
22
+ };
23
+ };
@@ -2,3 +2,4 @@ export * from './text-color.default-getter';
2
2
  export * from './payment-fill-color.default-getter';
3
3
  export * from './payment-text-and-border-color.default-getter';
4
4
  export * from './logo-background-fill.default-getter';
5
+ export * from './contact-form-card-color.default-getter';
@@ -379,7 +379,11 @@ export const availableButtonStyleConfigs: ButtonStyleConfig[] = [
379
379
  iconName: 'button-brushstroke',
380
380
  iconViewBox: '0 0 60 20',
381
381
  options: ['buttonFillColor', 'buttonIconColor'],
382
- brandPageType: [BRAND_PAGE_TYPES.default, BRAND_PAGE_TYPES.brandContact],
382
+ brandPageType: [
383
+ BRAND_PAGE_TYPES.default,
384
+ BRAND_PAGE_TYPES.brandContact,
385
+ BRAND_PAGE_TYPES.brandSite,
386
+ ],
383
387
  },
384
388
  {
385
389
  id: 'BUTTON_STYLE_20',
@@ -396,7 +400,11 @@ export const availableButtonStyleConfigs: ButtonStyleConfig[] = [
396
400
  iconName: 'button-arrow',
397
401
  iconViewBox: '0 0 60 20',
398
402
  options: ['buttonFillColor', 'buttonIconColor'],
399
- brandPageType: [BRAND_PAGE_TYPES.default, BRAND_PAGE_TYPES.brandContact],
403
+ brandPageType: [
404
+ BRAND_PAGE_TYPES.default,
405
+ BRAND_PAGE_TYPES.brandContact,
406
+ BRAND_PAGE_TYPES.brandSite,
407
+ ],
400
408
  },
401
409
  {
402
410
  id: 'BUTTON_STYLE_21',
@@ -413,6 +421,10 @@ export const availableButtonStyleConfigs: ButtonStyleConfig[] = [
413
421
  iconName: 'button-paper',
414
422
  iconViewBox: '0 0 60 20',
415
423
  options: ['buttonFillColor', 'buttonIconColor'],
416
- brandPageType: [BRAND_PAGE_TYPES.default, BRAND_PAGE_TYPES.brandContact],
424
+ brandPageType: [
425
+ BRAND_PAGE_TYPES.default,
426
+ BRAND_PAGE_TYPES.brandContact,
427
+ BRAND_PAGE_TYPES.brandSite,
428
+ ],
417
429
  },
418
430
  ];
@@ -137,7 +137,7 @@ export interface ContentSettingsField<TContent> {
137
137
  | ((brandPageType: BrandPageType) => VariantDisplayModes);
138
138
  replaceImageSettings?: ContentReplaceImageSettings<TContent>;
139
139
  showToggle?: boolean;
140
- disableTransparent?: boolean;
140
+ disableTransparent?: boolean | ((brandPageType: BrandPageType) => boolean);
141
141
  valueConvertor?: ValueConvertor<any, any>;
142
142
  canReplace?: boolean;
143
143
  placeholderAssessor?: PlaceholderTypeAssessor<TContent>;
@@ -179,6 +179,9 @@ export interface MultiFieldOption {
179
179
  export interface CreateInitialContentOptions {
180
180
  userState: UserState;
181
181
  brandPageType: BrandPageType;
182
+ // Current global button fill — copied into a new block's own container colour
183
+ // so it renders like the button fill but is detached from it (BP-5800).
184
+ buttonFillColor?: string;
182
185
  }
183
186
 
184
187
  export type CreateInitialContentFunction<TContent> = (
@@ -319,6 +319,9 @@ export const createInitialMailingListContent = (
319
319
  textStyleType: TEXT_STYLE_TYPES.buttons,
320
320
  textAlign: 'center',
321
321
  },
322
+ // Detach the container background from the button fill by copying the current
323
+ // fill as this block's own colour at creation (BP-5800; matches migration-19).
324
+ backgroundStyle: { backgroundColor: options?.buttonFillColor },
322
325
  };
323
326
  };
324
327
 
@@ -364,6 +367,9 @@ export const createInitialRequestPaymentContent = (
364
367
  textStyleType: TEXT_STYLE_TYPES.buttons,
365
368
  textAlign: 'center',
366
369
  },
370
+ // Detach the container background from the button fill by copying the current
371
+ // fill as this block's own colour at creation (BP-5800; matches migration-19).
372
+ backgroundStyle: { backgroundColor: options?.buttonFillColor },
367
373
  };
368
374
  };
369
375
 
@@ -461,6 +467,9 @@ export const createInitialSupportMeContent = (
461
467
  textStyleType: TEXT_STYLE_TYPES.buttons,
462
468
  textAlign: 'center',
463
469
  },
470
+ // Detach the container background from the button fill by copying the current
471
+ // fill as this block's own colour at creation (BP-5800; matches migration-19).
472
+ backgroundStyle: { backgroundColor: options?.buttonFillColor },
464
473
  };
465
474
  };
466
475
 
@@ -551,9 +560,13 @@ export const createInitialContactFormContent: CreateInitialContentFunction<
551
560
  successMessage: contentSettingsTr(`formSuccessMessage`),
552
561
  responseEmail: options?.userState.emailAddress || '',
553
562
  type: 'contact-form',
554
- cardStyle: {
555
- backgroundColor: DEFAULT_LOGO_BACKGROUND_COLOR_RGB,
556
- },
563
+ // brand-site: card layouts default to the logo bg. brand-page/brand-contact:
564
+ // copy the current button fill as the container's own colour so it renders
565
+ // like the button fill but is detached from it (BP-5800; matches migration-19).
566
+ cardStyle:
567
+ options?.brandPageType === BRAND_PAGE_TYPES.brandSite
568
+ ? { backgroundColor: DEFAULT_LOGO_BACKGROUND_COLOR_RGB }
569
+ : { backgroundColor: options?.buttonFillColor },
557
570
  backgroundStyle: {},
558
571
  titleStyle: {
559
572
  applyAutoScale: options?.brandPageType === BRAND_PAGE_TYPES.brandSite,
@@ -212,6 +212,12 @@ export default defineComponent({
212
212
  return this.field.showToggle;
213
213
  },
214
214
  disableTransparent(): boolean {
215
+ // Supports a function of brandPageType (like variant/min/maxLength) so a
216
+ // field can disable transparent only on some website types.
217
+ if (typeof this.field.disableTransparent === 'function') {
218
+ return this.field.disableTransparent(this.brandPageType);
219
+ }
220
+
215
221
  return this.field.disableTransparent || false;
216
222
  },
217
223
  plainTextValue(): string {
@@ -102,6 +102,9 @@ export type FieldGroup = ContentSettingsFieldGroup & {
102
102
  export interface CreateInitialContentOptions {
103
103
  userState: UserState;
104
104
  brandPageType: BrandPageType;
105
+ // Current global button fill — copied into a new block's own container colour
106
+ // so it renders like the button fill but is detached from it (BP-5800).
107
+ buttonFillColor?: string;
105
108
  }
106
109
 
107
110
  export interface AddContentOption<TContent> {
@@ -37,6 +37,7 @@ import {
37
37
  useVideoStore,
38
38
  } from '@brand-page-maker/stores';
39
39
  import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
40
+ import { useUiStyleSettingsStore } from '@shared/style-settings/store';
40
41
  import { useUiSideBarStore } from '../../side-bar/store';
41
42
  import {
42
43
  createDefaultContentItemGroupState,
@@ -653,6 +654,7 @@ export const useUiContentSettingsStore = defineStore('uiContentSettings', {
653
654
  }): ContentItem<Content> | undefined {
654
655
  const userStore = useBrandPageMakerUserStore();
655
656
  const brandPageMakerStore = useBrandPageMakerStore();
657
+ const styleSettingsStore = useUiStyleSettingsStore();
656
658
 
657
659
  const option = this.addContentOptions.find((o) => o.type === type) as
658
660
  | ContentSettingsConfig<any>
@@ -667,6 +669,7 @@ export const useUiContentSettingsStore = defineStore('uiContentSettings', {
667
669
  const content = option.createInitialContent({
668
670
  userState: userStore.$state,
669
671
  brandPageType: brandPageMakerStore.brandPageType,
672
+ buttonFillColor: styleSettingsStore.buttonFillColor,
670
673
  });
671
674
  const settingsConfig = CONTENT_SETTINGS_CONFIGS()[content.type];
672
675
 
@@ -165,6 +165,7 @@
165
165
  <button
166
166
  v-for="(buttonStyleConfig, index) in availableButtonStyleConfigs"
167
167
  :key="index"
168
+ :data-test-button-style="buttonStyleConfig.id"
168
169
  class="c-button-style tw-cursor-pointer tw-border-0 tw-bg-white tw-px-3 tw-rounded tw-transition-all tw-duration-300 tw-transform hover:tw-bg-grayscale-200 tw-h-14"
169
170
  :class="{
170
171
  'c-button-style--selected !tw-shadow-[0_0_0_2px] !tw-shadow-info-500':
@@ -1,13 +0,0 @@
1
- import type { BrandPageModel } from '../../brand-page/models';
2
- import { BaseMetadataBuilder, type BuilderResult, type MetadataBuilderRequest } from '../models';
3
- import type { Logger } from '../logger';
4
- export interface ReorderPagesPayload {
5
- pageOrder: string[];
6
- }
7
- export declare class ReorderPagesBuilder extends BaseMetadataBuilder<ReorderPagesPayload> {
8
- constructor(request: MetadataBuilderRequest<ReorderPagesPayload>, logger?: Logger);
9
- validateAsync(): Promise<{
10
- errors: string[];
11
- }>;
12
- buildAsync(model: BrandPageModel): Promise<BuilderResult>;
13
- }