@designcrowd/library.brand-page 5.17.27 → 5.17.28-ast-padding

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 (92) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DjrwAblu.js → CreatedOnBrandCrowd-de-de-BKiqBMgr.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-Clib9Fmn.js → CreatedOnBrandCrowd-en-us-BE9ztLEZ.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-FAUHtPC2.js → CreatedOnBrandCrowd-es-es-isBp-_KV.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-I1bem2U3.js → CreatedOnBrandCrowd-fr-ca-BHkyP1Ym.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-I1bem2U3.js → CreatedOnBrandCrowd-fr-fr-BHkyP1Ym.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-B4-cqGVL.js → CreatedOnBrandCrowd-pt-br-D4EXIp5p.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-B4-cqGVL.js → CreatedOnBrandCrowd-pt-pt-D4EXIp5p.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DCiTSoZu.js → CreatedOnDcom-de-de-DCyTITAn.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CBwxJf3p.js → CreatedOnDcom-en-us-Bwr-eCqH.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CuWpM6Ui.js → CreatedOnDcom-es-es-DBMJ7xE-.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BPW1Q-90.js → CreatedOnDcom-fr-ca-itsxeehe.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-COX-ZI7v.js → CreatedOnDcom-fr-fr-B8CIK3Dc.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-N6E3uYhE.js → CreatedOnDcom-pt-br-mV_AMZNj.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BUBb5xjA.js → CreatedOnDcom-pt-pt-mwvCkhOd.js} +1 -1
  15. package/lib/src/brand-page/components/background-shape/BackgroundShape.mixin.js +6 -0
  16. package/lib/src/brand-page/components/image-gallery/ImageGallery.mixin.d.ts +4 -0
  17. package/lib/src/brand-page/components/image-gallery/ImageGallery.mixin.js +4 -0
  18. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.d.ts +4 -0
  19. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +4 -1
  20. package/lib/src/brand-page/components/media/Shape.mixin.js +6 -0
  21. package/lib/src/brand-page/components/payment/request-payment/RequestPayment.mixin.d.ts +4 -0
  22. package/lib/src/brand-page/components/payment/request-payment/RequestPayment.mixin.js +4 -0
  23. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.d.ts +4 -0
  24. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.js +4 -1
  25. package/lib/src/brand-page/components/video/Video.mixin.d.ts +4 -0
  26. package/lib/src/brand-page/components/video/Video.mixin.js +4 -0
  27. package/lib/src/brand-page/models/content.model.d.ts +2 -0
  28. package/lib/src/brand-page/utils/content-padding.util.d.ts +13 -0
  29. package/lib/src/brand-page/utils/content-padding.util.js +10 -0
  30. package/lib/src/brand-page/utils/index.d.ts +1 -0
  31. package/lib/src/brand-page/utils/index.js +1 -0
  32. package/lib/src/brand-page/utils/migration/migration-16.d.ts +2 -0
  33. package/lib/src/brand-page/utils/migration/migration-16.js +32 -0
  34. package/lib/src/brand-page/utils/migration.util.js +6 -0
  35. package/lib/src/brand-page-maker/components/admin-logo-settings/AdminLogoSettings.mixin.d.ts +2 -0
  36. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +12 -0
  37. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +14 -0
  38. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +6 -8
  39. package/lib/src/brand-page-maker/constants/config-settings-constant.js +33 -0
  40. package/lib/src/brand-page-maker/models/content-settings.js +22 -0
  41. package/lib/src/{bundled-translations-CNK7l6_v.js → bundled-translations-D4Pw0u0B.js} +1 -1
  42. package/lib/src/bundles/bundled-translations.json +2 -0
  43. package/lib/src/css/library.brand-page-brandCrowd.min.css +115 -137
  44. package/lib/src/css/library.brand-page-brandPage.min.css +115 -137
  45. package/lib/src/css/library.brand-page-designCom.min.css +115 -137
  46. package/lib/src/css/library.brand-page-preview.min.css +115 -137
  47. package/lib/src/index.mjs +1 -1
  48. package/lib/src/{lib-CsTVlu2a.js → lib-ro9XYcgh.js} +19405 -19281
  49. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +14 -0
  50. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +14 -0
  51. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +12 -0
  52. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +12 -0
  53. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +12 -0
  54. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +12 -0
  55. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +16 -0
  56. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +14 -0
  57. package/lib/src/utils/minify-brand-page-metadata.js +11 -1
  58. package/package.json +1 -1
  59. package/src/brand-page/components/background-shape/BackgroundShape.mixin.ts +6 -0
  60. package/src/brand-page/components/background-shape/BackgroundShape.vue +12 -9
  61. package/src/brand-page/components/booking-section/BookingSection.vue +11 -3
  62. package/src/brand-page/components/contact-form/ContactForm.vue +13 -13
  63. package/src/brand-page/components/image-gallery/ImageGallery.mixin.ts +5 -0
  64. package/src/brand-page/components/image-gallery/ImageGallery.vue +1 -1
  65. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +8 -1
  66. package/src/brand-page/components/mailing-list/MailingList.vue +1 -1
  67. package/src/brand-page/components/map/Map.vue +5 -1
  68. package/src/brand-page/components/media/Shape.mixin.ts +6 -0
  69. package/src/brand-page/components/media/Shape.vue +2 -4
  70. package/src/brand-page/components/page/Page.vue +27 -5
  71. package/src/brand-page/components/payment/request-payment/RequestPayment.mixin.ts +5 -0
  72. package/src/brand-page/components/payment/request-payment/RequestPayment.vue +1 -0
  73. package/src/brand-page/components/payment/support-me/SupportMe.mixin.ts +8 -1
  74. package/src/brand-page/components/payment/support-me/SupportMe.vue +1 -0
  75. package/src/brand-page/components/placeholder/Placeholder.vue +39 -100
  76. package/src/brand-page/components/social-links/SocialLinks.vue +7 -3
  77. package/src/brand-page/components/text/Text.vue +12 -5
  78. package/src/brand-page/components/text-media-section/TextMediaSection.vue +11 -3
  79. package/src/brand-page/components/video/Video.mixin.ts +5 -0
  80. package/src/brand-page/components/video/Video.vue +1 -1
  81. package/src/brand-page/models/content.model.ts +2 -0
  82. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +7 -3
  83. package/src/brand-page/utils/content-padding.util.ts +13 -0
  84. package/src/brand-page/utils/index.ts +1 -0
  85. package/src/brand-page/utils/migration/migration-16.ts +42 -0
  86. package/src/brand-page/utils/migration.util.ts +7 -0
  87. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +10 -8
  88. package/src/brand-page-maker/constants/config-settings-constant.ts +39 -0
  89. package/src/brand-page-maker/models/content-settings.ts +22 -0
  90. package/src/bundles/bundled-translations.json +2 -0
  91. package/src/shared/content-settings/components/content-settings/i18n/content-settings.json +2 -0
  92. package/src/utils/minify-brand-page-metadata.ts +11 -1
