@designcrowd/library.brand-page 5.16.13-ast-bug-fix-9 → 5.16.13

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 (26) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-C-Kjk7Mf.js → CreatedOnBrandCrowd-de-de-CtO2RJXa.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-Da73K6iE.js → CreatedOnBrandCrowd-en-us-CZ3dIt1i.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CqSmhjNh.js → CreatedOnBrandCrowd-es-es-9ScTkL0Q.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-TpguCMe4.js → CreatedOnBrandCrowd-fr-ca-BWrn1KZs.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-TpguCMe4.js → CreatedOnBrandCrowd-fr-fr-BWrn1KZs.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Dv47A0wQ.js → CreatedOnBrandCrowd-pt-br-w9BZQE0-.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Dv47A0wQ.js → CreatedOnBrandCrowd-pt-pt-w9BZQE0-.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DNaAebBi.js → CreatedOnDcom-de-de-5MYEbeQk.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-qnXpTeaa.js → CreatedOnDcom-en-us-Btw0u0Ks.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-B2sQE-wp.js → CreatedOnDcom-es-es-4YwGIV-M.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BcyuEyOt.js → CreatedOnDcom-fr-ca-BpIS0iFt.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-FFt3_3mc.js → CreatedOnDcom-fr-fr-Bnk2A1-e.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-DZit9sQw.js → CreatedOnDcom-pt-br-CCZRRMaR.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-CXuEvbvE.js → CreatedOnDcom-pt-pt-BG8aaK5S.js} +1 -1
  15. package/lib/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.d.ts +69 -0
  16. package/lib/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.js +122 -0
  17. package/lib/src/css/library.brand-page-brandCrowd.min.css +10 -30
  18. package/lib/src/css/library.brand-page-brandPage.min.css +10 -33
  19. package/lib/src/css/library.brand-page-designCom.min.css +10 -42
  20. package/lib/src/css/library.brand-page-preview.min.css +10 -30
  21. package/lib/src/index.mjs +1 -1
  22. package/lib/src/{lib-CgqwbARM.js → lib-GB7OrH7U.js} +11115 -11101
  23. package/package.json +2 -2
  24. package/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.ts +144 -0
  25. package/src/brand-page/components/image-gallery/masonry/MasonryGallery.vue +16 -135
  26. package/src/brand-page/components/shop/ProductDetailModal.vue +1 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "5.16.13-ast-bug-fix-9",
4
+ "version": "5.16.13",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@ckpack/vue-color": "1.4.1",
58
- "@designcrowd/fe-shared-lib": "1.5.6-ast-masonry-1",
58
+ "@designcrowd/fe-shared-lib": "1.5.2",
59
59
  "@pinia/nuxt": "0.11.0",
60
60
  "@storybook/react": "9.0.4",
61
61
  "@tiptap/extension-bubble-menu": "^2.14.0",
