@shopgate/engage 7.32.0-beta.5 → 7.32.0-beta.7
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/account/components/Profile/ProfileAddressCard.d.ts.map +1 -1
- package/account/components/Profile/ProfileAddressCard.js +1 -0
- package/admin-preview/components/FrontendSettingsPreviewBridge/types.d.ts +2 -2
- package/admin-preview/components/FrontendSettingsPreviewBridge/types.d.ts.map +1 -1
- package/back-in-stock/components/Subscriptions/components/Subscription/index.js +2 -5
- package/cart/components/CartItem/CartItemProductLayout.js +1 -1
- package/cart/components/CartItem/CartItemProductLayoutWide.js +2 -2
- package/cart/components/CartItems/CartItems.js +8 -10
- package/cart/components/CartItems/CartItemsSubstitution.js +3 -2
- package/category/components/CategoryImage/index.js +11 -15
- package/components/Card/Card.d.ts +27 -0
- package/components/Card/Card.d.ts.map +1 -0
- package/components/Card/Card.js +57 -0
- package/components/Card/index.d.ts +4 -0
- package/components/Card/index.d.ts.map +1 -0
- package/components/Card/index.js +2 -0
- package/components/Card/spec.d.ts +2 -0
- package/components/Card/spec.d.ts.map +1 -0
- package/components/Card/spec.js +128 -0
- package/components/Card/useCardAppearance.d.ts +11 -0
- package/components/Card/useCardAppearance.d.ts.map +1 -0
- package/components/Card/useCardAppearance.js +22 -0
- package/components/Paper/Paper.d.ts +49 -0
- package/components/Paper/Paper.d.ts.map +1 -0
- package/components/Paper/Paper.js +64 -0
- package/components/Paper/index.d.ts +3 -0
- package/components/Paper/index.d.ts.map +1 -0
- package/components/Paper/index.js +1 -0
- package/components/Paper/spec.d.ts +2 -0
- package/components/Paper/spec.d.ts.map +1 -0
- package/components/Paper/spec.js +131 -0
- package/components/RadioCard/RadioCard.d.ts.map +1 -1
- package/components/RadioCard/RadioCard.js +2 -1
- package/components/constants.d.ts +6 -0
- package/components/constants.d.ts.map +1 -0
- package/components/index.d.ts +4 -1
- package/components/index.d.ts.map +1 -1
- package/components/index.js +3 -2
- package/core/helpers/getFullImageSource.d.ts +5 -1
- package/core/helpers/getFullImageSource.d.ts.map +1 -1
- package/core/helpers/getFullImageSource.js +30 -14
- package/core/helpers/i18n.d.ts +4 -0
- package/core/helpers/i18n.d.ts.map +1 -1
- package/core/helpers/i18n.js +3 -0
- package/core/hooks/html/useLoadImage.d.ts +3 -3
- package/core/hooks/html/useLoadImage.d.ts.map +1 -1
- package/core/hooks/html/useLoadImage.js +2 -2
- package/favorites/components/Item/Item.d.ts +1 -1
- package/favorites/components/Item/Item.d.ts.map +1 -1
- package/favorites/components/Item/Item.js +2 -5
- package/favorites/components/List/List.d.ts +1 -1
- package/locations/components/StoreList/StoreListProduct.js +2 -3
- package/orders/components/OrderHistory/OrderHistoryList.d.ts.map +1 -1
- package/orders/components/OrderHistory/OrderHistoryList.js +8 -9
- package/orders/components/OrderHistory/OrderHistoryTable.d.ts.map +1 -1
- package/orders/components/OrderHistory/OrderHistoryTable.js +4 -0
- package/package.json +8 -8
- package/page/widgets/ProductSlider/ProductSlider.js +1 -15
- package/product/components/Media/FeaturedMedia.js +7 -1
- package/product/components/Media/MediaImage.js +24 -23
- package/product/components/Media/MediaPlaceholder.js +4 -7
- package/product/components/MediaSlider/components/MediaImage/index.js +6 -2
- package/product/components/MediaSlider/constants.js +1 -12
- package/product/components/ProductCard/index.js +29 -23
- package/product/components/ProductGrid/components/Item/components/ItemDetails/index.js +6 -3
- package/product/components/ProductGrid/components/Item/components/ItemImage/index.js +2 -5
- package/product/components/ProductGrid/components/Item/components/ItemName/index.js +5 -1
- package/product/components/ProductGrid/components/Item/components/ItemName/spec.js +19 -1
- package/product/components/ProductGrid/components/Item/index.js +9 -1
- package/product/components/ProductGrid/hooks.d.ts +0 -7
- package/product/components/ProductGrid/hooks.d.ts.map +1 -1
- package/product/components/ProductGrid/hooks.js +9 -10
- package/product/components/ProductImage/ProductImage.d.ts +42 -0
- package/product/components/ProductImage/ProductImage.d.ts.map +1 -0
- package/product/components/ProductImage/ProductImage.js +153 -0
- package/product/components/ProductImage/ProductImagePlaceholder.d.ts +23 -0
- package/product/components/ProductImage/ProductImagePlaceholder.d.ts.map +1 -0
- package/product/components/ProductImage/ProductImagePlaceholder.js +9 -14
- package/product/components/ProductImage/constants.d.ts +7 -0
- package/product/components/ProductImage/constants.d.ts.map +1 -0
- package/product/components/ProductImage/constants.js +6 -0
- package/product/components/ProductImage/hooks.d.ts +8 -0
- package/product/components/ProductImage/hooks.d.ts.map +1 -0
- package/product/components/ProductImage/hooks.js +32 -0
- package/product/components/ProductImage/index.d.ts +3 -0
- package/product/components/ProductImage/index.d.ts.map +1 -0
- package/product/components/ProductImage/index.js +1 -201
- package/product/components/ProductImage/spec.js +115 -60
- package/product/components/ProductList/components/Item/index.js +5 -3
- package/product/components/ProductRatingStars/ProductRatingStars.js +2 -4
- package/product/components/ProductSlider/constants.d.ts +3 -0
- package/product/components/ProductSlider/constants.d.ts.map +1 -0
- package/product/components/ProductSlider/constants.js +2 -0
- package/product/components/ProductSlider/hooks.d.ts +7 -0
- package/product/components/ProductSlider/hooks.d.ts.map +1 -0
- package/product/components/ProductSlider/hooks.js +40 -0
- package/product/components/ProductSlider/index.js +8 -8
- package/product/components/ProductSlider/spec.js +2 -2
- package/product/components/Rating/index.js +2 -4
- package/product/components/RelationsSlider/RelationsSliderContent.js +3 -2
- package/product/components/RelationsSlider/constants.d.ts +3 -0
- package/product/components/RelationsSlider/constants.d.ts.map +1 -0
- package/product/components/RelationsSlider/constants.js +2 -1
- package/product/components/RelationsSlider/hooks.d.ts +6 -0
- package/product/components/RelationsSlider/hooks.d.ts.map +1 -0
- package/product/components/RelationsSlider/hooks.js +34 -0
- package/product/helpers/index.js +29 -11
- package/product/hooks/index.js +3 -1
- package/product/hooks/useLoadProductImage.js +4 -2
- package/product/hooks/useShowEmptyRatingStars.d.ts +7 -0
- package/product/hooks/useShowEmptyRatingStars.d.ts.map +1 -0
- package/product/hooks/useShowEmptyRatingStars.js +21 -0
- package/product/index.js +0 -1
- package/settings/action-creators/appSettings.d.ts +3 -3
- package/settings/action-creators/appSettings.d.ts.map +1 -1
- package/settings/constants/appSettings.d.ts +3 -0
- package/settings/constants/appSettings.d.ts.map +1 -1
- package/settings/constants/appSettings.js +6 -1
- package/settings/constants/imageSettings.d.ts +52 -0
- package/settings/constants/imageSettings.d.ts.map +1 -0
- package/settings/constants/imageSettings.js +69 -0
- package/settings/helpers/index.d.ts +3 -0
- package/settings/helpers/index.d.ts.map +1 -0
- package/settings/helpers/index.js +1 -0
- package/settings/helpers/resolveImageSettings.d.ts +70 -0
- package/settings/helpers/resolveImageSettings.d.ts.map +1 -0
- package/settings/helpers/resolveImageSettings.js +171 -0
- package/settings/helpers/toImageQuality.d.ts +7 -0
- package/settings/helpers/toImageQuality.d.ts.map +1 -0
- package/settings/helpers/toImageQuality.js +44 -0
- package/settings/helpers/toThumborColor.d.ts +15 -0
- package/settings/helpers/toThumborColor.d.ts.map +1 -0
- package/settings/helpers/toThumborColor.js +51 -0
- package/settings/hooks/index.d.ts +2 -0
- package/settings/hooks/index.d.ts.map +1 -0
- package/settings/hooks/index.js +1 -0
- package/settings/hooks/useImageSettings.d.ts +28 -0
- package/settings/hooks/useImageSettings.d.ts.map +1 -0
- package/settings/hooks/useImageSettings.js +39 -0
- package/settings/reducers/appSettings.d.ts.map +1 -1
- package/settings/reducers/appSettings.js +79 -11
- package/settings/reducers/index.d.ts +3 -3
- package/settings/selectors/appSettings.d.ts +71 -1
- package/settings/selectors/appSettings.d.ts.map +1 -1
- package/settings/selectors/appSettings.js +41 -1
- package/settings/types/appSettings.d.ts +192 -9
- package/settings/types/appSettings.d.ts.map +1 -1
- package/styles/index.d.ts +1 -1
- package/styles/index.d.ts.map +1 -1
- package/styles/reset/root.js +23 -4
- package/styles/reset/typographyCustomProps.d.ts +12 -0
- package/styles/reset/typographyCustomProps.d.ts.map +1 -0
- package/styles/reset/typographyCustomProps.js +11 -0
- package/styles/theme/createTheme/createComponents.types.d.ts +50 -0
- package/styles/theme/createTheme/createComponents.types.d.ts.map +1 -1
- package/styles/theme/createTheme/createComponents.types.js +50 -0
- package/styles/theme/createTheme/createCssVarsForColorSchemeThemes.d.ts.map +1 -1
- package/styles/theme/createTheme/createCssVarsForColorSchemeThemes.js +5 -1
- package/styles/theme/createTheme/createPalette.types.d.ts +4 -0
- package/styles/theme/createTheme/createPalette.types.d.ts.map +1 -1
- package/styles/theme/createTheme/createPalette.types.js +5 -1
- package/styles/theme/createTheme/createShape.d.ts +4 -0
- package/styles/theme/createTheme/createShape.d.ts.map +1 -1
- package/styles/theme/createTheme/createShape.js +2 -1
- package/styles/theme/createTheme/createThemeFromColorScheme.d.ts.map +1 -1
- package/styles/theme/createTheme/createThemeFromColorScheme.js +2 -1
- package/styles/theme/createTheme/createTypography.js +1 -0
- package/styles/theme/createTheme/helpers/cssVarsParser.d.ts.map +1 -1
- package/styles/theme/createTheme/helpers/cssVarsParser.js +10 -3
- package/styles/theme/createTheme/shadows.d.ts +11 -1
- package/styles/theme/createTheme/shadows.d.ts.map +1 -1
- package/styles/theme/createTheme/shadows.js +41 -7
- package/styles/theme/createTheme/types.d.ts +5 -1
- package/styles/theme/createTheme/types.d.ts.map +1 -1
- package/styles/theme/index.d.ts +1 -0
- package/styles/theme/index.d.ts.map +1 -1
- package/product/collections/index.js +0 -1
- package/product/components/EffectivityDates/constants.d.ts +0 -3
- package/product/components/EffectivityDates/constants.d.ts.map +0 -1
- package/product/components/EffectivityDates/helpers.d.ts +0 -6
- package/product/components/EffectivityDates/helpers.d.ts.map +0 -1
- package/product/components/Media/helpers.d.ts +0 -2
- package/product/components/Media/helpers.d.ts.map +0 -1
- package/product/components/ProductImage/connector.js +0 -12
- package/product/helpers/index.d.ts +0 -13
- package/product/helpers/index.d.ts.map +0 -1
- package/product/helpers/redirects.d.ts +0 -2
- package/product/helpers/redirects.d.ts.map +0 -1
- package/product/selectors/helpers/filterProperties.d.ts +0 -8
- package/product/selectors/helpers/filterProperties.d.ts.map +0 -1
- package/product/selectors/helpers/index.d.ts +0 -3
- package/product/selectors/helpers/index.d.ts.map +0 -1
- package/product/selectors/helpers/wrapMemoizedSelector.d.ts +0 -2
- package/product/selectors/helpers/wrapMemoizedSelector.d.ts.map +0 -1
- package/product/selectors/product.d.ts +0 -112
- package/product/selectors/product.d.ts.map +0 -1
|
@@ -1,87 +1,142 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { shallow } from 'enzyme';
|
|
3
3
|
import Image from '@shopgate/pwa-common/components/Image';
|
|
4
|
-
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
5
4
|
import PlaceholderIcon from '@shopgate/pwa-ui-shared/icons/PlaceholderIcon';
|
|
6
5
|
import ProductImagePlaceholder from "./ProductImagePlaceholder";
|
|
7
6
|
import ProductImage from "./index";
|
|
7
|
+
import { useProductImageShadow } from "./hooks";
|
|
8
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
9
|
jest.unmock('@shopgate/pwa-core');
|
|
10
10
|
jest.mock("../../../core/hocs/withWidgetSettings");
|
|
11
11
|
jest.mock('@shopgate/pwa-common/helpers/config');
|
|
12
|
-
|
|
12
|
+
// Shallow renders have no store; the component only reads the shop wide placeholder from it.
|
|
13
|
+
jest.mock('react-redux', () => ({
|
|
14
|
+
...jest.requireActual('react-redux'),
|
|
15
|
+
useSelector: () => null
|
|
16
|
+
}));
|
|
13
17
|
jest.mock('@shopgate/engage/components', () => ({
|
|
14
18
|
Image: () => null
|
|
15
19
|
}));
|
|
20
|
+
|
|
21
|
+
// These are shallow renders, so there is no Provider for the hook to read the store from. The
|
|
22
|
+
// mock returns what the resolver produces before the app settings are hydrated: the built-in
|
|
23
|
+
// resolutions, and no ratio, so the Image derives it from the largest resolution as before.
|
|
24
|
+
jest.mock("./hooks", () => ({
|
|
25
|
+
useProductImageShadow: jest.fn(() => false)
|
|
26
|
+
}));
|
|
27
|
+
jest.mock('@shopgate/engage/settings/hooks', () => ({
|
|
28
|
+
useProductImageSettings: () => ({
|
|
29
|
+
pdp: {
|
|
30
|
+
resolutions: [{
|
|
31
|
+
width: 440,
|
|
32
|
+
height: 440
|
|
33
|
+
}, {
|
|
34
|
+
width: 1024,
|
|
35
|
+
height: 1024
|
|
36
|
+
}],
|
|
37
|
+
ratio: null
|
|
38
|
+
},
|
|
39
|
+
gallery: {
|
|
40
|
+
resolutions: [{
|
|
41
|
+
width: 1024,
|
|
42
|
+
height: 1024
|
|
43
|
+
}, {
|
|
44
|
+
width: 2048,
|
|
45
|
+
height: 2048
|
|
46
|
+
}],
|
|
47
|
+
ratio: null
|
|
48
|
+
},
|
|
49
|
+
list: {
|
|
50
|
+
resolutions: [{
|
|
51
|
+
width: 440,
|
|
52
|
+
height: 440
|
|
53
|
+
}],
|
|
54
|
+
ratio: null
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
// Mocking the barrel replaces every export, and the Image component pulls this one from it.
|
|
58
|
+
useImageServiceSettings: () => ({
|
|
59
|
+
quality: 75,
|
|
60
|
+
fillColor: 'FFFFFF',
|
|
61
|
+
fillTransparent: true
|
|
62
|
+
})
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Reads the placeholder element the component hands to the Image. Image decides when to render it,
|
|
67
|
+
* so the placeholder is a prop here rather than part of this component's tree.
|
|
68
|
+
* @param {Object} wrapper The rendered ProductImage.
|
|
69
|
+
* @returns {JSX.Element} The placeholder element.
|
|
70
|
+
*/
|
|
71
|
+
const getPlaceholder = wrapper => wrapper.find(Image).prop('placeholder');
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Renders down to the component's own output, past the wrapper that supplies the shop wide
|
|
75
|
+
* placeholder and past the portals.
|
|
76
|
+
* @param {JSX.Element} element The element to render.
|
|
77
|
+
* @returns {Object} The rendered component.
|
|
78
|
+
*/
|
|
79
|
+
const renderProductImage = element => shallow(element).dive().dive();
|
|
16
80
|
describe('<ProductImage />', () => {
|
|
17
81
|
it('should render a placeholder if no src prop is provided', () => {
|
|
18
|
-
const wrapper =
|
|
82
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {}));
|
|
19
83
|
expect(wrapper).toMatchSnapshot();
|
|
20
|
-
expect(wrapper.find(
|
|
21
|
-
expect(wrapper.find(PlaceholderIcon).length).toBe(1);
|
|
84
|
+
expect(shallow(getPlaceholder(wrapper)).find(PlaceholderIcon).length).toBe(1);
|
|
22
85
|
});
|
|
23
86
|
it('should render the image without a placeholder', () => {
|
|
24
|
-
const wrapper =
|
|
87
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {
|
|
25
88
|
src: "http://placehold.it/300x300"
|
|
26
|
-
}))
|
|
27
|
-
expect(wrapper).toMatchSnapshot();
|
|
89
|
+
}));
|
|
28
90
|
expect(wrapper.find(Image).length).toBe(1);
|
|
29
91
|
expect(wrapper.find(PlaceholderIcon).length).toBe(0);
|
|
30
|
-
});
|
|
31
|
-
it('should not apply an inner shadow to the placeholder if turned off via the app config', () => {
|
|
32
|
-
jest.spyOn(appConfig, 'hideProductImageShadow', 'get').mockReturnValue(true);
|
|
33
|
-
const wrapper = shallow(/*#__PURE__*/_jsx(ProductImage, {
|
|
34
|
-
placeholderSrc: "http://placehold.it/300x300"
|
|
35
|
-
})).dive();
|
|
36
|
-
expect(wrapper).toMatchSnapshot();
|
|
37
|
-
expect(wrapper.find(ProductImagePlaceholder).prop('showInnerShadow')).toBe(false);
|
|
38
|
-
});
|
|
39
|
-
it('should not apply an inner shadow to the image if turned off via the app config', () => {
|
|
40
|
-
jest.spyOn(appConfig, 'hideProductImageShadow', 'get').mockReturnValue(true);
|
|
41
|
-
const wrapper = shallow(/*#__PURE__*/_jsx(ProductImage, {
|
|
42
|
-
src: "http://placehold.it/300x300"
|
|
43
|
-
})).dive();
|
|
44
92
|
expect(wrapper).toMatchSnapshot();
|
|
45
|
-
expect(wrapper.find(Image).prop('className')).toBe('');
|
|
46
93
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
showInnerShadow: false
|
|
52
|
-
}
|
|
53
|
-
})).dive();
|
|
54
|
-
expect(wrapper).toMatchSnapshot();
|
|
55
|
-
expect(wrapper.find(ProductImagePlaceholder).prop('showInnerShadow')).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
it('should not apply an inner shadow to the image if turned off via the widget settings', () => {
|
|
58
|
-
const wrapper = shallow(/*#__PURE__*/_jsx(ProductImage, {
|
|
94
|
+
|
|
95
|
+
// Most callers are untyped .jsx, and extensions are not type checked at all.
|
|
96
|
+
it('should fall back to the default context for an unknown one', () => {
|
|
97
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {
|
|
59
98
|
src: "http://placehold.it/300x300",
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
99
|
+
context: "somethingElse"
|
|
100
|
+
}));
|
|
101
|
+
expect(wrapper.find(Image).prop('resolutions')).toEqual([{
|
|
102
|
+
width: 440,
|
|
103
|
+
height: 440
|
|
104
|
+
}]);
|
|
66
105
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
106
|
+
describe('inner shadow', () => {
|
|
107
|
+
it('should not apply it to the placeholder when the hook says no', () => {
|
|
108
|
+
useProductImageShadow.mockReturnValue(false);
|
|
109
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {
|
|
110
|
+
placeholderSrc: "http://placehold.it/300x300"
|
|
111
|
+
}));
|
|
112
|
+
expect(getPlaceholder(wrapper).type).toBe(ProductImagePlaceholder);
|
|
113
|
+
expect(getPlaceholder(wrapper).props.showInnerShadow).toBe(false);
|
|
114
|
+
expect(wrapper).toMatchSnapshot();
|
|
115
|
+
});
|
|
116
|
+
it('should not apply it to the image when the hook says no', () => {
|
|
117
|
+
useProductImageShadow.mockReturnValue(false);
|
|
118
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {
|
|
119
|
+
src: "http://placehold.it/300x300"
|
|
120
|
+
}));
|
|
121
|
+
expect(wrapper.find(Image).prop('className')).not.toContain('innerShadow');
|
|
122
|
+
expect(wrapper).toMatchSnapshot();
|
|
123
|
+
});
|
|
124
|
+
it('should apply it to the placeholder when the hook says yes', () => {
|
|
125
|
+
useProductImageShadow.mockReturnValue(true);
|
|
126
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {
|
|
127
|
+
placeholderSrc: "http://placehold.it/300x300"
|
|
128
|
+
}));
|
|
129
|
+
expect(getPlaceholder(wrapper).type).toBe(ProductImagePlaceholder);
|
|
130
|
+
expect(getPlaceholder(wrapper).props.showInnerShadow).toBe(true);
|
|
131
|
+
expect(wrapper).toMatchSnapshot();
|
|
132
|
+
});
|
|
133
|
+
it('should apply it to the image when the hook says yes', () => {
|
|
134
|
+
useProductImageShadow.mockReturnValue(true);
|
|
135
|
+
const wrapper = renderProductImage(/*#__PURE__*/_jsx(ProductImage, {
|
|
136
|
+
src: "http://placehold.it/300x300"
|
|
137
|
+
}));
|
|
138
|
+
expect(wrapper.find(Image).prop('className')).toContain('innerShadow');
|
|
139
|
+
expect(wrapper).toMatchSnapshot();
|
|
140
|
+
});
|
|
86
141
|
});
|
|
87
142
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import { Link, Grid, Availability } from '@shopgate/engage/components';
|
|
4
4
|
import { bin2hex } from '@shopgate/pwa-common/helpers/data';
|
|
5
5
|
import Portal from '@shopgate/pwa-common/components/Portal';
|
|
6
6
|
import * as portals from '@shopgate/pwa-common-commerce/category/constants/Portals';
|
|
@@ -12,6 +12,7 @@ import Manufacturer from '@shopgate/pwa-ui-shared/Manufacturer';
|
|
|
12
12
|
import { PriceInfo, ProductName, ProductBadges } from '@shopgate/engage/product';
|
|
13
13
|
import { i18n } from '@shopgate/engage/core/helpers';
|
|
14
14
|
import { makeStyles } from '@shopgate/engage/styles';
|
|
15
|
+
import ProductImage from "../../../ProductImage";
|
|
15
16
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
17
|
const useStyles = makeStyles()(theme => ({
|
|
17
18
|
listItemContainer: {
|
|
@@ -92,10 +93,11 @@ const Item = ({
|
|
|
92
93
|
props: {
|
|
93
94
|
productId: product.id
|
|
94
95
|
},
|
|
95
|
-
children: /*#__PURE__*/_jsx(
|
|
96
|
+
children: /*#__PURE__*/_jsx(ProductImage, {
|
|
96
97
|
itemProp: "image",
|
|
97
98
|
src: product.featuredImageBaseUrl,
|
|
98
|
-
alt: product.name
|
|
99
|
+
alt: product.name,
|
|
100
|
+
context: "list"
|
|
99
101
|
})
|
|
100
102
|
}), /*#__PURE__*/_jsx(Portal, {
|
|
101
103
|
name: portals.PRODUCT_ITEM_IMAGE_AFTER,
|
|
@@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
|
|
|
3
3
|
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
4
4
|
import { getProductRating } from '@shopgate/pwa-common-commerce/product/selectors/product';
|
|
5
5
|
import { RatingStars } from '@shopgate/engage/components';
|
|
6
|
-
import
|
|
6
|
+
import useShowEmptyRatingStars from "../../hooks/useShowEmptyRatingStars";
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
const {
|
|
9
9
|
hasReviews
|
|
@@ -20,9 +20,7 @@ const ProductRatingStars = ({
|
|
|
20
20
|
getProductRating(state, {
|
|
21
21
|
productId
|
|
22
22
|
}));
|
|
23
|
-
const
|
|
24
|
-
showEmptyRatingStars = false
|
|
25
|
-
} = useWidgetSettings('@shopgate/engage/rating');
|
|
23
|
+
const showEmptyRatingStars = useShowEmptyRatingStars();
|
|
26
24
|
const showRatings = useMemo(() => {
|
|
27
25
|
if (hasReviews && (rating?.average ?? 0) > 0) {
|
|
28
26
|
return true;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../product/components/ProductSlider/constants.js"],"names":[],"mappings":"AAAA,wBAAyB,wCAAwC,CAAC;AAElE,sCAAuC,GAAG,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the number of slides the ProductSlider shows side by side for the active breakpoint.
|
|
3
|
+
* @param slidesPerViewProp The explicit prop value, if the caller passed one.
|
|
4
|
+
* @returns The resolved number of slides for the active breakpoint.
|
|
5
|
+
*/
|
|
6
|
+
export declare const useSlidesPerView: (slidesPerViewProp?: number) => number;
|
|
7
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../../product/components/ProductSlider/hooks.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,oBAAoB,MAAM,KAAG,MAgC7D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
import { useContext, useMemo } from 'react';
|
|
3
|
+
import { useSelector } from 'react-redux';
|
|
4
|
+
import { WidgetContext } from '@shopgate/engage/page/components/Widgets/WidgetContext';
|
|
5
|
+
import { useWidgetSettings } from '@shopgate/engage/core/hooks';
|
|
6
|
+
import { useResponsiveValue } from '@shopgate/engage/styles';
|
|
7
|
+
import { getAreAppSettingsHydrated, getProductSliderSlidesPerView } from '@shopgate/engage/settings/selectors/appSettings';
|
|
8
|
+
import { SCREEN_SIZE_BREAKPOINTS } from '@shopgate/engage/settings/constants/appSettings';
|
|
9
|
+
import { WIDGET_ID, DEFAULT_SLIDES_PER_VIEW } from "./constants";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the number of slides the ProductSlider shows side by side for the active breakpoint.
|
|
13
|
+
* @param slidesPerViewProp The explicit prop value, if the caller passed one.
|
|
14
|
+
* @returns The resolved number of slides for the active breakpoint.
|
|
15
|
+
*/
|
|
16
|
+
export const useSlidesPerView = slidesPerViewProp => {
|
|
17
|
+
const {
|
|
18
|
+
code: widgetCode
|
|
19
|
+
} = useContext(WidgetContext);
|
|
20
|
+
const isInsideWidget = Boolean(widgetCode);
|
|
21
|
+
const areAppSettingsHydrated = useSelector(getAreAppSettingsHydrated);
|
|
22
|
+
const appSettingsSlidesPerView = useSelector(getProductSliderSlidesPerView);
|
|
23
|
+
const {
|
|
24
|
+
slidesPerView: legacySlidesPerView
|
|
25
|
+
} = useWidgetSettings(WIDGET_ID) || {};
|
|
26
|
+
const sizes = useMemo(() => {
|
|
27
|
+
if (!areAppSettingsHydrated && !isInsideWidget && typeof legacySlidesPerView === 'number') {
|
|
28
|
+
return {
|
|
29
|
+
small: legacySlidesPerView
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return appSettingsSlidesPerView;
|
|
33
|
+
}, [areAppSettingsHydrated, isInsideWidget, legacySlidesPerView, appSettingsSlidesPerView]);
|
|
34
|
+
const breakpoints = useMemo(() => Object.entries(sizes).reduce((acc, [size, value]) => {
|
|
35
|
+
acc[SCREEN_SIZE_BREAKPOINTS[size]] = value;
|
|
36
|
+
return acc;
|
|
37
|
+
}, {}), [sizes]);
|
|
38
|
+
const resolved = useResponsiveValue(breakpoints);
|
|
39
|
+
return slidesPerViewProp || resolved || DEFAULT_SLIDES_PER_VIEW;
|
|
40
|
+
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { useWidgetSettings } from '@shopgate/engage/core';
|
|
4
3
|
import { useThemeComponents } from '@shopgate/engage/core/hooks';
|
|
5
4
|
import { Swiper } from '@shopgate/engage/components';
|
|
6
5
|
import { makeStyles } from '@shopgate/engage/styles';
|
|
7
6
|
import { ProductListTypeProvider, ProductListEntryProvider } from '@shopgate/engage/product/providers';
|
|
7
|
+
import { useSlidesPerView } from "./hooks";
|
|
8
|
+
import { WIDGET_ID } from "./constants";
|
|
8
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
10
|
const useStyles = makeStyles()({
|
|
10
11
|
container: {
|
|
11
|
-
|
|
12
|
+
padding: '8px 9px 16px !important'
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
15
|
const items = {
|
|
15
16
|
margin: '0 8px',
|
|
16
17
|
height: '100%'
|
|
17
18
|
};
|
|
18
|
-
export const WIDGET_ID = '@shopgate/engage/product/ProductSlider';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* @param {Object} props The component props.
|
|
@@ -36,12 +36,10 @@ function ProductSlider(props) {
|
|
|
36
36
|
meta,
|
|
37
37
|
productItemProps,
|
|
38
38
|
item,
|
|
39
|
+
slidesPerView: slidesPerViewProp,
|
|
39
40
|
...swiperProps
|
|
40
41
|
} = props;
|
|
41
|
-
const
|
|
42
|
-
const {
|
|
43
|
-
slidesPerView = 2.3
|
|
44
|
-
} = props.slidesPerView ? props : widgetSettings;
|
|
42
|
+
const slidesPerView = useSlidesPerView(slidesPerViewProp);
|
|
45
43
|
// ProductSlider items are rendered with the ProductCard component provided by the theme.
|
|
46
44
|
const {
|
|
47
45
|
ProductCard
|
|
@@ -63,8 +61,10 @@ function ProductSlider(props) {
|
|
|
63
61
|
freeMode: !snap,
|
|
64
62
|
...swiperProps,
|
|
65
63
|
slidesPerView: slidesPerView,
|
|
64
|
+
classNames: {
|
|
65
|
+
container: classes.container
|
|
66
|
+
},
|
|
66
67
|
children: productIds.map(id => /*#__PURE__*/_jsx(Swiper.Item, {
|
|
67
|
-
className: classes.container,
|
|
68
68
|
children: /*#__PURE__*/_jsx(ProductListEntryProvider, {
|
|
69
69
|
productId: id,
|
|
70
70
|
children: /*#__PURE__*/_jsx(Item, {
|
|
@@ -2,8 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import { render } from '@testing-library/react';
|
|
3
3
|
import ProductSlider from "./index";
|
|
4
4
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
-
jest.mock(
|
|
6
|
-
|
|
5
|
+
jest.mock("./hooks", () => ({
|
|
6
|
+
useSlidesPerView: jest.fn(() => 2.3)
|
|
7
7
|
}));
|
|
8
8
|
jest.mock('@shopgate/engage/components', () => {
|
|
9
9
|
const Swiper = ({
|
|
@@ -4,7 +4,7 @@ import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
|
4
4
|
import { RatingStars, SurroundPortals } from '@shopgate/engage/components';
|
|
5
5
|
import { PRODUCT_RATING } from '@shopgate/engage/product/constants';
|
|
6
6
|
import RatingCount from '@shopgate/engage/reviews/components/Reviews/components/RatingCount';
|
|
7
|
-
import {
|
|
7
|
+
import { useShowEmptyRatingStars } from '@shopgate/engage/product/hooks';
|
|
8
8
|
import { makeStyles } from '@shopgate/engage/styles';
|
|
9
9
|
import connect from "./connector";
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -42,9 +42,7 @@ const Rating = ({
|
|
|
42
42
|
const {
|
|
43
43
|
classes
|
|
44
44
|
} = useStyles();
|
|
45
|
-
const
|
|
46
|
-
showEmptyRatingStars = false
|
|
47
|
-
} = useWidgetSettings('@shopgate/engage/rating');
|
|
45
|
+
const showEmptyRatingStars = useShowEmptyRatingStars();
|
|
48
46
|
const showRatings = useMemo(() => {
|
|
49
47
|
if (hasReviews && (rating?.average ?? 0) > 0) {
|
|
50
48
|
return true;
|
|
@@ -6,6 +6,7 @@ import ProductCard from "../ProductCard";
|
|
|
6
6
|
import RelationsSheet from "./RelationsSheet";
|
|
7
7
|
import { useWidgetSettings, useCurrentProduct } from "../../../core";
|
|
8
8
|
import connect from "./RelationsSlider.connector";
|
|
9
|
+
import { useSlidesPerView } from "./hooks";
|
|
9
10
|
import { WIDGET_ID } from "./constants";
|
|
10
11
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
12
|
const useStyles = makeStyles()(theme => ({
|
|
@@ -51,12 +52,12 @@ const RelationsSliderContent = /*#__PURE__*/memo(({
|
|
|
51
52
|
hideRating,
|
|
52
53
|
titleRows,
|
|
53
54
|
showMoreButton,
|
|
54
|
-
type
|
|
55
|
-
slidesPerView = 2.3
|
|
55
|
+
type
|
|
56
56
|
} = useWidgetSettings(WIDGET_ID);
|
|
57
57
|
const {
|
|
58
58
|
productId
|
|
59
59
|
} = useCurrentProduct();
|
|
60
|
+
const slidesPerView = useSlidesPerView();
|
|
60
61
|
useEffect(() => {
|
|
61
62
|
getRelations();
|
|
62
63
|
}, [getRelations]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../product/components/RelationsSlider/constants.js"],"names":[],"mappings":"AAAA,wBAAyB,0CAA0C,CAAC;AAEpE,sCAAuC,GAAG,CAAC"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export const WIDGET_ID = '@shopgate/engage/product/RelationsSlider';
|
|
1
|
+
export const WIDGET_ID = '@shopgate/engage/product/RelationsSlider';
|
|
2
|
+
export const DEFAULT_SLIDES_PER_VIEW = 2.3;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the number of slides the RelationsSlider shows side by side for the active breakpoint.
|
|
3
|
+
* @returns The resolved number of slides for the active breakpoint.
|
|
4
|
+
*/
|
|
5
|
+
export declare const useSlidesPerView: () => number;
|
|
6
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../../product/components/RelationsSlider/hooks.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,MA6BnC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useSelector } from 'react-redux';
|
|
4
|
+
import { useWidgetSettings } from '@shopgate/engage/core/hooks';
|
|
5
|
+
import { useResponsiveValue } from '@shopgate/engage/styles';
|
|
6
|
+
import { getAreAppSettingsHydrated, getProductSliderSlidesPerView } from '@shopgate/engage/settings/selectors/appSettings';
|
|
7
|
+
import { SCREEN_SIZE_BREAKPOINTS } from '@shopgate/engage/settings/constants/appSettings';
|
|
8
|
+
import { WIDGET_ID, DEFAULT_SLIDES_PER_VIEW } from "./constants";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolves the number of slides the RelationsSlider shows side by side for the active breakpoint.
|
|
12
|
+
* @returns The resolved number of slides for the active breakpoint.
|
|
13
|
+
*/
|
|
14
|
+
export const useSlidesPerView = () => {
|
|
15
|
+
const areAppSettingsHydrated = useSelector(getAreAppSettingsHydrated);
|
|
16
|
+
const appSettingsSlidesPerView = useSelector(getProductSliderSlidesPerView);
|
|
17
|
+
const {
|
|
18
|
+
slidesPerView: legacySlidesPerView
|
|
19
|
+
} = useWidgetSettings(WIDGET_ID) || {};
|
|
20
|
+
const sizes = useMemo(() => {
|
|
21
|
+
if (!areAppSettingsHydrated && typeof legacySlidesPerView === 'number') {
|
|
22
|
+
return {
|
|
23
|
+
small: legacySlidesPerView
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return appSettingsSlidesPerView;
|
|
27
|
+
}, [areAppSettingsHydrated, legacySlidesPerView, appSettingsSlidesPerView]);
|
|
28
|
+
const breakpoints = useMemo(() => Object.entries(sizes).reduce((acc, [size, value]) => {
|
|
29
|
+
acc[SCREEN_SIZE_BREAKPOINTS[size]] = value;
|
|
30
|
+
return acc;
|
|
31
|
+
}, {}), [sizes]);
|
|
32
|
+
const resolved = useResponsiveValue(breakpoints);
|
|
33
|
+
return resolved || DEFAULT_SLIDES_PER_VIEW;
|
|
34
|
+
};
|
package/product/helpers/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import configuration from '@shopgate/pwa-common/collections/Configuration';
|
|
2
|
+
import { logger } from '@shopgate/pwa-core/helpers';
|
|
2
3
|
import { DEFAULT_PRODUCTS_FETCH_PARAMS } from '@shopgate/pwa-common/constants/Configuration';
|
|
3
4
|
import { getFullImageSource, isBeta, loadImage } from '@shopgate/engage/core/helpers';
|
|
4
5
|
import { getThemeSettings } from '@shopgate/engage/core/config';
|
|
6
|
+
import { PRODUCT_IMAGE_BASE_WIDTHS } from '@shopgate/engage/settings/constants/imageSettings';
|
|
5
7
|
import { buildShowScheduledParams } from "../components/EffectivityDates/helpers";
|
|
6
8
|
export * from '@shopgate/pwa-common-commerce/product/helpers';
|
|
7
9
|
export * from "../components/Media/helpers";
|
|
@@ -47,11 +49,23 @@ export const setDefaultProductFetchParams = () => {
|
|
|
47
49
|
});
|
|
48
50
|
};
|
|
49
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Whether the deprecation warning for getProductImageSettings has already been logged. Nulled
|
|
54
|
+
* after the first log, so a single warning is emitted per session rather than one per render.
|
|
55
|
+
*/
|
|
56
|
+
let productImageSettingsWarning = 'getProductImageSettings() is deprecated. Use the "context" prop of ProductImage, or the useProductImageSettings hook from @shopgate/engage/settings/hooks, so that images follow the configured aspect ratio.';
|
|
57
|
+
|
|
50
58
|
/**
|
|
51
59
|
* Provides the settings for ProductImages
|
|
60
|
+
* @deprecated Use the "context" prop of ProductImage, or useProductImageSettings. This accessor
|
|
61
|
+
* only reads the legacy theme configuration, so it does not pick up admin configured ratios.
|
|
52
62
|
* @return {Object}
|
|
53
63
|
*/
|
|
54
64
|
export const getProductImageSettings = () => {
|
|
65
|
+
if (productImageSettingsWarning) {
|
|
66
|
+
logger.warn(productImageSettingsWarning);
|
|
67
|
+
productImageSettingsWarning = null;
|
|
68
|
+
}
|
|
55
69
|
const appImages = getThemeSettings('AppImages');
|
|
56
70
|
return {
|
|
57
71
|
quality: 75,
|
|
@@ -79,18 +93,22 @@ export const getProductImageSettings = () => {
|
|
|
79
93
|
};
|
|
80
94
|
|
|
81
95
|
/**
|
|
82
|
-
* Load product image with given resolution
|
|
96
|
+
* Load product image with given resolution.
|
|
97
|
+
*
|
|
98
|
+
* A preload only pays off when it requests the same url the rendered image does, so pass the
|
|
99
|
+
* resolution and settings that image resolves. Anything omitted falls back to the built-in
|
|
100
|
+
* defaults.
|
|
83
101
|
* @param {string} src .
|
|
84
|
-
* @param {Object} resolution .
|
|
102
|
+
* @param {Object} [resolution] The resolution to preload. Falls back to the smallest built-in pdp
|
|
103
|
+
* resolution at a 1:1 ratio.
|
|
104
|
+
* @param {Object} [settings] The image service settings, as resolved by useImageServiceSettings.
|
|
85
105
|
* @returns {Promise}
|
|
86
106
|
*/
|
|
87
|
-
export const loadProductImage = (src, resolution = null) => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
return loadImage(getFullImageSource(src, res));
|
|
107
|
+
export const loadProductImage = (src, resolution = null, settings = undefined) => {
|
|
108
|
+
const [baseWidth] = PRODUCT_IMAGE_BASE_WIDTHS.pdp;
|
|
109
|
+
const res = resolution ?? {
|
|
110
|
+
width: baseWidth,
|
|
111
|
+
height: baseWidth
|
|
112
|
+
};
|
|
113
|
+
return loadImage(getFullImageSource(src, res, settings));
|
|
96
114
|
};
|
package/product/hooks/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { useLoadProductImage } from "./useLoadProductImage";
|
|
2
2
|
export { default as useProductListEntry } from "./useProductListEntry";
|
|
3
|
-
export { default as useProductListType } from "./useProductListType";
|
|
3
|
+
export { default as useProductListType } from "./useProductListType";
|
|
4
|
+
export { default as useShowEmptyRatingStars } from "./useShowEmptyRatingStars";
|
|
5
|
+
export { useSlidesPerView } from "../components/ProductSlider/hooks";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react';
|
|
2
|
+
import { useImageServiceSettings } from '@shopgate/engage/settings/hooks';
|
|
2
3
|
import { loadProductImage } from "../helpers/index";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -9,6 +10,7 @@ import { loadProductImage } from "../helpers/index";
|
|
|
9
10
|
*/
|
|
10
11
|
export function useLoadProductImage(src, resolution = null) {
|
|
11
12
|
const [loadedImage, setLoadedImage] = useState(null);
|
|
13
|
+
const imageServiceSettings = useImageServiceSettings();
|
|
12
14
|
useEffect(() => {
|
|
13
15
|
if (src) {
|
|
14
16
|
setLoadedImage(null);
|
|
@@ -16,8 +18,8 @@ export function useLoadProductImage(src, resolution = null) {
|
|
|
16
18
|
}, [src]);
|
|
17
19
|
useEffect(() => {
|
|
18
20
|
if (src && !loadedImage) {
|
|
19
|
-
loadProductImage(src, resolution).then(imageSrc => setLoadedImage(imageSrc));
|
|
21
|
+
loadProductImage(src, resolution, imageServiceSettings).then(imageSrc => setLoadedImage(imageSrc));
|
|
20
22
|
}
|
|
21
|
-
}, [loadedImage, resolution, src]);
|
|
23
|
+
}, [imageServiceSettings, loadedImage, resolution, src]);
|
|
22
24
|
return loadedImage;
|
|
23
25
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves whether rating stars are also rendered for products without a rating.
|
|
3
|
+
* @returns Whether empty rating stars are shown.
|
|
4
|
+
*/
|
|
5
|
+
declare const useShowEmptyRatingStars: () => boolean;
|
|
6
|
+
export default useShowEmptyRatingStars;
|
|
7
|
+
//# sourceMappingURL=useShowEmptyRatingStars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useShowEmptyRatingStars.d.ts","sourceRoot":"","sources":["../../../product/hooks/useShowEmptyRatingStars.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,QAAA,MAAM,uBAAuB,QAAO,OAYnC,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useSelector } from 'react-redux';
|
|
2
|
+
import { useWidgetSettings } from '@shopgate/engage/core/hooks';
|
|
3
|
+
import { getAreAppSettingsHydrated, getShowEmptyRatingStars } from '@shopgate/engage/settings/selectors/appSettings';
|
|
4
|
+
const RATING_WIDGET_ID = '@shopgate/engage/rating';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolves whether rating stars are also rendered for products without a rating.
|
|
8
|
+
* @returns Whether empty rating stars are shown.
|
|
9
|
+
*/
|
|
10
|
+
const useShowEmptyRatingStars = () => {
|
|
11
|
+
const areAppSettingsHydrated = useSelector(getAreAppSettingsHydrated);
|
|
12
|
+
const showEmptyStars = useSelector(getShowEmptyRatingStars);
|
|
13
|
+
const {
|
|
14
|
+
showEmptyRatingStars: legacyShowEmptyRatingStars = false
|
|
15
|
+
} = useWidgetSettings(RATING_WIDGET_ID) || {};
|
|
16
|
+
if (!areAppSettingsHydrated) {
|
|
17
|
+
return legacyShowEmptyRatingStars;
|
|
18
|
+
}
|
|
19
|
+
return showEmptyStars;
|
|
20
|
+
};
|
|
21
|
+
export default useShowEmptyRatingStars;
|
package/product/index.js
CHANGED
|
@@ -37,7 +37,6 @@ export * from "./selectors/relations";
|
|
|
37
37
|
export { ProductContext, VariantContext } from "./components/context";
|
|
38
38
|
export { default as ProductListTypeContext } from "./providers/ProductListType/context";
|
|
39
39
|
export { default as ProductListEntryContext } from "./providers/ProductListEntry/context";
|
|
40
|
-
export * from "./collections";
|
|
41
40
|
export * from "./constants";
|
|
42
41
|
export * from "./helpers";
|
|
43
42
|
export * from "./components";
|