@shopgate/pwa-common 7.30.0-alpha.7 → 7.30.0-alpha.8
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/App.js +48 -6
- package/action-creators/app/index.js +75 -12
- package/action-creators/app/spec.js +96 -1
- package/action-creators/client/index.js +27 -5
- package/action-creators/client/spec.js +44 -1
- package/action-creators/error/index.js +15 -3
- package/action-creators/index.js +9 -1
- package/action-creators/menu/index.js +23 -4
- package/action-creators/menu/spec.js +37 -1
- package/action-creators/modal/index.js +15 -3
- package/action-creators/modal/spec.js +26 -1
- package/action-creators/page/index.js +24 -4
- package/action-creators/page/spec.js +38 -1
- package/action-creators/router/index.js +48 -7
- package/action-creators/url/index.js +24 -4
- package/action-creators/url/spec.js +45 -1
- package/action-creators/user/index.js +90 -13
- package/action-creators/user/spec.js +186 -2
- package/actions/app/handleDeepLink.js +11 -2
- package/actions/app/handleLink.js +62 -6
- package/actions/app/handlePushNotification.js +32 -4
- package/actions/app/handleUniversalLink.js +11 -2
- package/actions/app/registerLinkEvents.js +24 -3
- package/actions/client/fetchClientInformation.js +26 -2
- package/actions/menu/fetchMenu.js +23 -2
- package/actions/modal/closeModal.js +18 -2
- package/actions/modal/promiseMap.js +3 -1
- package/actions/modal/showModal.js +54 -8
- package/actions/page/fetchPageConfig.js +69 -2
- package/actions/page/getPageConfig.js +6 -2
- package/actions/page/index.js +1 -1
- package/actions/router/historyPop.js +12 -2
- package/actions/router/historyPopToRoute.js +27 -2
- package/actions/router/historyPush.js +12 -2
- package/actions/router/historyRedirect.js +21 -2
- package/actions/router/historyReplace.js +20 -3
- package/actions/router/historyReset.js +11 -2
- package/actions/router/historyResetTo.js +12 -2
- package/actions/router/index.js +17 -1
- package/actions/router/routeDidPop.js +11 -2
- package/actions/router/routeDidPush.js +13 -2
- package/actions/router/routeDidReplace.js +11 -2
- package/actions/router/routeDidReset.js +11 -2
- package/actions/router/routeDidUpdate.js +10 -2
- package/actions/router/routeWillPop.js +11 -2
- package/actions/router/routeWillPush.js +13 -2
- package/actions/router/routeWillReplace.js +11 -2
- package/actions/router/routeWillReset.js +11 -2
- package/actions/router/windowOpenOverride.js +10 -2
- package/actions/user/fetchRegisterUrl.js +36 -2
- package/actions/user/fetchUser.js +29 -3
- package/actions/user/getUser.js +6 -2
- package/actions/user/index.js +1 -1
- package/actions/user/login.js +76 -9
- package/actions/user/logout.js +30 -2
- package/collections/AuthRoutes.js +73 -14
- package/collections/Configuration.js +54 -7
- package/collections/EmbeddedMedia.js +84 -11
- package/collections/PersistedReducers.js +41 -6
- package/collections/Redirects.js +103 -17
- package/collections/index.js +5 -1
- package/collections/media-providers/MediaProvider.js +151 -26
- package/collections/media-providers/Vimeo.js +113 -19
- package/collections/media-providers/YouTube.js +74 -14
- package/collections/media-providers/index.js +3 -1
- package/collections/media-providers/style.js +52 -2
- package/components/Backdrop/index.js +95 -6
- package/components/Backdrop/spec.js +23 -1
- package/components/Backdrop/style.js +11 -2
- package/components/Button/index.js +47 -5
- package/components/Button/spec.js +36 -1
- package/components/Button/style.js +6 -1
- package/components/Checkbox/index.js +126 -32
- package/components/Checkbox/spec.js +94 -3
- package/components/Consume/helpers/buildParams.js +13 -2
- package/components/Consume/index.js +14 -2
- package/components/CountdownTimer/index.js +115 -17
- package/components/CountdownTimer/spec.js +126 -12
- package/components/Drawer/index.js +131 -16
- package/components/Drawer/spec.js +76 -1
- package/components/Drawer/style.js +37 -1
- package/components/Dropdown/index.js +65 -6
- package/components/Dropdown/style.js +4 -1
- package/components/Dropdown/transitions.js +34 -1
- package/components/Ellipsis/index.js +16 -2
- package/components/Ellipsis/spec.js +13 -1
- package/components/EmbeddedMedia/index.js +56 -6
- package/components/EmbeddedMedia/spec.js +52 -3
- package/components/ErrorBoundary/connector.js +9 -2
- package/components/ErrorBoundary/index.js +43 -7
- package/components/Grid/components/Item/index.js +40 -4
- package/components/Grid/components/Item/spec.js +23 -1
- package/components/Grid/components/Item/style.js +17 -3
- package/components/Grid/index.js +36 -4
- package/components/Grid/spec.js +23 -1
- package/components/Grid/style.js +11 -2
- package/components/HtmlSanitizer/connector.js +24 -3
- package/components/HtmlSanitizer/index.js +104 -12
- package/components/HtmlSanitizer/spec.js +207 -6
- package/components/I18n/components/FormatDate/index.js +26 -2
- package/components/I18n/components/FormatDate/spec.js +46 -1
- package/components/I18n/components/FormatNumber/index.js +34 -2
- package/components/I18n/components/FormatNumber/spec.js +41 -2
- package/components/I18n/components/FormatPrice/index.js +32 -2
- package/components/I18n/components/FormatPrice/spec.js +46 -1
- package/components/I18n/components/FormatTime/index.js +26 -2
- package/components/I18n/components/FormatTime/spec.js +43 -2
- package/components/I18n/components/I18nProvider/index.js +52 -9
- package/components/I18n/components/I18nProvider/spec.js +39 -1
- package/components/I18n/components/Placeholder/index.js +8 -2
- package/components/I18n/components/Placeholder/spec.js +30 -1
- package/components/I18n/components/Translate/index.js +68 -7
- package/components/I18n/components/Translate/spec.js +30 -1
- package/components/I18n/index.js +16 -1
- package/components/Icon/index.js +25 -2
- package/components/Icon/style.js +6 -1
- package/components/Image/Image.js +176 -19
- package/components/Image/ImageInner.js +48 -2
- package/components/Image/index.js +1 -1
- package/components/Image/style.js +29 -2
- package/components/InfiniteContainer/index.js +381 -49
- package/components/InfiniteContainer/spec.js +199 -10
- package/components/Input/components/DateInput.js +262 -6
- package/components/Input/components/MultiLineInput.js +98 -12
- package/components/Input/components/SimpleInput.js +207 -31
- package/components/Input/index.js +32 -3
- package/components/Input/spec.js +122 -1
- package/components/KeyboardConsumer/index.js +48 -7
- package/components/Link/connector.js +7 -1
- package/components/Link/index.js +96 -11
- package/components/Link/spec.js +56 -1
- package/components/Link/style.js +10 -1
- package/components/List/components/Item/index.js +35 -3
- package/components/List/components/Item/style.js +16 -1
- package/components/List/index.js +20 -2
- package/components/List/spec.js +31 -1
- package/components/Loading/index.js +6 -2
- package/components/Modal/index.js +38 -3
- package/components/Modal/style.js +36 -1
- package/components/ModalContainer/connector.js +17 -3
- package/components/ModalContainer/index.js +36 -3
- package/components/ModalContainer/spec.js +105 -5
- package/components/Picker/components/Button/index.js +34 -2
- package/components/Picker/components/Button/style.js +19 -1
- package/components/Picker/components/List/index.js +33 -2
- package/components/Picker/components/List/style.js +17 -1
- package/components/Picker/components/Modal/index.js +60 -7
- package/components/Picker/components/Modal/style.js +78 -1
- package/components/Picker/index.js +167 -21
- package/components/Picker/spec.js +83 -2
- package/components/Portal/index.js +130 -19
- package/components/ProductCharacteristics/connector.js +33 -4
- package/components/ProductCharacteristics/context.js +2 -1
- package/components/ProductCharacteristics/helpers/index.js +135 -21
- package/components/ProductCharacteristics/index.js +266 -31
- package/components/RangeSlider/components/Handle/index.js +25 -2
- package/components/RangeSlider/components/Handle/style.js +14 -1
- package/components/RangeSlider/helper.js +43 -8
- package/components/RangeSlider/index.js +228 -38
- package/components/RangeSlider/style.js +14 -1
- package/components/Route/RouteNotFound.js +46 -3
- package/components/Route/index.js +78 -10
- package/components/Router/connector.js +9 -2
- package/components/Router/index.js +237 -31
- package/components/ScannerContainer/connector.js +9 -2
- package/components/ScannerContainer/index.js +42 -6
- package/components/Select/components/Item/index.js +20 -4
- package/components/Select/components/Item/style.js +4 -1
- package/components/Select/index.js +149 -28
- package/components/Select/spec.js +86 -2
- package/components/Select/style.js +17 -1
- package/components/SelectBox/components/Item/index.js +47 -5
- package/components/SelectBox/components/Item/style.js +7 -1
- package/components/SelectBox/index.js +173 -17
- package/components/SelectBox/spec.js +59 -3
- package/components/SelectBox/style.js +18 -1
- package/components/Slider/index.js +6 -2
- package/components/SurroundPortals/index.js +26 -2
- package/components/Swiper/components/SwiperItem/index.js +28 -4
- package/components/Swiper/components/SwiperItem/spec.js +17 -1
- package/components/Swiper/components/SwiperItem/styles.js +5 -1
- package/components/Swiper/index.js +210 -18
- package/components/Swiper/styles.js +75 -7
- package/components/Toaster/index.js +10 -2
- package/components/Transition/index.js +89 -13
- package/components/Widgets/components/Widget/index.js +52 -4
- package/components/Widgets/components/Widget/spec.js +68 -3
- package/components/Widgets/components/Widget/style.js +21 -3
- package/components/Widgets/components/WidgetGrid/index.js +52 -7
- package/components/Widgets/components/WidgetGrid/spec.js +46 -2
- package/components/Widgets/components/WidgetGrid/style.js +8 -1
- package/components/Widgets/helpers/shouldShowWidget.js +44 -7
- package/components/Widgets/index.js +127 -15
- package/components/Widgets/spec.js +213 -6
- package/components/index.js +9 -1
- package/constants/ActionTypes.js +97 -19
- package/constants/Configuration.js +12 -2
- package/constants/Device.js +29 -2
- package/constants/DisplayOptions.js +8 -1
- package/constants/MenuIDs.js +2 -1
- package/constants/ModalTypes.js +1 -1
- package/constants/PageIDs.js +1 -1
- package/constants/Pipelines.js +7 -1
- package/constants/Portals.js +136 -3
- package/constants/Registration.js +3 -1
- package/constants/RoutePaths.js +13 -2
- package/constants/Tracking.js +3 -1
- package/constants/client.js +6 -1
- package/constants/ui.js +2 -1
- package/constants/user.js +6 -2
- package/context/index.js +33 -3
- package/helpers/config/index.js +139 -21
- package/helpers/config/mock.js +200 -8
- package/helpers/config/theme.js +50 -4
- package/helpers/data/index.js +204 -29
- package/helpers/data/spec.js +187 -7
- package/helpers/date/index.js +58 -6
- package/helpers/date/spec.js +92 -1
- package/helpers/dom/index.js +48 -11
- package/helpers/environment/index.js +14 -2
- package/helpers/html/decodeHTML.js +7 -1
- package/helpers/html/handleDOM.js +172 -21
- package/helpers/html/parseHTML.js +67 -12
- package/helpers/i18n/getDateFormatter.js +23 -4
- package/helpers/i18n/getNumberFormatter.js +32 -4
- package/helpers/i18n/getPriceFormatter.js +38 -4
- package/helpers/i18n/getTimeFormatter.js +23 -4
- package/helpers/i18n/getTranslator.js +62 -8
- package/helpers/i18n/index.js +5 -1
- package/helpers/i18n/mergeTranslations.js +36 -9
- package/helpers/i18n/messageCache.js +3 -1
- package/helpers/legacy/index.js +47 -9
- package/helpers/modal/withShowModal.js +13 -2
- package/helpers/portals/portalCollection.js +28 -6
- package/helpers/portals/routePortals.js +12 -1
- package/helpers/redux/compareObjects.js +7 -2
- package/helpers/redux/generateResultHash.js +36 -3
- package/helpers/redux/generateSortedHash.js +7 -2
- package/helpers/redux/hasExpired.js +10 -2
- package/helpers/redux/index.js +7 -1
- package/helpers/redux/mutable.js +143 -24
- package/helpers/redux/shouldFetchData.js +46 -10
- package/helpers/redux/shouldFetchFilters.js +17 -4
- package/helpers/router/index.js +49 -5
- package/helpers/style/index.js +43 -4
- package/helpers/style/spec.js +108 -2
- package/helpers/tracking/index.js +52 -9
- package/helpers/validation/index.js +39 -12
- package/helpers/validation/spec.js +10 -1
- package/package.json +3 -3
- package/providers/index.js +4 -1
- package/providers/loading/context.js +2 -1
- package/providers/loading/index.js +137 -22
- package/providers/toast/context.js +2 -1
- package/providers/toast/index.js +105 -11
- package/reducers/client/connectivity.js +22 -2
- package/reducers/client/index.js +7 -1
- package/reducers/client/info.js +27 -2
- package/reducers/index.js +23 -4
- package/reducers/menu/index.js +5 -1
- package/reducers/menu/menusById.js +41 -2
- package/reducers/modal/index.js +14 -2
- package/reducers/page/index.js +68 -5
- package/reducers/router/index.js +48 -2
- package/reducers/url/index.js +42 -3
- package/reducers/user/data.js +27 -2
- package/reducers/user/index.js +7 -1
- package/reducers/user/login.js +65 -2
- package/selectors/client.js +138 -21
- package/selectors/history.js +49 -11
- package/selectors/menu.js +34 -6
- package/selectors/modal.js +15 -4
- package/selectors/page.js +25 -4
- package/selectors/router.js +154 -30
- package/selectors/url.js +25 -4
- package/selectors/user.js +90 -13
- package/store/index.js +60 -6
- package/store/middelwares/logger.js +7 -1
- package/store/middelwares/streams.js +19 -2
- package/streams/app.js +60 -8
- package/streams/client.js +8 -2
- package/streams/error.js +14 -3
- package/streams/index.js +6 -1
- package/streams/interval.js +6 -2
- package/streams/main.js +27 -2
- package/streams/router.js +45 -8
- package/streams/user.js +89 -15
- package/streams/view.js +97 -25
- package/styles/reset/form.js +57 -5
- package/styles/reset/index.js +6 -1
- package/styles/reset/media.js +22 -1
- package/styles/reset/root.js +33 -1
- package/styles/reset/table.js +10 -1
- package/styles/reset/typography.js +26 -1
- package/subscriptions/app.js +148 -17
- package/subscriptions/error.js +292 -13
- package/subscriptions/helpers/buildRegisterUrl.js +25 -6
- package/subscriptions/helpers/clearUpInAppBrowser.js +14 -3
- package/subscriptions/helpers/handleLinks.js +267 -25
- package/subscriptions/helpers/pipeline.js +12 -1
- package/subscriptions/history.js +34 -6
- package/subscriptions/index.js +25 -4
- package/subscriptions/menu.js +22 -5
- package/subscriptions/mock.js +39 -7
- package/subscriptions/router.js +336 -23
- package/subscriptions/user.js +93 -3
|
@@ -1,13 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { useMemo, useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import cls from 'classnames';
|
|
5
|
+
import { A11y, Autoplay, FreeMode, Navigation, Pagination, Zoom } from 'swiper/modules';
|
|
6
|
+
/* eslint-disable import/no-unresolved */
|
|
7
|
+
import { Swiper as OriginalSwiper } from 'swiper/react';
|
|
8
|
+
import 'swiper/css';
|
|
9
|
+
import 'swiper/css/a11y';
|
|
10
|
+
import 'swiper/css/pagination';
|
|
11
|
+
import 'swiper/css/navigation';
|
|
12
|
+
import 'swiper/css/zoom';
|
|
13
|
+
/* eslint-enable import/no-unresolved */
|
|
14
|
+
import { useReduceMotion } from '@shopgate/engage/a11y/hooks';
|
|
15
|
+
import SwiperItem from "./components/SwiperItem";
|
|
16
|
+
import { container, innerContainer, zoomFix, buttonNext, buttonPrev } from "./styles";
|
|
17
|
+
|
|
18
|
+
/**
|
|
2
19
|
* @typedef {import('swiper/react').SwiperProps} SwiperCmpProps
|
|
3
|
-
*/
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
4
23
|
* @typedef {import('swiper/react').SwiperClass} SwiperClass
|
|
5
|
-
*/
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
6
27
|
* Performs steps that are required when the loop prop of the Swiper is updated.
|
|
7
28
|
* @param {SwiperClass} swiper Swiper instance
|
|
8
29
|
* @param {boolean} loop Whether the loop mode should be enabled or not.
|
|
9
|
-
*/
|
|
10
|
-
|
|
30
|
+
*/
|
|
31
|
+
const handleLoopPropUpdate = (swiper, loop) => {
|
|
32
|
+
const realIndex = swiper?.realIndex || 0;
|
|
33
|
+
|
|
34
|
+
// eslint-disable-next-line no-param-reassign
|
|
35
|
+
swiper.params.loop = loop;
|
|
36
|
+
if (loop) {
|
|
37
|
+
swiper.loopDestroy();
|
|
38
|
+
swiper.loopCreate(realIndex);
|
|
39
|
+
swiper.updateSlides();
|
|
40
|
+
} else {
|
|
41
|
+
swiper.loopDestroy();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
11
46
|
* The basic Swiper component. It acts as a wrapper for the Swiper JS library component.
|
|
12
47
|
*
|
|
13
48
|
* This component wraps the [Swiper](https://swiperjs.com/) library's main component.
|
|
@@ -15,20 +50,177 @@ swiper.params.loop=loop;if(loop){swiper.loopDestroy();swiper.loopCreate(realInde
|
|
|
15
50
|
*
|
|
16
51
|
* @param {SwiperCmpProps} props The component props.
|
|
17
52
|
* @returns {JSX.Element}
|
|
18
|
-
*/
|
|
19
|
-
|
|
53
|
+
*/
|
|
54
|
+
const Swiper = ({
|
|
55
|
+
maxIndicators,
|
|
56
|
+
indicators,
|
|
57
|
+
controls,
|
|
58
|
+
'aria-hidden': ariaHidden,
|
|
59
|
+
disabled,
|
|
60
|
+
autoPlay,
|
|
61
|
+
interval,
|
|
62
|
+
classNames,
|
|
63
|
+
className,
|
|
64
|
+
onSlideChange,
|
|
65
|
+
onBreakpoint,
|
|
66
|
+
additionalModules,
|
|
67
|
+
loop: loopProp,
|
|
68
|
+
children,
|
|
69
|
+
paginationType: paginationTypeProp,
|
|
70
|
+
...swiperProps
|
|
71
|
+
}) => {
|
|
72
|
+
const useFraction = maxIndicators && maxIndicators < children.length;
|
|
73
|
+
const paginationType = useFraction ? 'fraction' : 'bullets';
|
|
74
|
+
const showPagination = indicators && children.length > 1;
|
|
75
|
+
const hasControls = typeof controls === 'boolean' && controls === true;
|
|
76
|
+
const reduceMotion = useReduceMotion();
|
|
77
|
+
|
|
78
|
+
/** @type {React.RefObject<{ swiper: SwiperClass}>} */
|
|
79
|
+
const swiperRef = useRef(null);
|
|
80
|
+
const [currentSlidesPerView, setCurrentSlidesPerView] = useState(swiperProps?.slidesPerView || 1);
|
|
81
|
+
const navigation = useMemo(() => {
|
|
82
|
+
let nav;
|
|
83
|
+
if (hasControls) {
|
|
84
|
+
nav = {
|
|
85
|
+
// Important to use dot notation (swiper uses it as selector internally)
|
|
86
|
+
nextEl: `.swiper-button-next.${buttonNext}`,
|
|
87
|
+
prevEl: `.swiper-button-prev.${buttonPrev}`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (typeof controls === 'object') {
|
|
91
|
+
nav = controls;
|
|
92
|
+
}
|
|
93
|
+
return nav;
|
|
94
|
+
}, [controls, hasControls]);
|
|
95
|
+
const handleSlideChange = useCallback(swiper => {
|
|
96
|
+
if (typeof onSlideChange === 'function') {
|
|
97
|
+
onSlideChange(swiper.realIndex, swiper);
|
|
98
|
+
}
|
|
99
|
+
}, [onSlideChange]);
|
|
100
|
+
|
|
101
|
+
/**
|
|
20
102
|
* @type {SwiperCmpProps}
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
103
|
+
*/
|
|
104
|
+
const internalProps = useMemo(() => ({
|
|
105
|
+
modules: [A11y, Autoplay, FreeMode, Navigation, Pagination, Zoom, ...(Array.isArray(additionalModules) ? additionalModules : [])],
|
|
106
|
+
className: cls(innerContainer, classNames.container, {
|
|
107
|
+
[zoomFix]: swiperProps?.zoom
|
|
108
|
+
}),
|
|
109
|
+
autoplay: autoPlay ? {
|
|
110
|
+
delay: interval
|
|
111
|
+
} : false,
|
|
112
|
+
navigation,
|
|
113
|
+
...(showPagination && {
|
|
114
|
+
pagination: {
|
|
115
|
+
el: undefined,
|
|
116
|
+
type: paginationTypeProp || paginationType,
|
|
117
|
+
bulletClass: classNames.bulletClass || 'swiper-pagination-bullet',
|
|
118
|
+
bulletActiveClass: classNames.bulletActiveClass || 'swiper-pagination-bullet-active',
|
|
119
|
+
dynamicBullets: true,
|
|
120
|
+
clickable: true,
|
|
121
|
+
enabled: indicators && children.length > 1
|
|
122
|
+
}
|
|
123
|
+
}),
|
|
124
|
+
allowSlidePrev: !disabled,
|
|
125
|
+
allowSlideNext: !disabled,
|
|
126
|
+
onSlideChange: handleSlideChange
|
|
127
|
+
}), [additionalModules, classNames.container, classNames.bulletClass, classNames.bulletActiveClass, swiperProps, autoPlay, interval, navigation, showPagination, paginationTypeProp, paginationType, indicators, children.length, disabled, handleSlideChange]);
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (!internalProps.autoplay && !swiperProps.autoplay) {
|
|
130
|
+
if (swiperRef.current?.swiper?.autoplay) {
|
|
131
|
+
// When autoplay is disabled, ensure that the slider is really stopped. That tackles UI
|
|
132
|
+
// issues when e.g. autoplay and loop mode where disabled during one slide interval.
|
|
133
|
+
swiperRef.current.swiper.autoplay.stop();
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (swiperRef.current?.swiper?.autoplay) {
|
|
138
|
+
if (reduceMotion) {
|
|
139
|
+
swiperRef.current.swiper.autoplay.stop();
|
|
140
|
+
} else {
|
|
141
|
+
swiperRef.current.swiper.autoplay.start();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}, [internalProps.autoplay, reduceMotion, swiperProps.autoplay]);
|
|
145
|
+
|
|
146
|
+
// The currently configured delay for autoplay.
|
|
147
|
+
const delay = internalProps.autoplay?.delay || swiperProps.autoplay?.delay;
|
|
148
|
+
// Whether the loop mode should be enabled.
|
|
149
|
+
const shouldLoop = loopProp && children?.length > currentSlidesPerView + 1;
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
if (!swiperRef.current) return;
|
|
152
|
+
// Perform required steps when loop prop changes on runtime.
|
|
153
|
+
handleLoopPropUpdate(swiperRef.current.swiper, shouldLoop);
|
|
154
|
+
}, [shouldLoop]);
|
|
155
|
+
|
|
156
|
+
/**
|
|
27
157
|
* Handles the breakpoint change event.
|
|
28
158
|
* The Swiper has some issues when props are changed on runtime followed by a breakpoint change.
|
|
29
159
|
* This function is supposed to ensure the the Swiper behaves as expected in that case.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
160
|
+
*/
|
|
161
|
+
const handleOnBreakpoint = useCallback(
|
|
162
|
+
/**
|
|
163
|
+
* @param {SwiperClass} swiper Swiper instance
|
|
164
|
+
* @param {Object} breakpoint Current breakpoint object
|
|
165
|
+
*/
|
|
166
|
+
(swiper, breakpoint) => {
|
|
167
|
+
let {
|
|
168
|
+
slidesPerView
|
|
169
|
+
} = breakpoint;
|
|
170
|
+
if (!slidesPerView) {
|
|
171
|
+
slidesPerView = 1;
|
|
172
|
+
}
|
|
173
|
+
const wasRunning = swiper?.autoplay?.running || false;
|
|
174
|
+
if (wasRunning) {
|
|
175
|
+
swiper.autoplay.stop();
|
|
176
|
+
}
|
|
177
|
+
const loopUpdate = loopProp && swiper.slides.length > slidesPerView + 1;
|
|
178
|
+
handleLoopPropUpdate(swiper, loopUpdate);
|
|
179
|
+
if (typeof delay === 'number' && swiper.params.autoplay) {
|
|
180
|
+
// eslint-disable-next-line no-param-reassign
|
|
181
|
+
swiper.params.autoplay.delay = delay;
|
|
182
|
+
}
|
|
183
|
+
if (wasRunning) {
|
|
184
|
+
swiper.autoplay.start();
|
|
185
|
+
}
|
|
186
|
+
setCurrentSlidesPerView(slidesPerView);
|
|
187
|
+
if (typeof onBreakpoint === 'function') {
|
|
188
|
+
onBreakpoint(swiper, breakpoint);
|
|
189
|
+
}
|
|
190
|
+
}, [delay, loopProp, onBreakpoint]);
|
|
191
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
192
|
+
className: cls(container, className, 'common__swiper'),
|
|
193
|
+
"aria-hidden": ariaHidden
|
|
194
|
+
}, /*#__PURE__*/React.createElement(OriginalSwiper, _extends({
|
|
195
|
+
"aria-live": "off",
|
|
196
|
+
a11y: {
|
|
197
|
+
enabled: false
|
|
198
|
+
}
|
|
199
|
+
}, internalProps, swiperProps, {
|
|
200
|
+
loop: shouldLoop,
|
|
201
|
+
onBreakpoint: handleOnBreakpoint,
|
|
202
|
+
ref: swiperRef
|
|
203
|
+
}), children, hasControls && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
204
|
+
className: `swiper-button-next ${buttonNext}`
|
|
205
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
206
|
+
className: `swiper-button-prev ${buttonPrev}`
|
|
207
|
+
}))));
|
|
208
|
+
};
|
|
209
|
+
Swiper.Item = SwiperItem;
|
|
210
|
+
Swiper.defaultProps = {
|
|
211
|
+
'aria-hidden': false,
|
|
212
|
+
additionalModules: null,
|
|
213
|
+
autoPlay: false,
|
|
214
|
+
className: null,
|
|
215
|
+
classNames: {},
|
|
216
|
+
controls: false,
|
|
217
|
+
indicators: false,
|
|
218
|
+
interval: 3000,
|
|
219
|
+
loop: false,
|
|
220
|
+
maxIndicators: null,
|
|
221
|
+
disabled: false,
|
|
222
|
+
onSlideChange: null,
|
|
223
|
+
onBreakpoint: null,
|
|
224
|
+
paginationType: null
|
|
225
|
+
};
|
|
226
|
+
export default Swiper;
|
|
@@ -1,8 +1,76 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
import { themeColors } from '@shopgate/pwa-common/helpers/config';
|
|
3
|
+
export const container = css({
|
|
4
|
+
position: 'relative',
|
|
5
|
+
maxHeight: '100%'
|
|
6
|
+
// This needs to be 100vw to compensate a chrome 80 bug - see related ticket / pr. (PWA-2509)
|
|
7
|
+
// commented out for now since it causes issues in the responsive layout
|
|
8
|
+
// width: '100vw',
|
|
9
|
+
}).toString();
|
|
10
|
+
export const innerContainer = css({
|
|
11
|
+
overflow: 'hidden',
|
|
12
|
+
'--swiper-navigation-color': themeColors.gray,
|
|
13
|
+
' .swiper-wrapper': {
|
|
14
|
+
alignItems: 'stretch'
|
|
15
|
+
},
|
|
16
|
+
' .swiper-slide': {
|
|
17
|
+
height: 'auto'
|
|
18
|
+
},
|
|
19
|
+
' .swiper-pagination': {
|
|
20
|
+
' .swiper-pagination-bullet': {
|
|
21
|
+
background: themeColors.gray,
|
|
22
|
+
opacity: '.5',
|
|
23
|
+
margin: '0 4px',
|
|
24
|
+
transition: 'opacity 300ms cubic-bezier(0.25, 0.1, 0.25, 1)',
|
|
25
|
+
border: `1px solid ${themeColors.dark}`
|
|
26
|
+
},
|
|
27
|
+
' .swiper-pagination-bullet-active.swiper-pagination-bullet-active-main': {
|
|
28
|
+
opacity: 1
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
' .swiper-pagination-fraction': {
|
|
32
|
+
top: 'var(--swiper-pagination-fraction-top-offset, 4px)',
|
|
33
|
+
left: 'auto',
|
|
34
|
+
right: 0,
|
|
35
|
+
bottom: 'auto',
|
|
36
|
+
fontSize: 12,
|
|
37
|
+
background: themeColors.background,
|
|
38
|
+
borderRadius: '50px',
|
|
39
|
+
width: 'fit-content',
|
|
40
|
+
padding: '4px 8px',
|
|
41
|
+
margin: '4px 16px',
|
|
42
|
+
transition: 'opacity 300ms cubic-bezier(0.25, 0.1, 0.25, 1)'
|
|
43
|
+
},
|
|
44
|
+
' .swiper-pagination-progressbar': {
|
|
45
|
+
background: themeColors.shade7,
|
|
46
|
+
' .swiper-pagination-progressbar-fill': {
|
|
47
|
+
background: themeColors.dark
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}).toString();
|
|
51
|
+
|
|
52
|
+
/**
|
|
5
53
|
* Prevents a visible shrink animation of swiped out slides which where in a zoomed state before.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'
|
|
54
|
+
*/
|
|
55
|
+
export const zoomFix = css({
|
|
56
|
+
' .swiper-slide': {
|
|
57
|
+
overflow: 'hidden'
|
|
58
|
+
}
|
|
59
|
+
}).toString();
|
|
60
|
+
export const wrapper = css({
|
|
61
|
+
flexShrink: 0
|
|
62
|
+
});
|
|
63
|
+
export const buttonNext = css({
|
|
64
|
+
backgroundImage: "url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23808080'%2F%3E%3C%2Fsvg%3E\") !important",
|
|
65
|
+
// Hide original SwiperJS chevron
|
|
66
|
+
':after': {
|
|
67
|
+
color: 'transparent'
|
|
68
|
+
}
|
|
69
|
+
}).toString();
|
|
70
|
+
export const buttonPrev = css({
|
|
71
|
+
backgroundImage: "url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23808080'%2F%3E%3C%2Fsvg%3E\") !important",
|
|
72
|
+
// Hide original SwiperJS chevron
|
|
73
|
+
':after': {
|
|
74
|
+
color: 'transparent'
|
|
75
|
+
}
|
|
76
|
+
}).toString();
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import ToastContext from "../../providers/toast/context";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* The Toaster component.
|
|
3
7
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
const Toaster = ({
|
|
10
|
+
render
|
|
11
|
+
}) => /*#__PURE__*/React.createElement(ToastContext.Consumer, null, context => render(context));
|
|
12
|
+
export default Toaster;
|
|
@@ -1,24 +1,100 @@
|
|
|
1
|
-
|
|
1
|
+
import isEqual from 'lodash/isEqual';
|
|
2
|
+
import React, { Component } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { findDOMNode } from 'react-dom';
|
|
5
|
+
import gsap from 'gsap';
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* Handles a transition of an object.
|
|
3
9
|
* This component only can have one child element at a time!
|
|
4
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
class Transition extends Component {
|
|
12
|
+
/**
|
|
5
13
|
* Runs the transition animation initially.
|
|
6
|
-
*/
|
|
14
|
+
*/
|
|
15
|
+
componentDidMount() {
|
|
16
|
+
this.animate();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
7
20
|
* Checks if transition related props (from/to) have updated and runs the animation.
|
|
8
21
|
* @param {Object} nextProps - The received props.
|
|
9
|
-
*/
|
|
22
|
+
*/
|
|
23
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
24
|
+
if (!isEqual(this.props.from, nextProps.from) || !isEqual(this.props.to, nextProps.to)) {
|
|
25
|
+
this.animate(nextProps);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
10
30
|
* Returns the first child of children.
|
|
11
31
|
* @returns {React.Element}
|
|
12
|
-
*/
|
|
32
|
+
*/
|
|
33
|
+
getFirstChild() {
|
|
34
|
+
return React.Children.map(this.props.children, (element, idx) => (/*#__PURE__*/React.cloneElement(element, {
|
|
35
|
+
ref: idx
|
|
36
|
+
})))[0];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
13
40
|
* Sets the transition state and runs the transition animation.
|
|
14
41
|
* @param {Object} props - The props object the animation should be based upon.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
42
|
+
*/
|
|
43
|
+
animate(props = this.props) {
|
|
44
|
+
// eslint-disable-next-line react/no-find-dom-node, react/no-string-refs
|
|
45
|
+
const element = findDOMNode(this.refs[0]);
|
|
46
|
+
const duration = props.duration / 1000;
|
|
47
|
+
const transitionSettings = {
|
|
48
|
+
ease: props.easing,
|
|
49
|
+
transformOrigin: props.origin,
|
|
50
|
+
onComplete: props.onComplete,
|
|
51
|
+
force3D: true,
|
|
52
|
+
immediateRender: true
|
|
53
|
+
};
|
|
54
|
+
if (props.set) {
|
|
55
|
+
// Sets properties to an absolute state.
|
|
56
|
+
gsap.set(element, props.set);
|
|
57
|
+
}
|
|
58
|
+
if (this.tween) {
|
|
59
|
+
// Remove previously set tween.
|
|
60
|
+
this.tween.kill();
|
|
61
|
+
}
|
|
62
|
+
if (props.from && props.to) {
|
|
63
|
+
// Starts a {from} -> {to} transition.
|
|
64
|
+
this.tween = gsap.fromTo(element, duration, props.from, {
|
|
65
|
+
...props.to,
|
|
66
|
+
...transitionSettings
|
|
67
|
+
});
|
|
68
|
+
} else if (props.from) {
|
|
69
|
+
// Starts a {from} only transition.
|
|
70
|
+
this.tween = gsap.from(element, duration, {
|
|
71
|
+
...props.from,
|
|
72
|
+
...transitionSettings
|
|
73
|
+
});
|
|
74
|
+
} else if (props.to) {
|
|
75
|
+
// Starts a {to} only transition.
|
|
76
|
+
this.tween = gsap.to(element, duration, {
|
|
77
|
+
...props.to,
|
|
78
|
+
...transitionSettings
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
22
84
|
* Renders the component.
|
|
23
85
|
* @returns {JSX}
|
|
24
|
-
*/
|
|
86
|
+
*/
|
|
87
|
+
render() {
|
|
88
|
+
return React.Children.only(this.getFirstChild());
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
Transition.defaultProps = {
|
|
92
|
+
easing: 'Power1.easeOut',
|
|
93
|
+
origin: '0 0 0',
|
|
94
|
+
duration: 150,
|
|
95
|
+
from: null,
|
|
96
|
+
onComplete: () => {},
|
|
97
|
+
set: null,
|
|
98
|
+
to: null
|
|
99
|
+
};
|
|
100
|
+
export default Transition;
|
|
@@ -1,8 +1,56 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { Component, Suspense } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import isEqual from 'lodash/isEqual';
|
|
4
|
+
import Loading from "../../../Loading";
|
|
5
|
+
import Grid from "../../../Grid";
|
|
6
|
+
import styles from "./style";
|
|
7
|
+
/**
|
|
2
8
|
* The widget component.
|
|
3
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
class Widget extends Component {
|
|
11
|
+
/**
|
|
4
12
|
* @param {Object} nextProps The next component props.
|
|
5
13
|
* @return {boolean}
|
|
6
|
-
*/
|
|
14
|
+
*/
|
|
15
|
+
shouldComponentUpdate(nextProps) {
|
|
16
|
+
if (this.props.component !== nextProps.component) return true;
|
|
17
|
+
if (!isEqual(this.props.config, nextProps.config)) return true;
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
7
22
|
* @return {JSX}
|
|
8
|
-
*/
|
|
23
|
+
*/
|
|
24
|
+
render() {
|
|
25
|
+
const {
|
|
26
|
+
col,
|
|
27
|
+
row,
|
|
28
|
+
height,
|
|
29
|
+
settings,
|
|
30
|
+
width
|
|
31
|
+
} = this.props.config;
|
|
32
|
+
if (!this.props.component) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return /*#__PURE__*/React.createElement(Grid.Item, {
|
|
36
|
+
className: `common__widgets__widget ${styles.widgetCell({
|
|
37
|
+
col,
|
|
38
|
+
row,
|
|
39
|
+
height,
|
|
40
|
+
width
|
|
41
|
+
})}`,
|
|
42
|
+
component: "div"
|
|
43
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
44
|
+
className: styles.content
|
|
45
|
+
}, /*#__PURE__*/React.createElement(Suspense, {
|
|
46
|
+
fallback: /*#__PURE__*/React.createElement(Loading, null)
|
|
47
|
+
}, /*#__PURE__*/React.createElement(this.props.component, {
|
|
48
|
+
settings,
|
|
49
|
+
ratio: [width, height]
|
|
50
|
+
}))));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
Widget.defaultProps = {
|
|
54
|
+
component: null
|
|
55
|
+
};
|
|
56
|
+
export default Widget;
|
|
@@ -1,5 +1,70 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
import Grid from "../../../Grid";
|
|
4
|
+
import Widget from "./index";
|
|
5
|
+
jest.mock('react', () => ({
|
|
6
|
+
...require.requireActual('react'),
|
|
7
|
+
Suspense: function Suspense({
|
|
8
|
+
children
|
|
9
|
+
}) {
|
|
10
|
+
return children;
|
|
11
|
+
}
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
/**
|
|
2
15
|
* A dummy component.
|
|
3
16
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
5
|
-
|
|
17
|
+
*/
|
|
18
|
+
const MyComponent = () => /*#__PURE__*/React.createElement("div", null);
|
|
19
|
+
const widgets = {
|
|
20
|
+
'@shopgate/commerce-widgets/image': MyComponent
|
|
21
|
+
};
|
|
22
|
+
describe('<Widget />', () => {
|
|
23
|
+
it('should render an image widget', () => {
|
|
24
|
+
const config = {
|
|
25
|
+
type: '@shopgate/commerce-widgets/image',
|
|
26
|
+
col: 1,
|
|
27
|
+
row: 1,
|
|
28
|
+
width: 12,
|
|
29
|
+
height: 6
|
|
30
|
+
};
|
|
31
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Widget, {
|
|
32
|
+
config: config,
|
|
33
|
+
component: widgets[config.type]
|
|
34
|
+
}));
|
|
35
|
+
expect(wrapper).toMatchSnapshot();
|
|
36
|
+
expect(wrapper.find(Grid.Item).exists()).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('should render an image widget with offset', () => {
|
|
39
|
+
const config = {
|
|
40
|
+
type: '@shopgate/commerce-widgets/image',
|
|
41
|
+
col: 1,
|
|
42
|
+
row: 1,
|
|
43
|
+
width: 6,
|
|
44
|
+
height: 6
|
|
45
|
+
};
|
|
46
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Widget, {
|
|
47
|
+
config: config,
|
|
48
|
+
component: widgets[config.type],
|
|
49
|
+
cellSize: 100
|
|
50
|
+
}));
|
|
51
|
+
expect(wrapper).toMatchSnapshot();
|
|
52
|
+
expect(wrapper.find(Grid.Item).exists()).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('should not render when the `type` prop is invalid', () => {
|
|
55
|
+
const config = {
|
|
56
|
+
type: 'some_widget',
|
|
57
|
+
// Invalid
|
|
58
|
+
col: 1,
|
|
59
|
+
row: 1,
|
|
60
|
+
width: 12,
|
|
61
|
+
height: 6
|
|
62
|
+
};
|
|
63
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Widget, {
|
|
64
|
+
config: config,
|
|
65
|
+
component: widgets[config.type]
|
|
66
|
+
}));
|
|
67
|
+
expect(wrapper).toMatchSnapshot();
|
|
68
|
+
expect(wrapper.find(Grid.Item).exists()).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -1,9 +1,27 @@
|
|
|
1
|
-
import{css}from'glamor'
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates a widget cell grid style.
|
|
3
5
|
* @param {number} col Col index.
|
|
4
6
|
* @param {number} row Row index.
|
|
5
7
|
* @param {number} width Width.
|
|
6
8
|
* @param {number} height Height.
|
|
7
|
-
* @param {
|
|
9
|
+
* @param {boolean} visible Visible.
|
|
8
10
|
* @returns {string}
|
|
9
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
function widgetCell({
|
|
13
|
+
col,
|
|
14
|
+
row,
|
|
15
|
+
width,
|
|
16
|
+
height
|
|
17
|
+
}) {
|
|
18
|
+
return css({
|
|
19
|
+
gridColumnStart: col + 1,
|
|
20
|
+
gridColumnEnd: col + width + 1,
|
|
21
|
+
gridRowStart: row + 1,
|
|
22
|
+
gridRowEnd: row + height + 1
|
|
23
|
+
}).toString();
|
|
24
|
+
}
|
|
25
|
+
export default {
|
|
26
|
+
widgetCell
|
|
27
|
+
};
|