@@ -0,0 +1,144 @@
1
+ import { defineComponent, ref } from 'vue';
2
+ import type { PropType } from 'vue';
3
+ import type { ImageGalleryViewModel } from '../../../view-models';
4
+ import type { DebounceHandle } from 'lodash.debounce';
5
+ import debounce from 'lodash.debounce';
6
+ import type { ImageGalleryImageClickPayload } from '../models';
7
+ import type { BrandPageContext, ImageGalleryItem } from '../../../models';
8
+ import { getImageAltText } from '../../../utils';
9
+
10
+ interface IndexedImageGalleryItem extends ImageGalleryItem {
11
+ id: number;
12
+ }
13
+
14
+ const CONTAINER_WIDTH_MIN_THRESHOLD = 360;
15
+ const DEBOUNCE_WAIT_MS = 100;
16
+ const INIT_COLUMN_WIDTH = 140;
17
+ const MIN_COLUMNS = 2;
18
+ const MAX_COLUMNS = 3;
19
+
20
+ export default defineComponent({
21
+ props: {
22
+ gap: {
23
+ type: Number,
24
+ required: false,
25
+ default: 5,
26
+ },
27
+ viewModel: {
28
+ type: Object as PropType<ImageGalleryViewModel>,
29
+ required: true,
30
+ },
31
+ context: {
32
+ type: Object as PropType<BrandPageContext>,
33
+ required: true,
34
+ },
35
+ contentIndex: {
36
+ type: Number,
37
+ required: false,
38
+ default: undefined,
39
+ },
40
+ },
41
+ setup() {
42
+ const masonryRef = ref<InstanceType<any> | null>(null);
43
+
44
+ return {
45
+ masonryRef,
46
+ };
47
+ },
48
+ emits: ['image-click'],
49
+ data() {
50
+ return {
51
+ columnWidth: INIT_COLUMN_WIDTH,
52
+ resizeDebounceHandler: undefined as DebounceHandle | undefined,
53
+ resizeObserver: undefined as ResizeObserver | undefined,
54
+ imagesBroken: {},
55
+ };
56
+ },
57
+ computed: {
58
+ items(): IndexedImageGalleryItem[] {
59
+ if (!this.viewModel || !Array.isArray(this.viewModel.images)) {
60
+ return [];
61
+ }
62
+
63
+ return this.viewModel.images.map((item, id) => {
64
+ return { ...item, id };
65
+ });
66
+ },
67
+
68
+ altText(): (item: ImageGalleryItem) => string {
69
+ return (item) => {
70
+ return getImageAltText(item, this.context);
71
+ };
72
+ },
73
+ },
74
+ created() {
75
+ if (!this.resizeDebounceHandler) {
76
+ this.resizeDebounceHandler = debounce(() => {
77
+ this.onResize();
78
+ }, DEBOUNCE_WAIT_MS);
79
+ }
80
+ },
81
+ mounted() {
82
+ const $masonry = this.masonryRef;
83
+
84
+ if (this.resizeDebounceHandler && $masonry) {
85
+ this.resizeObserver?.disconnect();
86
+ this.resizeObserver = new ResizeObserver(this.resizeDebounceHandler);
87
+ this.resizeObserver.observe($masonry.$el);
88
+ }
89
+
90
+ this.onResize();
91
+ },
92
+ beforeUnmount() {
93
+ this.resizeObserver?.disconnect();
94
+ this.resizeObserver = undefined;
95
+ },
96
+ watch: {
97
+ viewModel: {
98
+ handler(newVal, oldVal) {
99
+ if (newVal.images !== oldVal.images) {
100
+ this.resetImageBrokenList();
101
+ }
102
+ },
103
+ deep: true,
104
+ },
105
+ },
106
+ methods: {
107
+ onImageClick(selectedIndex: number) {
108
+ const payload: ImageGalleryImageClickPayload = {
109
+ selectedIndex,
110
+ };
111
+
112
+ this.$emit('image-click', payload);
113
+ },
114
+ onResize() {
115
+ const $masonry = this.masonryRef;
116
+
117
+ if (!$masonry) {
118
+ return;
119
+ }
120
+
121
+ const containerWidth = $masonry.$el.clientWidth;
122
+ const column =
123
+ containerWidth < CONTAINER_WIDTH_MIN_THRESHOLD
124
+ ? MIN_COLUMNS
125
+ : MAX_COLUMNS;
126
+
127
+ this.columnWidth = containerWidth / column - this.gap;
128
+
129
+ // Force vue masonry wall to resize when container width changed but document width unchanged
130
+ if ($masonry.$el.$children && $masonry.$el.$children[0]) {
131
+ $masonry.$el.$children[0].$resize();
132
+ }
133
+ },
134
+ onImageError(index: number) {
135
+ this.imagesBroken[index] = true;
136
+ },
137
+ hasImageError(index: number) {
138
+ return this.imagesBroken[index] || false;
139
+ },
140
+ resetImageBrokenList() {
141
+ this.imagesBroken = {};
142
+ },
143
+ },
144
+ });
@@ -2,10 +2,8 @@
2
2
  <Masonry
3
3
  v-if="items.length > 0"
4
4
  ref="masonryRef"
5
- :gap="gap"
5
+ :gap="5"
6
6
  :column-width="columnWidth"
7
- :max-columns="MAX_COLUMNS"
8
- :min-columns="MIN_COLUMNS"
9
7
  :items="items"
10
8
  >
11
9
  <template #item="{ item }">
@@ -31,148 +29,31 @@
31
29
  </template>
32
30
  </Masonry>
33
31
  </template>
34
- <script setup lang="ts">
35
- import {
36
- computed,
37
- ref,
38
- watch,
39
- onMounted,
40
- onBeforeUnmount,
41
- nextTick,
42
- } from 'vue';
32
+ <script>
43
33
  import { Masonry } from '@designcrowd/fe-shared-lib';
44
- import debounce from 'lodash.debounce';
45
- import type { DebounceHandle } from 'lodash.debounce';
34
+ import MasonryGalleryMixin from './MasonryGallery.mixin.ts';
46
35
  import Placeholder from '../../placeholder/Placeholder.vue';
47
36
  import FallbackImage from '../../fallback-image/FallbackImage.vue';
48
37
  import { imageGalleryTr } from '../../../../composables/useTranslate';
49
- import type { ImageGalleryViewModel } from '../../../view-models';
50
- import type { BrandPageContext, ImageGalleryItem } from '../../../models';
51
- import type { ImageGalleryImageClickPayload } from '../models';
52
- import { getImageAltText } from '../../../utils';
53
38
 
