@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,4 +1,88 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow, mount } from 'enzyme';
|
|
3
|
+
import Select from "./index";
|
|
4
|
+
import SelectItem from "./components/Item";
|
|
5
|
+
describe('<Select />', () => {
|
|
6
|
+
jest.useFakeTimers();
|
|
7
|
+
it('opens and closes the item list', () => {
|
|
8
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Select, null));
|
|
9
|
+
let previousOpenState = wrapper.state('isOpen');
|
|
10
|
+
wrapper.instance().toggleOpenState();
|
|
11
|
+
expect(wrapper.state('isOpen')).toBe(!previousOpenState);
|
|
12
|
+
previousOpenState = wrapper.state('isOpen');
|
|
13
|
+
wrapper.instance().toggleOpenState();
|
|
14
|
+
expect(wrapper.state('isOpen')).toBe(!previousOpenState);
|
|
15
|
+
});
|
|
16
|
+
it('renders without items', () => {
|
|
17
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Select, null));
|
|
18
|
+
wrapper.instance().toggleOpenState();
|
|
19
|
+
expect(wrapper).toMatchSnapshot();
|
|
20
|
+
expect(wrapper.find(SelectItem).length).toBe(0);
|
|
21
|
+
});
|
|
22
|
+
it('renders with implicit items (closed)', () => {
|
|
23
|
+
const items = ['a', 'b', 'c', 'd', 'e', 'f'];
|
|
24
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Select, {
|
|
25
|
+
items: items
|
|
26
|
+
}));
|
|
27
|
+
expect(wrapper).toMatchSnapshot();
|
|
28
|
+
expect(wrapper.find(SelectItem).length).toBe(0);
|
|
29
|
+
});
|
|
30
|
+
it('renders with implicit items (opened)', () => {
|
|
31
|
+
const items = ['a', 'b', 'c', 'd', 'e', 'f'];
|
|
32
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Select, {
|
|
33
|
+
items: items
|
|
34
|
+
}));
|
|
35
|
+
wrapper.instance().toggleOpenState();
|
|
36
|
+
wrapper.update();
|
|
37
|
+
expect(wrapper).toMatchSnapshot();
|
|
38
|
+
expect(wrapper.find(SelectItem).length).toBe(items.length);
|
|
39
|
+
});
|
|
40
|
+
it('accepts implicit and explicit items', () => {
|
|
41
|
+
const items = ['a', 'b', {
|
|
42
|
+
value: 'c'
|
|
43
|
+
}, 'd', {
|
|
44
|
+
value: 'e',
|
|
45
|
+
label: 'E'
|
|
46
|
+
}, 'f'];
|
|
47
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Select, {
|
|
48
|
+
items: items
|
|
49
|
+
}));
|
|
50
|
+
wrapper.instance().toggleOpenState();
|
|
51
|
+
wrapper.update();
|
|
52
|
+
expect(wrapper).toMatchSnapshot();
|
|
53
|
+
expect(wrapper.find(SelectItem).length).toBe(items.length);
|
|
54
|
+
let i = 0;
|
|
55
|
+
wrapper.find(SelectItem).forEach(item => {
|
|
56
|
+
let expectedLabel = items[i];
|
|
57
|
+
if (expectedLabel.label) {
|
|
58
|
+
expectedLabel = expectedLabel.label;
|
|
59
|
+
}
|
|
60
|
+
if (expectedLabel.value) {
|
|
61
|
+
expectedLabel = expectedLabel.value;
|
|
62
|
+
}
|
|
63
|
+
expect(item.prop('label')).toBe(expectedLabel);
|
|
64
|
+
i += 1;
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
it('triggers callback on change', () => {
|
|
68
|
+
const items = ['a', 'b', 'c', 'd', 'e', 'f'];
|
|
69
|
+
const selectionIndex = Math.floor(items.length / 2);
|
|
70
|
+
|
|
71
|
+
/**
|
|
2
72
|
* Mocked callback for the onSelect event
|
|
3
73
|
* @param {string} value Mocked value
|
|
4
|
-
*/
|
|
74
|
+
*/
|
|
75
|
+
const callback = value => {
|
|
76
|
+
expect(value).toBe(items[selectionIndex]);
|
|
77
|
+
};
|
|
78
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Select, {
|
|
79
|
+
items: items,
|
|
80
|
+
onChange: callback
|
|
81
|
+
}));
|
|
82
|
+
wrapper.instance().toggleOpenState();
|
|
83
|
+
wrapper.update();
|
|
84
|
+
expect(wrapper).toMatchSnapshot();
|
|
85
|
+
const node = wrapper.find(SelectItem).at(selectionIndex);
|
|
86
|
+
node.prop('onSelect')(node.prop('value'), node.prop('label'));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
const container = css({
|
|
3
|
+
margin: 0,
|
|
4
|
+
padding: 0
|
|
5
|
+
}).toString();
|
|
6
|
+
const selectHandle = css({
|
|
7
|
+
float: 'right'
|
|
8
|
+
}).toString();
|
|
9
|
+
const items = css({
|
|
10
|
+
position: 'absolute',
|
|
11
|
+
width: '100%'
|
|
12
|
+
}).toString();
|
|
13
|
+
export default {
|
|
14
|
+
container,
|
|
15
|
+
selectHandle,
|
|
16
|
+
items
|
|
17
|
+
};
|
|
@@ -1,10 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import I18n from "../../../I18n";
|
|
5
|
+
import { item } from "./style";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* The SelectBoxItem component.
|
|
3
9
|
* @param {Object} props The components props.
|
|
4
10
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
*/
|
|
12
|
+
class SelectBoxItem extends Component {
|
|
13
|
+
constructor(...args) {
|
|
14
|
+
super(...args);
|
|
15
|
+
/**
|
|
16
|
+
* Calls the handleSelectionUpdate prop and prevents further events.
|
|
17
|
+
*/
|
|
18
|
+
this.handleSelectionUpdate = () => {
|
|
19
|
+
this.props.handleSelectionUpdate(this.props.value);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
8
23
|
* Renders the component
|
|
9
24
|
* @returns {JSX}
|
|
10
|
-
*/
|
|
25
|
+
*/
|
|
26
|
+
render() {
|
|
27
|
+
const Wrapper = this.props.wrapper;
|
|
28
|
+
const {
|
|
29
|
+
selectItem,
|
|
30
|
+
selectItemSelected
|
|
31
|
+
} = this.props.classNames;
|
|
32
|
+
return /*#__PURE__*/React.createElement("li", {
|
|
33
|
+
className: classNames(selectItem, item, {
|
|
34
|
+
[selectItemSelected]: this.props.isSelected
|
|
35
|
+
}),
|
|
36
|
+
onKeyUp: () => {},
|
|
37
|
+
onClick: this.handleSelectionUpdate,
|
|
38
|
+
"data-test-id": this.props.label,
|
|
39
|
+
role: "menuitem",
|
|
40
|
+
ref: this.props.forwardedRef,
|
|
41
|
+
tabIndex: this.props.isSelected ? '0' : '-1',
|
|
42
|
+
"aria-current": this.props.isSelected
|
|
43
|
+
}, /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(I18n.Text, {
|
|
44
|
+
string: this.props.label
|
|
45
|
+
})));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
SelectBoxItem.defaultProps = {
|
|
49
|
+
forwardedRef: null,
|
|
50
|
+
classNames: {}
|
|
51
|
+
};
|
|
52
|
+
export default SelectBoxItem;
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
export const item = css({
|
|
3
|
+
cursor: 'pointer'
|
|
4
|
+
}).toString();
|
|
5
|
+
export const selected = css({
|
|
6
|
+
fontWeight: 500
|
|
7
|
+
});
|
|
@@ -1,24 +1,180 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import find from 'lodash/find';
|
|
5
|
+
import Dropdown from "../Dropdown";
|
|
6
|
+
import I18n from "../I18n";
|
|
7
|
+
import SelectBoxItem from "./components/Item";
|
|
8
|
+
import styles from "./style";
|
|
9
|
+
|
|
10
|
+
/**
|
|
2
11
|
* The select box component.
|
|
3
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
class SelectBox extends Component {
|
|
14
|
+
/**
|
|
4
15
|
* Initializes the component.
|
|
5
16
|
* @param {Object} props The components props.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
*/
|
|
18
|
+
constructor(props) {
|
|
19
|
+
super(props);
|
|
20
|
+
/**
|
|
21
|
+
* When dropdown animation is finished.
|
|
22
|
+
*/
|
|
23
|
+
this.onDropdownComplete = () => {
|
|
24
|
+
this.dropdownCompleted = true;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Handles any interaction the user does outside of the component.
|
|
28
|
+
* In this case the select gets closed.
|
|
29
|
+
* @param {Object} event The event object.
|
|
30
|
+
*/
|
|
31
|
+
this.handleInteractionOutside = event => {
|
|
32
|
+
this.setState({
|
|
33
|
+
isOpen: false
|
|
34
|
+
});
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
event.stopPropagation();
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Sets the open state to true
|
|
40
|
+
*/
|
|
41
|
+
this.handleOpenList = () => {
|
|
42
|
+
if (this.state.isOpen) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.dropdownCompleted = false;
|
|
46
|
+
this.setState({
|
|
47
|
+
isOpen: true
|
|
48
|
+
});
|
|
49
|
+
if (this.firstItemRef) {
|
|
50
|
+
this.firstItemRef.focus();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Sets the new active selection.
|
|
55
|
+
* @param {string} value Value of the selected item.
|
|
56
|
+
*/
|
|
57
|
+
this.handleSelectionUpdate = value => {
|
|
58
|
+
const selection = find(this.props.items, {
|
|
59
|
+
value
|
|
60
|
+
});
|
|
61
|
+
this.setState({
|
|
62
|
+
selected: selection,
|
|
63
|
+
isOpen: false
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Delay the callback to make sure actions are fired after animations are done.
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
this.props.handleSelectionUpdate(selection.value);
|
|
69
|
+
}, this.props.duration);
|
|
70
|
+
if (this.controlRef) {
|
|
71
|
+
this.controlRef.focus();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/** @param {HTMLElement} ref The element */
|
|
75
|
+
this.setControlRef = ref => {
|
|
76
|
+
this.controlRef = ref;
|
|
77
|
+
};
|
|
78
|
+
/** @param {HTMLElement} ref The element */
|
|
79
|
+
this.setFirstItemRef = ref => {
|
|
80
|
+
this.firstItemRef = ref;
|
|
81
|
+
};
|
|
82
|
+
this.dropdownCompleted = false;
|
|
83
|
+
this.state = {
|
|
84
|
+
isOpen: false,
|
|
85
|
+
selected: find(props.items, {
|
|
86
|
+
value: props.initialValue
|
|
87
|
+
})
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
19
92
|
* Reset selected when changing the initial value.
|
|
20
93
|
* @param {Object} nextProps The next props the component will receive.
|
|
21
|
-
*/
|
|
94
|
+
*/
|
|
95
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
96
|
+
if (this.props.initialValue !== nextProps.initialValue) {
|
|
97
|
+
this.setState({
|
|
98
|
+
selected: find(nextProps.items, {
|
|
99
|
+
value: nextProps.initialValue
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
22
105
|
* Renders the component
|
|
23
106
|
* @returns {JSX}
|
|
24
|
-
*/
|
|
107
|
+
*/
|
|
108
|
+
render() {
|
|
109
|
+
const Icon = this.props.icon;
|
|
110
|
+
const {
|
|
111
|
+
icon,
|
|
112
|
+
iconOpen = null,
|
|
113
|
+
selection,
|
|
114
|
+
button,
|
|
115
|
+
dropdown,
|
|
116
|
+
selectItem,
|
|
117
|
+
selectItemSelected
|
|
118
|
+
} = this.props.classNames;
|
|
119
|
+
const buttonLabel = this.state.selected ? this.state.selected.label : this.props.defaultText;
|
|
120
|
+
const iconClasses = classNames(icon, {
|
|
121
|
+
[iconOpen]: this.state.isOpen && iconOpen !== null
|
|
122
|
+
});
|
|
123
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
124
|
+
className: `${this.props.className} common__select-box`,
|
|
125
|
+
"data-test-id": this.props.testId
|
|
126
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
127
|
+
className: button,
|
|
128
|
+
onClick: this.handleOpenList,
|
|
129
|
+
"data-test-id": buttonLabel,
|
|
130
|
+
type: "button",
|
|
131
|
+
"aria-haspopup": true,
|
|
132
|
+
"aria-expanded": this.state.isOpen ? true : null,
|
|
133
|
+
"aria-controls": buttonLabel,
|
|
134
|
+
ref: this.setControlRef
|
|
135
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
136
|
+
className: selection
|
|
137
|
+
}, /*#__PURE__*/React.createElement(I18n.Text, {
|
|
138
|
+
string: buttonLabel
|
|
139
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
140
|
+
className: iconClasses
|
|
141
|
+
}, /*#__PURE__*/React.createElement(Icon, null))), /*#__PURE__*/React.createElement(Dropdown, {
|
|
142
|
+
className: dropdown,
|
|
143
|
+
isOpen: this.state.isOpen,
|
|
144
|
+
onComplete: this.onDropdownComplete,
|
|
145
|
+
duration: this.props.duration
|
|
146
|
+
}, /*#__PURE__*/React.createElement("ul", {
|
|
147
|
+
role: "menu",
|
|
148
|
+
id: buttonLabel,
|
|
149
|
+
tabIndex: "-1"
|
|
150
|
+
}, this.props.items.map(item => /*#__PURE__*/React.createElement(SelectBoxItem, {
|
|
151
|
+
classNames: {
|
|
152
|
+
selectItem,
|
|
153
|
+
selectItemSelected
|
|
154
|
+
},
|
|
155
|
+
wrapper: this.props.item,
|
|
156
|
+
key: item.value,
|
|
157
|
+
value: item.value,
|
|
158
|
+
label: item.label,
|
|
159
|
+
handleSelectionUpdate: this.handleSelectionUpdate,
|
|
160
|
+
isSelected: buttonLabel === item.label,
|
|
161
|
+
forwardedRef: buttonLabel === item.label ? this.setFirstItemRef : null
|
|
162
|
+
})))), this.state.isOpen && /*#__PURE__*/React.createElement("button", {
|
|
163
|
+
className: styles.overlay,
|
|
164
|
+
onClick: this.handleInteractionOutside,
|
|
165
|
+
onTouchMove: this.handleInteractionOutside,
|
|
166
|
+
type: "button",
|
|
167
|
+
"aria-hidden": true
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
SelectBox.defaultProps = {
|
|
172
|
+
className: '',
|
|
173
|
+
classNames: {},
|
|
174
|
+
duration: 225,
|
|
175
|
+
defaultText: 'filter.sort.default',
|
|
176
|
+
handleSelectionUpdate: () => {},
|
|
177
|
+
initialValue: null,
|
|
178
|
+
testId: null
|
|
179
|
+
};
|
|
180
|
+
export default SelectBox;
|
|
@@ -1,9 +1,65 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { mount } from 'enzyme';
|
|
4
|
+
import SelectBox from "./index";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Mock Icon component.
|
|
3
8
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
const MockIconComponent = () => /*#__PURE__*/React.createElement("span", {
|
|
11
|
+
id: "icon"
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
/**
|
|
5
15
|
* Mock Item component.
|
|
6
16
|
* @param {Object} props The components props.
|
|
7
17
|
* @param {JSX} props.children The components children.
|
|
8
18
|
* @returns {JSX}
|
|
9
|
-
*/
|
|
19
|
+
*/
|
|
20
|
+
const MockItemComponent = ({
|
|
21
|
+
children
|
|
22
|
+
}) => /*#__PURE__*/React.createElement("div", null, children);
|
|
23
|
+
describe('<SelectBox>', () => {
|
|
24
|
+
const dummyItems = [{
|
|
25
|
+
label: 'My item #1',
|
|
26
|
+
value: 'item_1'
|
|
27
|
+
}, {
|
|
28
|
+
label: 'My item #2',
|
|
29
|
+
value: 'item_2'
|
|
30
|
+
}, {
|
|
31
|
+
label: 'My item #3',
|
|
32
|
+
value: 'item_3'
|
|
33
|
+
}];
|
|
34
|
+
it('should render the selectbox with given mock components', () => {
|
|
35
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(SelectBox, {
|
|
36
|
+
icon: MockIconComponent,
|
|
37
|
+
item: MockItemComponent,
|
|
38
|
+
items: dummyItems
|
|
39
|
+
}));
|
|
40
|
+
expect(wrapper).toMatchSnapshot();
|
|
41
|
+
expect(wrapper.find(MockIconComponent).length).toEqual(1);
|
|
42
|
+
expect(wrapper.find(MockItemComponent).length).toEqual(3);
|
|
43
|
+
});
|
|
44
|
+
it('should render with a default text', () => {
|
|
45
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(SelectBox, {
|
|
46
|
+
icon: MockIconComponent,
|
|
47
|
+
item: MockItemComponent,
|
|
48
|
+
items: dummyItems,
|
|
49
|
+
defaultText: "Foo"
|
|
50
|
+
}));
|
|
51
|
+
expect(wrapper).toMatchSnapshot();
|
|
52
|
+
expect(wrapper.find('span').at(0).text()).toEqual('Foo');
|
|
53
|
+
});
|
|
54
|
+
it('should render with a preselected selection', () => {
|
|
55
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(SelectBox, {
|
|
56
|
+
icon: MockIconComponent,
|
|
57
|
+
item: MockItemComponent,
|
|
58
|
+
items: dummyItems,
|
|
59
|
+
defaultText: "Foo",
|
|
60
|
+
initialValue: "item_2"
|
|
61
|
+
}));
|
|
62
|
+
expect(wrapper).toMatchSnapshot();
|
|
63
|
+
expect(wrapper.find('span').at(0).text()).toEqual('My item #2');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -1 +1,18 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
const overlay = css({
|
|
3
|
+
position: 'fixed',
|
|
4
|
+
top: 0,
|
|
5
|
+
left: 0,
|
|
6
|
+
width: '100%',
|
|
7
|
+
height: '100%',
|
|
8
|
+
overflow: 'auto',
|
|
9
|
+
zIndex: 1,
|
|
10
|
+
outline: 0
|
|
11
|
+
}).toString();
|
|
12
|
+
const rotatedIcon = css({
|
|
13
|
+
transform: 'rotate(180deg)'
|
|
14
|
+
}).toString();
|
|
15
|
+
export default {
|
|
16
|
+
overlay,
|
|
17
|
+
rotatedIcon
|
|
18
|
+
};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import Swiper from"../Swiper"
|
|
1
|
+
import Swiper from "../Swiper";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* The basic slider component.
|
|
3
5
|
* @param {Object} props The component properties.
|
|
4
6
|
* @deprecated
|
|
5
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
const Slider = Swiper;
|
|
9
|
+
export default Slider;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import React,{Fragment}from'react';
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Portal from "../Portal";
|
|
4
|
+
import { AFTER, BEFORE } from "../../constants/Portals";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The SurroundPortals component renders three Portal component. The main portal is wrapped around
|
|
3
8
|
* its children, the two additional portals are rendered before and after the main portal.
|
|
4
9
|
* The names of the additional portals are automatically created from the name of the main portal
|
|
@@ -9,4 +14,23 @@ import React,{Fragment}from'react';import PropTypes from'prop-types';import Port
|
|
|
9
14
|
* @param {Object} props.portalProps Props that are assigned to the portals
|
|
10
15
|
* @param {React.ReactNode} props.children Component children
|
|
11
16
|
* @returns {JSX.Element}
|
|
12
|
-
*/
|
|
17
|
+
*/
|
|
18
|
+
const SurroundPortals = ({
|
|
19
|
+
portalName,
|
|
20
|
+
portalProps,
|
|
21
|
+
children
|
|
22
|
+
}) => /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(Portal, {
|
|
23
|
+
name: `${portalName}.${BEFORE}`,
|
|
24
|
+
props: portalProps
|
|
25
|
+
}), /*#__PURE__*/React.createElement(Portal, {
|
|
26
|
+
name: portalName,
|
|
27
|
+
props: portalProps
|
|
28
|
+
}, children), /*#__PURE__*/React.createElement(Portal, {
|
|
29
|
+
name: `${portalName}.${AFTER}`,
|
|
30
|
+
props: portalProps
|
|
31
|
+
}));
|
|
32
|
+
SurroundPortals.defaultProps = {
|
|
33
|
+
children: null,
|
|
34
|
+
portalProps: null
|
|
35
|
+
};
|
|
36
|
+
export default SurroundPortals;
|
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
// eslint-disable-next-line import/no-unresolved
|
|
6
|
+
import { SwiperSlide } from 'swiper/react';
|
|
7
|
+
import { item } from "./styles";
|
|
8
|
+
|
|
9
|
+
/**
|
|
3
10
|
* @typedef {import('swiper/react').SwiperSlideProps} SwiperSlideProps
|
|
4
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
5
14
|
* The basic swiper item component.
|
|
6
15
|
* @param {SwiperSlideProps} props The component props.
|
|
7
16
|
* @returns {React.Node}
|
|
8
|
-
*/
|
|
17
|
+
*/
|
|
18
|
+
function SwiperItem({
|
|
19
|
+
children,
|
|
20
|
+
className,
|
|
21
|
+
...slideProps
|
|
22
|
+
}) {
|
|
23
|
+
return /*#__PURE__*/React.createElement(SwiperSlide, _extends({}, slideProps, {
|
|
24
|
+
className: classNames(item, className),
|
|
25
|
+
"data-test-id": "Slider"
|
|
26
|
+
}), children);
|
|
27
|
+
}
|
|
28
|
+
SwiperItem.displayName = 'SwiperSlide';
|
|
29
|
+
SwiperItem.defaultProps = {
|
|
30
|
+
className: null
|
|
31
|
+
};
|
|
32
|
+
export default SwiperItem;
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import SwiperItem from '.';
|
|
4
|
+
jest.mock('react', () => ({
|
|
5
|
+
...jest.requireActual('react'),
|
|
6
|
+
useLayoutEffect: jest.requireActual('react').useEffect
|
|
7
|
+
}));
|
|
8
|
+
describe('<SwiperItem />', () => {
|
|
9
|
+
it('should not render without children', () => {
|
|
10
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(SwiperItem, null, /*#__PURE__*/React.createElement("div", null)));
|
|
11
|
+
expect(wrapper).toMatchSnapshot();
|
|
12
|
+
expect(wrapper.html()).toEqual('<div class="swiper-slide css-10a4qrv" data-test-id="Slider"><div></div></div>');
|
|
13
|
+
});
|
|
14
|
+
it('should add custom className', () => {
|
|
15
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(SwiperItem, {
|
|
16
|
+
className: "test"
|
|
17
|
+
}, /*#__PURE__*/React.createElement("div", null)));
|
|
18
|
+
expect(wrapper).toMatchSnapshot();
|
|
19
|
+
expect(wrapper.html()).toEqual('<div class="swiper-slide css-10a4qrv test" data-test-id="Slider"><div></div></div>');
|
|
20
|
+
});
|
|
21
|
+
});
|