@shopgate/pwa-common 7.30.0-alpha.7 → 7.30.0-alpha.9
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 +214 -7
- 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 +21 -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 +228 -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 -4
- 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 +1,76 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount, shallow } from 'enzyme';
|
|
3
|
+
import Drawer from "./index";
|
|
4
|
+
jest.mock('@shopgate/engage/a11y/components');
|
|
5
|
+
describe('<Drawer />', () => {
|
|
6
|
+
const onOpen = jest.fn();
|
|
7
|
+
const onClose = jest.fn();
|
|
8
|
+
const onDidOpen = jest.fn();
|
|
9
|
+
const onDidClose = jest.fn();
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
it('should render', () => {
|
|
14
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Drawer, null));
|
|
15
|
+
expect(wrapper).toMatchSnapshot();
|
|
16
|
+
});
|
|
17
|
+
it('should execute callback when drawer is opened', () => {
|
|
18
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Drawer, {
|
|
19
|
+
onOpen: onOpen
|
|
20
|
+
}));
|
|
21
|
+
wrapper.setProps({
|
|
22
|
+
isOpen: true
|
|
23
|
+
});
|
|
24
|
+
expect(onOpen).toBeCalled();
|
|
25
|
+
});
|
|
26
|
+
it('should execute callback when drawer is closed', () => {
|
|
27
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Drawer, {
|
|
28
|
+
isOpen: true,
|
|
29
|
+
onClose: onClose
|
|
30
|
+
}));
|
|
31
|
+
wrapper.setProps({
|
|
32
|
+
isOpen: false
|
|
33
|
+
});
|
|
34
|
+
expect(onClose).toBeCalled();
|
|
35
|
+
});
|
|
36
|
+
it('should add custom classes', () => {
|
|
37
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Drawer, {
|
|
38
|
+
className: "custom-class-name",
|
|
39
|
+
isOpen: true
|
|
40
|
+
}));
|
|
41
|
+
expect(wrapper).toMatchSnapshot();
|
|
42
|
+
expect(wrapper.hasClass('custom-class-name')).toEqual(true);
|
|
43
|
+
});
|
|
44
|
+
it('should execute callback when drawer open animation did end', () => {
|
|
45
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Drawer, {
|
|
46
|
+
className: "custom-class-name",
|
|
47
|
+
isOpen: false,
|
|
48
|
+
onOpen: onOpen,
|
|
49
|
+
onDidOpen: onDidOpen
|
|
50
|
+
}));
|
|
51
|
+
expect(wrapper).toMatchSnapshot();
|
|
52
|
+
wrapper.setProps({
|
|
53
|
+
isOpen: true
|
|
54
|
+
});
|
|
55
|
+
expect(onOpen).toBeCalled();
|
|
56
|
+
expect(onDidOpen).not.toBeCalled();
|
|
57
|
+
wrapper.simulate('animationEnd');
|
|
58
|
+
expect(onDidOpen).toBeCalled();
|
|
59
|
+
});
|
|
60
|
+
it('should execute callback when drawer close animation did end', () => {
|
|
61
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Drawer, {
|
|
62
|
+
className: "custom-class-name",
|
|
63
|
+
isOpen: true,
|
|
64
|
+
onClose: onClose,
|
|
65
|
+
onDidClose: onDidClose
|
|
66
|
+
}));
|
|
67
|
+
expect(wrapper).toMatchSnapshot();
|
|
68
|
+
wrapper.setProps({
|
|
69
|
+
isOpen: false
|
|
70
|
+
});
|
|
71
|
+
expect(onClose).toBeCalled();
|
|
72
|
+
expect(onDidClose).not.toBeCalled();
|
|
73
|
+
wrapper.simulate('animationEnd');
|
|
74
|
+
expect(onDidClose).toBeCalled();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -1 +1,37 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
const duration = 150;
|
|
3
|
+
const easing = 'ease';
|
|
4
|
+
const slideInBaseDrawer = css.keyframes({
|
|
5
|
+
'0%': {
|
|
6
|
+
transform: 'translateY(100%)'
|
|
7
|
+
},
|
|
8
|
+
'100%': {
|
|
9
|
+
transform: 'translateY(0)'
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
const slideOutBaseDrawer = css.keyframes({
|
|
13
|
+
'0%': {
|
|
14
|
+
transform: 'translateY(0)'
|
|
15
|
+
},
|
|
16
|
+
'100%': {
|
|
17
|
+
transform: 'translateY(100%)'
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const container = css({
|
|
21
|
+
position: 'fixed',
|
|
22
|
+
bottom: 0,
|
|
23
|
+
left: 0,
|
|
24
|
+
zIndex: 5
|
|
25
|
+
}).toString();
|
|
26
|
+
const animation = {
|
|
27
|
+
in: css({
|
|
28
|
+
animation: `${slideInBaseDrawer} ${duration}ms 1 forwards ${easing}`
|
|
29
|
+
}).toString(),
|
|
30
|
+
out: css({
|
|
31
|
+
animation: `${slideOutBaseDrawer} ${duration}ms 1 forwards ${easing}`
|
|
32
|
+
}).toString()
|
|
33
|
+
};
|
|
34
|
+
export default {
|
|
35
|
+
container,
|
|
36
|
+
animation
|
|
37
|
+
};
|
|
@@ -1,17 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { Component } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import Transition from "../Transition";
|
|
5
|
+
import styles from "./style";
|
|
6
|
+
import transitions from "./transitions";
|
|
7
|
+
|
|
8
|
+
/**
|
|
2
9
|
* This component slides it's child content up or down based on it's isOpen property.
|
|
3
10
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
class Dropdown extends Component {
|
|
13
|
+
/**
|
|
5
14
|
* Constructor
|
|
6
15
|
* @param {Object} props Props of the Component
|
|
7
|
-
*/
|
|
16
|
+
*/
|
|
17
|
+
constructor(props) {
|
|
18
|
+
super(props);
|
|
19
|
+
this.state = {
|
|
20
|
+
initialRender: true
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
8
25
|
* Update the initialRender state if the isOpen state changes from false to true
|
|
9
26
|
* @param {Object} nextProps The new props
|
|
10
|
-
*/
|
|
27
|
+
*/
|
|
28
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
29
|
+
if (this.props.isOpen === false && nextProps.isOpen === true) {
|
|
30
|
+
this.setState({
|
|
31
|
+
initialRender: false
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
11
37
|
* Only update the component if isOpen changed
|
|
12
38
|
* @param {Object} nextProps The new props
|
|
13
39
|
* @returns {boolean}
|
|
14
|
-
*/
|
|
40
|
+
*/
|
|
41
|
+
shouldComponentUpdate(nextProps) {
|
|
42
|
+
return this.props.isOpen !== nextProps.isOpen;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
15
46
|
* Renders the component.
|
|
16
47
|
* @returns {JSX}
|
|
17
|
-
*/
|
|
48
|
+
*/
|
|
49
|
+
render() {
|
|
50
|
+
let transitionProps;
|
|
51
|
+
if (this.props.isOpen) {
|
|
52
|
+
transitionProps = this.state.initialRender ? transitions.initialOpen : transitions.open;
|
|
53
|
+
} else {
|
|
54
|
+
transitionProps = this.state.initialRender ? transitions.initialClose : transitions.close;
|
|
55
|
+
}
|
|
56
|
+
return /*#__PURE__*/React.createElement(Transition, _extends({}, transitionProps, {
|
|
57
|
+
onComplete: this.props.onComplete,
|
|
58
|
+
onStart: this.props.onStart,
|
|
59
|
+
duration: this.props.duration,
|
|
60
|
+
easing: this.props.easing
|
|
61
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
62
|
+
className: `${styles} ${this.props.className} common__dropdown`,
|
|
63
|
+
"aria-hidden": !this.props.isOpen
|
|
64
|
+
}, this.props.children));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
Dropdown.defaultProps = {
|
|
68
|
+
className: '',
|
|
69
|
+
children: null,
|
|
70
|
+
duration: 150,
|
|
71
|
+
easing: null,
|
|
72
|
+
isOpen: false,
|
|
73
|
+
onComplete: () => {},
|
|
74
|
+
onStart: () => {}
|
|
75
|
+
};
|
|
76
|
+
export default Dropdown;
|
|
@@ -1 +1,34 @@
|
|
|
1
|
-
export default{
|
|
1
|
+
export default {
|
|
2
|
+
open: {
|
|
3
|
+
set: {
|
|
4
|
+
height: 'auto'
|
|
5
|
+
},
|
|
6
|
+
from: {
|
|
7
|
+
height: 0
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
initialOpen: {
|
|
11
|
+
set: {
|
|
12
|
+
height: 'auto'
|
|
13
|
+
},
|
|
14
|
+
from: {
|
|
15
|
+
height: 'auto'
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
close: {
|
|
19
|
+
from: {
|
|
20
|
+
height: 'auto'
|
|
21
|
+
},
|
|
22
|
+
to: {
|
|
23
|
+
height: 0
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
initialClose: {
|
|
27
|
+
from: {
|
|
28
|
+
height: 0
|
|
29
|
+
},
|
|
30
|
+
to: {
|
|
31
|
+
height: 0
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Dotdotdot from 'react-dotdotdot';
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* The ellipsis text component.
|
|
3
7
|
* @param {Object} props The component props.
|
|
4
8
|
* @returns {JSX.Element}
|
|
5
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
const Ellipsis = props => /*#__PURE__*/React.createElement(Dotdotdot, {
|
|
11
|
+
clamp: props.rows,
|
|
12
|
+
className: `${props.className} common__ellipsis`,
|
|
13
|
+
useNativeClamp: true
|
|
14
|
+
}, props.children);
|
|
15
|
+
Ellipsis.defaultProps = {
|
|
16
|
+
className: '',
|
|
17
|
+
rows: 3
|
|
18
|
+
};
|
|
19
|
+
export default Ellipsis;
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import Ellipsis from "./index";
|
|
4
|
+
const clamp = 3;
|
|
5
|
+
const text = 'Some very long text that should be cut off by this ellipsis component.';
|
|
6
|
+
describe('<Ellipsis />', () => {
|
|
7
|
+
it('should render', () => {
|
|
8
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Ellipsis, {
|
|
9
|
+
rows: clamp
|
|
10
|
+
}, text));
|
|
11
|
+
expect(wrapper).toMatchSnapshot();
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -1,11 +1,61 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { Fragment, useMemo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Helmet from 'react-helmet';
|
|
4
|
+
import { embeddedMedia } from '@shopgate/pwa-common/collections';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* EmbeddedMedia component. Handles loading of media related scripts e.g. the Vimeo Player.
|
|
3
8
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
5
|
-
|
|
9
|
+
*/
|
|
10
|
+
const EmbeddedMedia = ({
|
|
11
|
+
children,
|
|
12
|
+
cookieConsentSettings
|
|
13
|
+
}) => {
|
|
14
|
+
const cookieConsent = useMemo(() => ({
|
|
15
|
+
comfortCookiesAccepted: false,
|
|
16
|
+
statisticsCookiesAccepted: false,
|
|
17
|
+
...cookieConsentSettings
|
|
18
|
+
}), [cookieConsentSettings]);
|
|
19
|
+
if (!embeddedMedia.getHasPendingProviders() || !cookieConsent.comfortCookiesAccepted) {
|
|
20
|
+
return children;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Get all pending providers
|
|
24
|
+
const pendingProviders = Array.from(embeddedMedia.providers).filter(p => p.isPending);
|
|
25
|
+
|
|
26
|
+
/**
|
|
6
27
|
* Inject onLoad cb to script tags
|
|
7
28
|
* @param {Element[]} scriptTags script tags to listen for
|
|
8
29
|
* @param {MediaProvider} provider Provider
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
30
|
+
*/
|
|
31
|
+
const updateProviderScripts = ({
|
|
32
|
+
scriptTags
|
|
33
|
+
}) => {
|
|
34
|
+
if (scriptTags) {
|
|
35
|
+
scriptTags.forEach(scriptTag => {
|
|
36
|
+
const provider = pendingProviders.find(p => p.remoteScriptUrl === scriptTag.getAttribute('src'));
|
|
37
|
+
// eslint-disable-next-line no-param-reassign
|
|
38
|
+
scriptTag.onload = () => {
|
|
39
|
+
provider.onScriptLoaded();
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const scripts = pendingProviders.map(provider => ({
|
|
45
|
+
src: provider.remoteScriptUrl,
|
|
46
|
+
type: 'text/javascript'
|
|
47
|
+
}));
|
|
48
|
+
return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(Helmet, {
|
|
49
|
+
script: scripts
|
|
50
|
+
// Helmet doesn't support `onload` in script objects so we have to hack in our own
|
|
51
|
+
,
|
|
52
|
+
onChangeClientState: (newState, addedTags) => updateProviderScripts(addedTags)
|
|
53
|
+
}), children);
|
|
54
|
+
};
|
|
55
|
+
EmbeddedMedia.defaultProps = {
|
|
56
|
+
cookieConsentSettings: {
|
|
57
|
+
comfortCookiesAccepted: false,
|
|
58
|
+
statisticsCookiesAccepted: false
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
export default EmbeddedMedia;
|
|
@@ -1,3 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import { embeddedMedia } from '@shopgate/pwa-common/collections';
|
|
4
|
+
import EmbeddedMedia from "./index";
|
|
5
|
+
jest.mock('@shopgate/pwa-common/collections', () => ({
|
|
6
|
+
embeddedMedia: {
|
|
7
|
+
getHasPendingProviders: jest.fn(),
|
|
8
|
+
providers: new Set([{
|
|
9
|
+
isPending: false,
|
|
10
|
+
remoteScriptUrl: 'http://foo.bar'
|
|
11
|
+
}, {
|
|
12
|
+
isPending: true,
|
|
13
|
+
remoteScriptUrl: 'http://bar.foo',
|
|
14
|
+
onScriptLoaded: jest.fn()
|
|
15
|
+
}])
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
18
|
+
describe('<EmbeddedMedia />', () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
jest.clearAllMocks();
|
|
21
|
+
});
|
|
22
|
+
it('should return children', () => {
|
|
23
|
+
embeddedMedia.getHasPendingProviders.mockReturnValueOnce(false);
|
|
24
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(EmbeddedMedia, null, /*#__PURE__*/React.createElement("div", null, "Children")));
|
|
25
|
+
expect(wrapper.html()).toEqual('<div>Children</div>');
|
|
26
|
+
});
|
|
27
|
+
it.skip('should render Helmet with a script', () => {
|
|
28
|
+
embeddedMedia.getHasPendingProviders.mockReturnValueOnce(true);
|
|
29
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(EmbeddedMedia, null, /*#__PURE__*/React.createElement("div", null, "Content with embedded media (youtube, vimeo, etc)")));
|
|
30
|
+
const helmetProps = wrapper.find('HelmetWrapper').props();
|
|
31
|
+
expect(helmetProps).toEqual({
|
|
32
|
+
defer: true,
|
|
33
|
+
encodeSpecialCharacters: true,
|
|
34
|
+
onChangeClientState() {},
|
|
35
|
+
script: []
|
|
36
|
+
});
|
|
37
|
+
const scriptTags = [{
|
|
38
|
+
onload: jest.fn(),
|
|
39
|
+
getAttribute: jest.fn().mockReturnValue('http://bar.foo')
|
|
40
|
+
}];
|
|
41
|
+
|
|
42
|
+
// Invoke helmet cb
|
|
43
|
+
helmetProps.onChangeClientState(null, {
|
|
44
|
+
scriptTags
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Invoke onload on script
|
|
48
|
+
scriptTags[0].onload();
|
|
49
|
+
const [, secondProvider] = embeddedMedia.providers;
|
|
50
|
+
expect(secondProvider.onScriptLoaded).toHaveBeenCalledTimes(1);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import{connect}from'react-redux';
|
|
1
|
+
import { connect } from 'react-redux';
|
|
2
|
+
import { appError } from "../../action-creators/error";
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* Connects the dispatch function to a callable function in the props.
|
|
3
6
|
* @param {Function} dispatch The redux dispatch function.
|
|
4
7
|
* @return {Object} The extended component props.
|
|
5
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
const mapDispatchToProps = dispatch => ({
|
|
10
|
+
appError: error => dispatch(appError(error))
|
|
11
|
+
});
|
|
12
|
+
export default connect(null, mapDispatchToProps);
|
|
@@ -1,11 +1,47 @@
|
|
|
1
|
-
|
|
1
|
+
import { PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import connector from "./connector";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* The App error boundary component.
|
|
3
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
class ErrorBoundary extends PureComponent {
|
|
9
|
+
constructor(...args) {
|
|
10
|
+
super(...args);
|
|
11
|
+
this.state = {
|
|
12
|
+
hasError: false
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @returns {{hasError: boolean}}
|
|
17
|
+
*/
|
|
18
|
+
static getDerivedStateFromError() {
|
|
19
|
+
return {
|
|
20
|
+
hasError: true
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
4
25
|
* @param {Object} error The error object.
|
|
5
26
|
* @param {Object} errorInfo The error information.
|
|
6
|
-
*/
|
|
7
|
-
error
|
|
27
|
+
*/
|
|
28
|
+
componentDidCatch(error, errorInfo) {
|
|
29
|
+
// eslint-disable-next-line no-param-reassign
|
|
30
|
+
error.stack = errorInfo.componentStack;
|
|
31
|
+
this.props.appError(error);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
8
35
|
* @returns {JSX}
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
36
|
+
*/
|
|
37
|
+
render() {
|
|
38
|
+
if (this.state.hasError) {
|
|
39
|
+
return this.props.fallbackUi;
|
|
40
|
+
}
|
|
41
|
+
return this.props.children;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
ErrorBoundary.defaultProps = {
|
|
45
|
+
fallbackUi: null
|
|
46
|
+
};
|
|
47
|
+
export default connector(ErrorBoundary);
|
|
@@ -1,9 +1,45 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { objectWithoutProps } from "../../../../helpers/data";
|
|
4
|
+
import styles from "./style";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The grid item component.
|
|
3
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
class GridItem extends Component {
|
|
10
|
+
/**
|
|
4
11
|
* Composes the props.
|
|
5
12
|
* @returns {Object} The composed props.
|
|
6
|
-
*/
|
|
13
|
+
*/
|
|
14
|
+
getProps() {
|
|
15
|
+
let {
|
|
16
|
+
className
|
|
17
|
+
} = this.props;
|
|
18
|
+
if (this.props.grow !== 0) {
|
|
19
|
+
className += ` ${styles.grow(this.props.grow)}`;
|
|
20
|
+
}
|
|
21
|
+
if (this.props.shrink !== 1) {
|
|
22
|
+
className += ` ${styles.shrink(this.props.shrink)}`;
|
|
23
|
+
}
|
|
24
|
+
const props = {
|
|
25
|
+
...this.props,
|
|
26
|
+
className
|
|
27
|
+
};
|
|
28
|
+
return objectWithoutProps(props, ['component', 'grow', 'shrink']);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
7
32
|
* Renders the component.
|
|
8
33
|
* @returns {JSX}
|
|
9
|
-
*/
|
|
34
|
+
*/
|
|
35
|
+
render() {
|
|
36
|
+
return /*#__PURE__*/React.createElement(this.props.component, this.getProps());
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
GridItem.defaultProps = {
|
|
40
|
+
className: '',
|
|
41
|
+
component: 'li',
|
|
42
|
+
grow: 0,
|
|
43
|
+
shrink: 1
|
|
44
|
+
};
|
|
45
|
+
export default GridItem;
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import GridItem from "./index";
|
|
4
|
+
describe('<GridItem />', () => {
|
|
5
|
+
it('should render without any further props', () => {
|
|
6
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(GridItem, null));
|
|
7
|
+
expect(wrapper).toMatchSnapshot();
|
|
8
|
+
});
|
|
9
|
+
it('should be able to render a custom tag', () => {
|
|
10
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(GridItem, {
|
|
11
|
+
component: "section"
|
|
12
|
+
}));
|
|
13
|
+
expect(wrapper).toMatchSnapshot();
|
|
14
|
+
expect(wrapper.type()).toEqual('section');
|
|
15
|
+
});
|
|
16
|
+
it('should add custom classes on demand', () => {
|
|
17
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(GridItem, {
|
|
18
|
+
className: "custom-class-name"
|
|
19
|
+
}));
|
|
20
|
+
expect(wrapper).toMatchSnapshot();
|
|
21
|
+
expect(wrapper.hasClass('custom-class-name')).toEqual(true);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import{css}from'glamor'
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates a class name for the flex-grow property
|
|
3
5
|
* @param {number} [value=0] The value for the flex-grow property
|
|
4
6
|
* @return {string} The class name
|
|
5
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
const grow = (value = 0) => css({
|
|
9
|
+
flexGrow: value
|
|
10
|
+
}).toString();
|
|
11
|
+
|
|
12
|
+
/**
|
|
6
13
|
* Creates a class name for the flex-shrink property
|
|
7
14
|
* @param {number} [value=0] The value for the flex-shrink property
|
|
8
15
|
* @return {string} The class name
|
|
9
|
-
*/
|
|
16
|
+
*/
|
|
17
|
+
const shrink = (value = 1) => css({
|
|
18
|
+
flexShrink: value
|
|
19
|
+
}).toString();
|
|
20
|
+
export default {
|
|
21
|
+
grow,
|
|
22
|
+
shrink
|
|
23
|
+
};
|