@@ -1,7 +1,16 @@
1
1
  <template>
2
- <div data-component="background-shape" class="c-shape-background">
2
+ <div
3
+ v-if="objectUrl"
4
+ data-component="background-shape"
5
+ class="c-shape-background"
6
+ >
3
7
  <div :style="backgroundShapesStyle" class="c-shape c-shape-object">
4
- <object class="tw-w-full tw-h-full" :data="objectUrl" />
8
+ <img
9
+ class="tw-w-full tw-h-full"
10
+ :src="objectUrl"
11
+ alt=""
12
+ aria-hidden="true"
13
+ />
5
14
  </div>
6
15
  </div>
7
16
  </template>
@@ -14,16 +23,10 @@ export default {
14
23
  </script>
15
24
  <style scoped>
16
25
  .c-shape-background {
17
- transform: translate3d(0, 0, 0);
18
- position: fixed;
26
+ position: absolute;
19
27
  top: 0;
20
28
  left: 0;
21
29
  width: 100%;
22
- height: 100vh;
23
- }
24
-
25
- .template-preview .c-shape-background,
26
- .device-wrapper .c-shape-background {
27
30
  height: 100%;
28
31
  }
29
32
 
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <section data-component="booking-section">
3
3
  <div
4
- class="tw-relative tw-px-6 tw-py-8"
5
- :style="viewModel.backgroundStyle"
4
+ class="tw-relative tw-px-6"
5
+ :style="[viewModel.backgroundStyle, contentPaddingStyle]"
6
6
  style="container-type: inline-size"
7
7
  >
8
8
  <div
@@ -45,7 +45,11 @@ import type {
45
45
  ButtonViewModel,
46
46
  } from '@brand-page/view-models';
47
47
  import type { BrandPageContext } from '@brand-page/models';
48
- import { getRenderText, escapeContentText } from '@brand-page/utils';
48
+ import {
49
+ getRenderText,
50
+ escapeContentText,
51
+ contentPaddingStyle as toContentPaddingStyle,
52
+ } from '@brand-page/utils';
49
53
  import { hasRTEContent } from '@brand-page-maker/utils';
50
54
  import { hasValidButton as shouldShowButtonUtil } from '../../../utils/validator.util';
51
55
  import Button from '../button/Button.vue';
@@ -71,6 +75,10 @@ const props = defineProps({
71
75
  },
72
76
  });