54
- interface IndexedImageGalleryItem extends ImageGalleryItem {
55
- id: number;
56
- }
57
-
58
- interface Props {
59
- gap?: number;
60
- viewModel: ImageGalleryViewModel;
61
- context: BrandPageContext;
62
- contentIndex?: number;
63
- }
64
-
65
- const CONTAINER_WIDTH_MIN_THRESHOLD = 360;
66
- const DEBOUNCE_WAIT_MS = 100;
67
- const INIT_COLUMN_WIDTH = 140;
68
- const MIN_COLUMNS = 2;
69
- const MAX_COLUMNS = 3;
70
-
71
- const props = withDefaults(defineProps<Props>(), {
72
- gap: 5,
73
- contentIndex: undefined,
74
- });
75
-
76
- const emit = defineEmits<{
77
- 'image-click': [payload: ImageGalleryImageClickPayload];
78
- }>();
79
-
80
- const masonryRef = ref<InstanceType<typeof Masonry> | null>(null);
81
- const columnWidth = ref(INIT_COLUMN_WIDTH);
82
- const imagesBroken = ref<Record<number, boolean>>({});
83
- let resizeObserver: ResizeObserver | undefined;
84
- let resizeDebounceHandler: DebounceHandle | undefined;
85
-
86
- const items = computed((): IndexedImageGalleryItem[] => {
87
- if (!props.viewModel || !Array.isArray(props.viewModel.images)) {
88
- return [];
89
- }
90
-
91
- return props.viewModel.images.map((item, id) => {
92
- return { ...item, id };
93
- });
94
- });
95
-
96
- const altText = (item: ImageGalleryItem): string => {
97
- return getImageAltText(item, props.context);
98
- };
99
-
100
- const onImageClick = (selectedIndex: number) => {
101
- const payload: ImageGalleryImageClickPayload = {
102
- selectedIndex,
103
- };
104
- emit('image-click', payload);
105
- };
106
-
107
- const onResize = () => {
108
- const $masonry = masonryRef.value;
109
-
110
- if (!$masonry) {
111
- return;
112
- }
113
-
114
- const containerWidth = $masonry.$el.clientWidth;
115
- const column =
116
- containerWidth < CONTAINER_WIDTH_MIN_THRESHOLD ? MIN_COLUMNS : MAX_COLUMNS;
117
-
118
- columnWidth.value = containerWidth / column - props.gap;
119
-
120
- // Force vue masonry wall to resize when container width changed but document width unchanged
121
- if ($masonry.$el.$children && $masonry.$el.$children[0]) {
122
- $masonry.$el.$children[0].$resize();
123
- }
124
- };
125
-
126
- const onImageError = (index: number) => {
127
- imagesBroken.value[index] = true;
128
- };
129
-
130
- const hasImageError = (index: number): boolean => {
131
- return imagesBroken.value[index] || false;
132
- };
133
-
134
- const resetImageBrokenList = () => {
135
- imagesBroken.value = {};
136
- };
137
-
138
- // Watchers
139
- watch(
140
- () => props.viewModel.images,
141
- () => {
142
- resetImageBrokenList();
39
+ export default {
40
+ components: {
41
+ Masonry,
42
+ Placeholder,
43
+ FallbackImage,
143
44
  },
144
- { deep: true },
145
- );
146
-
147
- // Lifecycle
148
- onMounted(() => {
149
- resizeDebounceHandler = debounce(() => {
150
- onResize();
151
- }, DEBOUNCE_WAIT_MS);
152
-
153
- const $masonry = masonryRef.value;
154
-
155
- if (resizeDebounceHandler && $masonry) {
156
- resizeObserver?.disconnect();
157
- resizeObserver = new ResizeObserver(resizeDebounceHandler);
158
- resizeObserver.observe($masonry.$el);
159
- }
160
-
161
- // Initial resize calculation
162
- nextTick(() => {
163
- onResize();
164
- });
165
- });
166
-
167
- onBeforeUnmount(() => {
168
- resizeObserver?.disconnect();
169
- });
45
+ mixins: [MasonryGalleryMixin],
46
+ setup() {
47
+ return {
48
+ ...MasonryGalleryMixin.setup(),
49
+ imageGalleryTr,
50
+ };
51
+ },
52
+ };
170
53
  </script>
171
54
  <style scoped>
172
55
  .c-masonry-img {
173
56
  @apply tw-w-full tw-cursor-pointer;
174
- display: block;
175
- height: auto;
176
57
  }
177
58
  </style>
178
59
  <style>
@@ -47,7 +47,7 @@
47
47
  ref="dropdown"
48
48
  v-model:show="data.showMenu"
49
49
  element-classes="tw-h-10 tw-w-full tw-text-grayscale-800"
50
- menu-element-classes="tw-overflow-y-auto tw-max-h-72 tw-w-full"
50
+ menu-element-classes="tw-overflow-y-auto tw-max-h-72"
51
51
  :title="data.selectedOption.option"
52
52
  @update:show="onShowMenu"
53
53
  >