73
77
 
78
+ const contentPaddingStyle = computed(() =>
79
+ toContentPaddingStyle(props.viewModel),
80
+ );
81
+
74
82
  const renderText = computed((): string => {
75
83
  if (!props.viewModel.description) {
76
84
  return '';
@@ -38,7 +38,7 @@
38
38
  :text-style="viewModel.descriptionStyle"
39
39
  :text="renderText"
40
40
  element="div"
41
- class="tw-text-center tw-mb-2 tw-text-base"
41
+ class="tw-mb-2 tw-text-base"
42
42
  />
43
43
  <div v-if="!isSubmitting">
44
44
  <div
@@ -102,7 +102,7 @@
102
102
  v-if="viewModel.successMessage"
103
103
  :text="renderSuccessText"
104
104
  element="p"
105
- :class="'tw-text-center tw-font-bold tw-my-0.5'"
105
+ :class="'tw-my-0.5'"
106
106
  />
107
107
  </div>
108
108
  </Collapsible>
@@ -124,15 +124,15 @@
124
124
  v-if="viewModel.title"
125
125
  :text-style="viewModel.titleStyle"
126
126
  :text="viewModel.title"
127
- element="div"
128
- class="tw-text-center tw-mb-4 tw-text-base"
127
+ element="h1"
128
+ class="tw-mb-4 tw-text-base"
129
129
  />
130
130
  <TextWrapper
131
131
  v-if="renderText"
132
132
  :text-style="viewModel.descriptionStyle"
133
133
  :text="renderText"
134
134
  element="div"
135
- class="tw-text-center tw-mb-4 tw-text-base"
135
+ class="tw-mb-4 tw-text-base"
136
136
  />
137
137
  <div v-if="!isSubmitting" class="tw-grid tw-grid-cols-2 tw-gap-4">
138
138
  <div
@@ -203,7 +203,7 @@
203
203
  v-if="viewModel.successMessage"
204
204
  :text="renderSuccessText"
205
205
  element="p"
206
- :class="'tw-text-center tw-font-bold tw-my-0.5'"
206
+ :class="'tw-my-0.5'"
207
207
  />
208
208
  </div>
209
209
  </div>
@@ -224,15 +224,15 @@
224
224
  v-if="viewModel.title"
225
225
  :text-style="viewModel.titleStyle"
226
226
  :text="viewModel.title"
227
- element="div"
228
- class="tw-text-center tw-mb-4 tw-text-base"
227
+ element="h1"
228
+ class="tw-mb-4 tw-text-base"
229
229
  />
230
230
  <TextWrapper
231
231
  v-if="renderText"
232
232
  :text-style="viewModel.descriptionStyle"
233
233
  :text="renderText"
234
234
  element="div"
235
- class="tw-text-center tw-mb-4 tw-text-base"
235
+ class="tw-mb-4 tw-text-base"
236
236
  />
237
237
  </div>
238
238
  <form
@@ -317,7 +317,7 @@
317
317
  v-if="viewModel.successMessage"
318
318
  :text="renderSuccessText"
319
319
  element="p"
320
- :class="'tw-text-center tw-font-bold tw-my-0.5'"
320
+ :class="'tw-my-0.5'"
321
321
  />
322
322
  </div>
323
323
  </div>
@@ -358,7 +358,7 @@
358
358
  v-if="viewModel.title && !isSubmitting"
359
359
  :text-style="viewModel.titleStyle"
360
360
  :text="viewModel.title"
361
- element="div"
361
+ element="h1"
362
362
  class="tw-w-full tw-mb-2"
363
363
  />
364
364
  <TextWrapper
@@ -366,7 +366,7 @@
366
366
  :text-style="viewModel.descriptionStyle"
367
367
  :text="renderText"
368
368
  element="div"
369
- class="tw-text-center tw-mb-4 tw-text-base"
369
+ class="tw-mb-4 tw-text-base"
370
370
  />
371
371
  <form @submit.prevent="submitContactForm">
372
372
  <div
@@ -443,7 +443,7 @@
443
443
  v-if="viewModel.successMessage"
444
444
  :text="renderSuccessText"
445
445
  element="p"
446
- :class="'tw-text-center tw-font-bold tw-my-0.5'"
446
+ :class="'tw-my-0.5'"
447
447
  />
448
448
  </div>
449
449
  </div>
@@ -1,6 +1,7 @@
1
1
  import { defineComponent } from 'vue';
2
2
  import type { PropType } from 'vue';
3
3
  import type { ImageGalleryViewModel } from '@brand-page/view-models';
4
+ import { contentPaddingStyle as toContentPaddingStyle } from '@brand-page/utils';
4
5
  import ComponentCommonMixin from '../mixins/component-common.mixin';
5
6
  import ImageModalMixin from '../mixins/image-modal.mixin';
6
7
  import type { ImageGalleryImageClickPayload } from './models';
@@ -34,6 +35,10 @@ export default defineComponent({
34
35
  };
35
36
  },
36
37
  computed: {
38
+ contentPaddingStyle(): { paddingTop: string; paddingBottom: string } {
39
+ return toContentPaddingStyle(this.viewModel);
40
+ },
41
+
37
42
  getContainerStyle(): BrandPageCssStyle {
38
43
  if (this.galleryType === 'carousel') {
39
44
  const maxWidth = this.containerClientWidth
@@ -10,7 +10,7 @@
10
10
  'c-carousel-full-width':
11
11
  viewModel.isFullWidth && isPreview && galleryType === 'carousel',
12
12
  }"
13
- :style="getContainerStyle"
13
+ :style="[getContainerStyle, contentPaddingStyle]"
14
14
  >
15
15
  <component
16
16
  :is="galleryType"
@@ -2,7 +2,10 @@ import { defineComponent } from 'vue';
2
2
  import type { PropType } from 'vue';
3
3
  import type { MailingListViewModel } from '@brand-page/view-models';
4
4
  import brandPageClient from '../../clients/brand-page.client';
5
- import { getEmailValidationError } from '@brand-page/utils';
5
+ import {
6
+ getEmailValidationError,
7
+ contentPaddingStyle as toContentPaddingStyle,
8
+ } from '@brand-page/utils';
6
9
  import type { BrandPageContext } from '@brand-page/models';
7
10
  import {
8
11
  contentSettingsTr,
@@ -61,6 +64,10 @@ export default defineComponent({
61
64
  }
62
65
  },
63
66
  computed: {
67
+ contentPaddingStyle(): { paddingTop: string; paddingBottom: string } {
68
+ return toContentPaddingStyle(this.viewModel);
69
+ },
70
+
64
71
  hasNameError(): boolean {
65
72
  return !!this.nameError;
66
73
  },
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <section>
2
+ <section :style="contentPaddingStyle">
3
3
  <div
4
4
  v-if="show"
5
5
  class="tw-p-4"
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div data-component="map">
2
+ <div data-component="map" :style="contentPaddingStyle">
3
3
  <div
4
4
  class="c-map"
5
5
  :class="{
@@ -22,6 +22,7 @@ import Placeholder from '../placeholder/Placeholder.vue';
22
22
  import type { MapViewModel } from '@brand-page/view-models';
23
23
  import type { BrandPageContext } from '@brand-page/models';
24
24
  import { mapTr } from '@src/composables/useTranslate';
25
+ import { contentPaddingStyle as toContentPaddingStyle } from '@brand-page/utils';
25
26
  import { computed } from 'vue';
26
27
 
27
28
  interface Props {
@@ -37,6 +38,9 @@ const props = withDefaults(defineProps<Props>(), {
37
38
  });
38
39
 
39
40
  const placeId = computed(() => props.viewModel?.address?.placeId);
41
+ const contentPaddingStyle = computed(() =>
42
+ toContentPaddingStyle(props.viewModel),
43
+ );
40
44
  </script>
41
45
  <style scoped>
42
46
  .c-map {
@@ -120,6 +120,12 @@ export default defineComponent({
120
120
  }
121
121
  }
122
122
  },
123
+ beforeUnmount() {
124
+ if (this.svgDataObjectUrl) {
125
+ URL.revokeObjectURL(this.svgDataObjectUrl);
126
+ this.svgDataObjectUrl = '';
127
+ }
128
+ },
123
129
  methods: {
124
130
  applySvgAttributes(svgData: string): string {
125
131
  const attributes: string[] = [];
@@ -1,12 +1,10 @@
1
1
  <template>
2
- <div data-component="shape" :class="imgClasses">
2
+ <div v-if="objectUrl" data-component="shape" :class="imgClasses">
3
3
  <div
4
4
  class="c-shape c-shape-object"
5
5
  :class="{ 'tw-flex tw-justify-center tw-items-center': size }"
6
6
  >
7
- <object :style="objectStyle" :data="objectUrl" />
8
- <!-- Div overlay over object element so that clicks are registered on current dom rather than iframe in side object -->
9
- <div :style="objectStyle" class="tw-absolute tw-pointer-events-none" />
7
+ <img :style="objectStyle" :src="objectUrl" alt="" aria-hidden="true" />
10
8
  </div>
11
9
  </div>
12
10
  </template>
@@ -33,11 +33,17 @@
33
33
  "
34
34
  >
35
35
  <div class="brand-page">
36
- <BackgroundShape
37
- v-for="(shape, i) in backgroundShapes"
38
- :key="`${shape.name}-${i}`"
39
- :view-model="shape"
40
- />
36
+ <div
37
+ v-if="backgroundShapes.length"
38
+ class="brand-page__background-shapes-layer"
39
+ aria-hidden="true"
40
+ >
41
+ <BackgroundShape
42
+ v-for="(shape, i) in backgroundShapes"
43
+ :key="`${shape.name}-${i}`"
44
+ :view-model="shape"
45
+ />
46
+ </div>
41
47
  <div
42
48
  id="preview-page-scroll"
43
49
  class="brand-page__inner tw-overflow-x-hidden tw-overflow-y-auto"
@@ -348,6 +354,22 @@ body {
348
354
  @apply tw-h-full tw-box-border tw-flex tw-flex-col;
349
355
  }
350
356
 
357
+ .brand-page__background-shapes-layer {
358
+ position: fixed;
359
+ top: 0;
360
+ left: 0;
361
+ width: 100%;
362
+ height: 100vh;
363
+ pointer-events: none;
364
+ transform: translate3d(0, 0, 0);
365
+ contain: layout paint;
366
+ }
367
+
368
+ .template-preview .brand-page__background-shapes-layer,
369
+ .device-wrapper .brand-page__background-shapes-layer {
370
+ height: 100%;
371
+ }
372
+
351
373
  .brand-page__inner--default {
352
374
  @apply tw-h-full tw-flex tw-flex-col tw-relative tw-z-10;
353
375
  }
@@ -14,6 +14,7 @@ import type { RequestPaymentViewModel } from '../../../view-models';
14
14
  import type { PaymentRequestDetails } from '../Payment.mixin';
15
15
  import { DEFAULT_CURRENCY_SYMBOL } from '../../../constants';
16
16
  import { addOpacityToHex } from '../../../utils/color.util';
17
+ import { contentPaddingStyle as toContentPaddingStyle } from '../../../utils';
17
18
  import { RGBAtoHex } from '@utils/helpers';
18
19
 
19
20
  const MAX_CUSTOM_REQUEST_CHARS = 500;
@@ -42,6 +43,10 @@ export default defineComponent({
42
43
  };
43
44
  },
44
45
  computed: {
46
+ contentPaddingStyle(): { paddingTop: string; paddingBottom: string } {
47
+ return toContentPaddingStyle(this.viewModel);
48
+ },
49
+
45
50
  isCustomerRequestDetailsValid(): boolean {
46
51
  return (
47
52
  !this.viewModel.requestPaymentConfig.isCustomerRequestDetailsEnabled ||
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  data-component="request-payment"
4
+ :style="contentPaddingStyle"
4
5
  :class="{
5
6
  'tw-my-8': context.isBrandSite,
6
7
  'tw-mb-4': context.isBrandPageOrIsBrandContact,
@@ -4,7 +4,10 @@ import { SUPPORT_ME_CUSTOM_PRODUCT_NAME } from '../../../constants';
4
4
  import type { BrandPageContext, PaymentOption } from '../../../models';
5
5
  import type { SupportMeViewModel } from '../../../view-models';
6
6
  import type { PaymentRequestDetails } from '../Payment.mixin';
7
- import { isPaymentAmountValid } from '../../../utils';
7
+ import {
8
+ isPaymentAmountValid,
9
+ contentPaddingStyle as toContentPaddingStyle,
10
+ } from '../../../utils';
8
11
  import {
9
12
  DEFAULT_CURRENCY_SYMBOL,
10
13
  DEFAULT_CURRENCY_CODE,
@@ -33,6 +36,10 @@ export default defineComponent({
33
36
  };
34
37
  },
35
38
  computed: {
39
+ contentPaddingStyle(): { paddingTop: string; paddingBottom: string } {
40
+ return toContentPaddingStyle(this.viewModel);
41
+ },
42
+
36
43
  isCustomAmountFieldVisible(): boolean {
37
44
  return this.viewModel.supportMeConfig.paymentOptions.some(
38
45
  (o) => o.name === SUPPORT_ME_CUSTOM_PRODUCT_NAME,
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  data-component="support-me"
4
+ :style="contentPaddingStyle"
4
5
  :class="{
5
6
  'tw-my-8': context.isBrandSite,
6
7
  'tw-mb-4': context.isBrandPageOrIsBrandContact,
@@ -5,15 +5,20 @@
5
5
  class="c-placeholder"
6
6
  :style="style"
7
7
  >
8
- <div class="c-placeholder__content" :style="cssProps" />
8
+ <svg
9
+ class="c-placeholder__icon"
10
+ viewBox="0 0 100 100"
11
+ preserveAspectRatio="none"
12
+ aria-hidden="true"
13
+ >
14
+ <rect class="c-placeholder__fill" width="100" height="100" />
15
+ <line x1="0" y1="0" x2="100" y2="100" />
16
+ <line x1="100" y1="0" x2="0" y2="100" />
17
+ </svg>
9
18
  </div>
10
19
  </template>
11
20
  <script>
12
- import debounce from 'lodash.debounce';
13
- const RESIZE_DEBOUNCE_WAIT_MS = 5;
14
-
15
21
  export default {
16
- components: {},
17
22
  props: {
18
23
  minHeight: {
19
24
  type: [Number, Boolean],
@@ -26,48 +31,14 @@ export default {
26
31
  required: false,
27
32
  },
28
33
  },
29
- data() {
30
- return {
31
- height: 0,
32
- width: 0,
33
- debouncedOnResize: undefined,
34
- };
35
- },
36
34
  computed: {
37
35
  style() {
38
36
  return {
39
37
  minHeight: this.minHeight ? `${this.minHeight}px` : undefined,
40
38
  minWidth: this.minWidth ? `${this.minWidth}px` : undefined,
41
- '--height': `${this.height}px`,
42
- '--width': `${this.width}px`,
43
- };
44
- },
45
- cssProps() {
46
- return {
47
- '--height': `${this.height}px`,
48
- '--width': `${this.width}px`,
49
39
  };
50
40
  },
51
41
  },
52
- mounted() {
53
- this.debouncedOnResize = debounce(this.onResize, RESIZE_DEBOUNCE_WAIT_MS);
54
-
55
- if (this.$refs.placeholder) {
56
- new ResizeObserver(this.debouncedOnResize).observe(
57
- this.$refs.placeholder,
58
- );
59
- }
60
-
61
- this.onResize();
62
- },
63
- methods: {
64
- onResize() {
65
- if (this.$refs.placeholder) {
66
- this.height = this.$refs.placeholder.clientHeight;
67
- this.width = this.$refs.placeholder.clientWidth;
68
- }
69
- },
70
- },
71
42
  };
72
43
  </script>
73
44
  <style scoped>
@@ -76,73 +47,41 @@ export default {
76
47
  display: block;
77
48
  }
78
49
 
79
- .c-placeholder__content {
50
+ /*
51
+ * Provide a positioning context for the absolute SVG icon — but only when the
52
+ * caller hasn't already positioned the placeholder itself. Some callers pass
53
+ * `tw-absolute` (e.g. the big-image banner uses it to fill the banner as a
54
+ * background); a blanket `position: relative` here would out-specify that
55
+ * utility and break the layout. An already-positioned placeholder is its own
56
+ * containing block, so the SVG fills it either way.
57
+ */
58
+ .c-placeholder:not(.tw-absolute):not(.tw-fixed) {
80
59
  position: relative;
81
- display: block;
82
- }
83
- .c-placeholder__content::after {
84
- --size: 1px;
85
- --n-size: -1px;
86
- --border: calc(var(--n-size) * 2 + var(--height) / 2);
87
- --border-left: calc(var(--n-size) * 2 + var(--width) / 2);
88
- --tw-border-opacity: 0.5;
89
- position: absolute;
90
- top: calc(var(--size) * 2);
91
- left: var(--size);
92
- content: ' ';
93
- border-top: var(--border) solid transparent;
94
- border-bottom: var(--border) solid transparent;
95
- border-left: var(--border-left) solid
96
- rgb(208 208 208 / var(--tw-border-opacity));
97
- }
98
- .c-placeholder__content::before {
99
- --size: 1px;
100
- --n-size: -1px;
101
- --border: calc(var(--n-size) * 2 + var(--height) / 2);
102
- --border-right: calc(var(--n-size) * 2 + var(--width) / 2);
103
- --tw-border-opacity: 0.5;
104
- position: absolute;
105
- top: calc(var(--size) * 2);
106
- right: var(--size);
107
- content: ' ';
108
- border-top: var(--border) solid transparent;
109
- border-bottom: var(--border) solid transparent;
110
- border-right: var(--border-right) solid
111
- rgb(208 208 208 / var(--tw-border-opacity));
112
60
  }
113
61
 
114
- .c-placeholder::after {
115
- --size: 1px;
116
- --n-size: -1px;
117
- --border: calc(var(--n-size) * 2 + var(--width) / 2);
118
- --border-right: calc(var(--n-size) * 2 + var(--height) / 2);
119
- --tw-border-opacity: 0.5;
62
+ /*
63
+ * The X icon is drawn as an SVG with preserveAspectRatio="none" so the
64
+ * diagonals always run corner-to-corner regardless of the box aspect ratio
65
+ * (square thumbnails through full-width 2/1 banners). vector-effect keeps the
66
+ * stroke an even width while the viewBox is stretched non-uniformly. The SVG
67
+ * is absolutely positioned so it fills the box sized by min-height / the
68
+ * caller's aspect-ratio class rather than driving the height itself.
69
+ */
70
+ .c-placeholder__icon {
120
71
  position: absolute;
121
- left: calc(var(--size) * 2);
122
- top: var(--size);
123
- content: ' ';
124
- border-left: var(--border) solid transparent;
125
- border-right: var(--border) solid transparent;
126
- border-top: var(--border-right) solid
127
- rgb(208 208 208 / var(--tw-border-opacity));
72
+ inset: 0;
73
+ display: block;
74
+ width: 100%;
75
+ height: 100%;
128
76
  }
129
- .c-placeholder::before {
130
- --size: 1px;
131
- --n-size: -1px;
132
- --border: calc(var(--n-size) * 2 + var(--width) / 2);
133
- --border-bottom: calc(var(--n-size) * 2 + var(--height) / 2);
134
- --tw-border-opacity: 0.5;
135
- position: absolute;
136
- left: calc(var(--size) * 2);
137
- bottom: var(--size);
138
- content: ' ';
139
- border-left: var(--border) solid transparent;
140
- border-right: var(--border) solid transparent;
141
- border-bottom: var(--border-bottom) solid
142
- rgb(208 208 208 / var(--tw-border-opacity));
77
+
78
+ .c-placeholder__fill {
79
+ fill: rgb(208 208 208 / 0.5);
143
80
  }
144
81
 
145
- .c-placeholder__content > * {
146
- padding-bottom: 0.5rem;
82
+ .c-placeholder__icon line {
83
+ stroke: #fff;
84
+ stroke-width: 2;
85
+ vector-effect: non-scaling-stroke;
147
86
  }
148
87
  </style>
@@ -1,11 +1,10 @@
1
1
  <template>
2
2
  <div data-component="social-links">
3
3
  <div
4
- class="tw-pb-8"
5
4
  :class="{
6
5
  'tw-mb-4': context.isBrandPageOrIsBrandContact,
7
6
  }"
8
- :style="containerStyles"
7
+ :style="[containerStyles, contentPaddingStyle]"
9
8
  style="container-type: inline-size"
10
9
  >
11
10
  <TextWrapper
@@ -14,7 +13,7 @@
14
13
  :text="title"
15
14
  element="h1"
16
15
  :class="textAlignClass"
17
- class="tw-py-8"
16
+ class="tw-pb-8"
18
17
  />
19
18
  <SocialLinksItems
20
19
  :id="id"
@@ -34,6 +33,7 @@ import TextWrapper from '../text-wrapper/TextWrapper.vue';
34
33
  import type { SocialLinksViewModel } from 'src/brand-page/view-models';
35
34
  import { SOCIAL_LINKS_ICON_DISPLAY_STYLES } from '@brand-page/models';
36
35
  import type { BrandPageContext, LinksItem } from '@brand-page/models';
36
+ import { contentPaddingStyle as toContentPaddingStyle } from '@brand-page/utils';
37
37
  import { computed } from 'vue';
38
38
 
39
39
  const props = withDefaults(
@@ -51,6 +51,10 @@ const containerStyles = computed((): BrandPageCssStyle => {
51
51
  return props.viewModel.backgroundStyles || {};
52
52
  });
53
53
 
54
+ const contentPaddingStyle = computed(() =>
55
+ toContentPaddingStyle(props.viewModel),
56
+ );
57
+
54
58
  const iconStyle = computed((): BrandPageCssStyle => {
55
59
  return props.viewModel.iconFillStyles || {};
56
60
  });
@@ -2,7 +2,7 @@
2
2
  <div>
3
3
  <div
4
4
  v-if="!context.isBrandSite"
5
- :style="containerStyle"
5
+ :style="[containerStyle, contentPaddingStyle]"
6
6
  :class="{
7
7
  [containerClasses]: true,
8
8
  }"
@@ -15,9 +15,9 @@
15
15
  data-test-tag="text-content-text"
16
16
  />
17
17
  </div>
18
- <div v-else :style="containerStyle">
18
+ <div v-else :style="[containerStyle, contentPaddingStyle]">
19
19
  <div
20
- class="c-text-container tw-py-3 tw-px-6 grid-container tw-gap-4"
20
+ class="c-text-container tw-px-6 grid-container tw-gap-4"
21
21
  :class="{
22
22
  [containerClasses]: true,
23
23
  [gridClass]: context.isBrandSite,
@@ -41,7 +41,10 @@
41
41
  import TextWrapper from '../text-wrapper/TextWrapper.vue';
42
42
  import { computed } from 'vue';
43
43
  import type { TextViewModel } from '@brand-page/view-models';
44
- import { getRenderText } from '@brand-page/utils';
44
+ import {
45
+ getRenderText,
46
+ contentPaddingStyle as toContentPaddingStyle,
47
+ } from '@brand-page/utils';
45
48
  import type { BrandPageContext } from '@brand-page/models';
46
49
 
47
50
  interface Props {
@@ -51,6 +54,10 @@ interface Props {
51
54
 
52
55
  const props = defineProps<Props>();
53
56
 
57
+ const contentPaddingStyle = computed(() =>
58
+ toContentPaddingStyle(props.viewModel),
59
+ );
60
+
54
61
  const containerStyle = computed<any>(() => {
55
62
  const containerStyles = {} as BrandPageCssStyle;
56
63
 
@@ -83,7 +90,7 @@ const containerClasses = computed(() => {
83
90
  return '';
84
91
  }
85
92
 
86
- return 'tw-py-3 tw-px-6';
93
+ return 'tw-px-6';
87
94
  });
88
95
 
89
96
  const renderText = computed(() => {