@shopgate/pwa-common 7.30.0-alpha.6 → 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,51 +1,227 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { Component } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* A component that takes care of rendering and validation of input fields.
|
|
3
8
|
* This component has no styling and should not be used directly.
|
|
4
9
|
* You may want to use an appropriate form field component from the template instead.
|
|
5
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
class SimpleInput extends Component {
|
|
12
|
+
/**
|
|
6
13
|
* Creates a new input component.
|
|
7
14
|
* @param {Object} props The component properties.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
*/
|
|
16
|
+
constructor(props) {
|
|
17
|
+
super(props);
|
|
18
|
+
/**
|
|
19
|
+
* Internal focus event handler.
|
|
20
|
+
* @param {Object} e The event object.
|
|
21
|
+
*/
|
|
22
|
+
this.handleFocus = e => {
|
|
23
|
+
this.setState({
|
|
24
|
+
isFocused: true
|
|
25
|
+
});
|
|
26
|
+
this.props.onFocusChange(true, e);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Internal blur event handler.
|
|
30
|
+
* @param {Object} e The event object.
|
|
31
|
+
*/
|
|
32
|
+
this.handleBlur = e => {
|
|
33
|
+
const newState = {
|
|
34
|
+
isFocused: false
|
|
35
|
+
};
|
|
36
|
+
if (this.props.validateOnBlur) {
|
|
37
|
+
// Validate the value.
|
|
38
|
+
newState.isValid = this.props.onValidate(this.value, false);
|
|
39
|
+
}
|
|
40
|
+
this.setState(newState);
|
|
41
|
+
this.props.onFocusChange(false, e);
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Internal change event handler.
|
|
45
|
+
* @param {Object} event The event object.
|
|
46
|
+
*/
|
|
47
|
+
this.handleChange = event => {
|
|
48
|
+
const {
|
|
49
|
+
value
|
|
50
|
+
} = this.state;
|
|
51
|
+
const {
|
|
52
|
+
type
|
|
53
|
+
} = this.props;
|
|
54
|
+
|
|
55
|
+
// Special handling to prevent invalid characters within number inputs on Firefox / Safari
|
|
56
|
+
if (type === 'number' && event?.target?.validity?.badInput) {
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
event.stopPropagation();
|
|
59
|
+
this.ref.value = value;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Sanitize the input value.
|
|
64
|
+
const sanitizedValue = this.props.onSanitize(event.target.value || '');
|
|
65
|
+
|
|
66
|
+
// Update the state.
|
|
67
|
+
this.updateValue(sanitizedValue, !this.props.isControlled);
|
|
68
|
+
|
|
69
|
+
// Emit an event.
|
|
70
|
+
this.props.onChange(sanitizedValue, event);
|
|
71
|
+
};
|
|
72
|
+
this.ref = null;
|
|
73
|
+
// Initially sanitize the value.
|
|
74
|
+
const _sanitizedValue = this.props.onSanitize(this.props.value || '');
|
|
75
|
+
this.state = {
|
|
76
|
+
value: _sanitizedValue,
|
|
77
|
+
isValid: this.props.onValidate(_sanitizedValue, true),
|
|
78
|
+
isFocused: false
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
24
83
|
* Initially trigger onChange() to set the initial value.
|
|
25
|
-
*/
|
|
84
|
+
*/
|
|
85
|
+
componentDidMount() {
|
|
86
|
+
const sanitizedValue = this.props.onSanitize(this.props.value || '');
|
|
87
|
+
this.props.onChange(sanitizedValue);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
26
91
|
* Updates the value of the input field if the props has been modified.
|
|
27
92
|
* @param {Object} nextProps The new properties.
|
|
28
|
-
*/
|
|
93
|
+
*/
|
|
94
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
95
|
+
/**
|
|
29
96
|
* Only set the state value if the value prop has been changed,
|
|
30
97
|
* otherwise use the current input state.
|
|
31
|
-
*/
|
|
98
|
+
*/
|
|
99
|
+
const sanitizedValue = this.props.onSanitize(nextProps.value || '');
|
|
100
|
+
if (sanitizedValue !== this.state.value) {
|
|
101
|
+
this.updateValue(sanitizedValue, true);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
32
106
|
* @returns {boolean} Whether the current value of the input field is valid.
|
|
33
|
-
*/
|
|
107
|
+
*/
|
|
108
|
+
get isValid() {
|
|
109
|
+
return this.state.isValid;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
34
113
|
* @return {boolean} Whether the input field is focused.
|
|
35
|
-
*/
|
|
114
|
+
*/
|
|
115
|
+
get isFocused() {
|
|
116
|
+
return this.state.isFocused;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
36
120
|
* @returns {string} The current value of the input field.
|
|
37
|
-
*/
|
|
121
|
+
*/
|
|
122
|
+
get value() {
|
|
123
|
+
return this.state.value;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
38
126
|
* Handles reference passing to callback and assignation.
|
|
39
127
|
* @param {HTMLElement} ref The element
|
|
40
|
-
*/
|
|
128
|
+
*/
|
|
129
|
+
handleRef(ref) {
|
|
130
|
+
this.ref = ref;
|
|
131
|
+
this.props.setRef(ref);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
41
135
|
* Updates and validates the internal state value of the input field.
|
|
42
136
|
* @param {string} newValue The new value.
|
|
43
137
|
* @param {boolean} setOwnState Specifies whether or not to update the internal state.
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
|
|
138
|
+
*/
|
|
139
|
+
updateValue(newValue, setOwnState) {
|
|
140
|
+
const newState = {
|
|
141
|
+
value: newValue
|
|
142
|
+
};
|
|
143
|
+
if (!this.props.validateOnBlur) {
|
|
144
|
+
// Validate while typing.
|
|
145
|
+
newState.isValid = this.props.onValidate(newValue, false);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Uncontrolled when setOwnState is true
|
|
149
|
+
if (setOwnState) {
|
|
150
|
+
this.setState(newState);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
47
155
|
* Renders the component.
|
|
48
156
|
* @returns {JSX.Element}
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
|
|
157
|
+
*/
|
|
158
|
+
render() {
|
|
159
|
+
const {
|
|
160
|
+
attributes,
|
|
161
|
+
className,
|
|
162
|
+
disabled,
|
|
163
|
+
id,
|
|
164
|
+
name,
|
|
165
|
+
password,
|
|
166
|
+
onKeyPress,
|
|
167
|
+
maxLength,
|
|
168
|
+
required
|
|
169
|
+
} = this.props;
|
|
170
|
+
const type = password ? 'password' : this.props.type;
|
|
171
|
+
const {
|
|
172
|
+
value
|
|
173
|
+
} = this.state;
|
|
174
|
+
const autoComplete = this.props.autoComplete ? 'on' : 'off';
|
|
175
|
+
const autoCorrect = this.props.autoCorrect ? 'on' : 'off';
|
|
176
|
+
const InputComponent = this.props.inputComponent;
|
|
177
|
+
return /*#__PURE__*/React.createElement(InputComponent, _extends({
|
|
178
|
+
id: id,
|
|
179
|
+
name: name,
|
|
180
|
+
ref: ref => this.handleRef(ref),
|
|
181
|
+
className: classNames(className, 'simpleInput', 'common__simple-input'),
|
|
182
|
+
type: type,
|
|
183
|
+
inputMode: type === 'number' ? 'decimal' : null,
|
|
184
|
+
pattern: type === 'number' ? '[0-9]*' : null,
|
|
185
|
+
min: type === 'number' ? 0 : null,
|
|
186
|
+
step: type === 'number' ? 'any' : null,
|
|
187
|
+
value: value,
|
|
188
|
+
onKeyPress: onKeyPress
|
|
189
|
+
// Use onInput for number fields to enable handling for invalid values
|
|
190
|
+
// (onChange might to be triggered when the input is invalid)
|
|
191
|
+
,
|
|
192
|
+
onInput: type === 'number' ? this.handleChange : null,
|
|
193
|
+
onChange: type !== 'number' ? this.handleChange : () => {},
|
|
194
|
+
onFocus: this.handleFocus,
|
|
195
|
+
onBlur: this.handleBlur,
|
|
196
|
+
disabled: disabled,
|
|
197
|
+
autoCorrect: autoCorrect,
|
|
198
|
+
autoComplete: autoComplete,
|
|
199
|
+
maxLength: maxLength,
|
|
200
|
+
required: required
|
|
201
|
+
}, attributes));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
SimpleInput.defaultProps = {
|
|
205
|
+
attributes: null,
|
|
206
|
+
autoComplete: false,
|
|
207
|
+
autoCorrect: false,
|
|
208
|
+
className: '',
|
|
209
|
+
disabled: false,
|
|
210
|
+
id: null,
|
|
211
|
+
isControlled: false,
|
|
212
|
+
maxLength: '',
|
|
213
|
+
name: null,
|
|
214
|
+
onChange: () => {},
|
|
215
|
+
onFocusChange: () => {},
|
|
216
|
+
onKeyPress: () => {},
|
|
217
|
+
onSanitize: value => value,
|
|
218
|
+
onValidate: () => true,
|
|
219
|
+
password: false,
|
|
220
|
+
required: false,
|
|
221
|
+
setRef: () => {},
|
|
222
|
+
type: 'text',
|
|
223
|
+
validateOnBlur: true,
|
|
224
|
+
value: '',
|
|
225
|
+
inputComponent: 'input'
|
|
226
|
+
};
|
|
227
|
+
export default SimpleInput;
|
|
@@ -1,8 +1,37 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import SimpleInput from "./components/SimpleInput";
|
|
4
|
+
import MultiLineInput from "./components/MultiLineInput";
|
|
5
|
+
import DateInput from "./components/DateInput";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* @returns {boolean}
|
|
3
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
const isDateSupported = () => {
|
|
11
|
+
const input = document.createElement('input');
|
|
12
|
+
const value = 'a';
|
|
13
|
+
input.setAttribute('type', 'date');
|
|
14
|
+
input.setAttribute('value', value);
|
|
15
|
+
return input.value !== value;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
4
19
|
* Input component.
|
|
5
20
|
*
|
|
6
21
|
* @param {Object} props Props
|
|
7
22
|
* @return {JSX}
|
|
8
|
-
*/
|
|
23
|
+
*/
|
|
24
|
+
const Factory = props => {
|
|
25
|
+
if (props.type === 'date' && !isDateSupported()) {
|
|
26
|
+
return /*#__PURE__*/React.createElement(DateInput, props);
|
|
27
|
+
}
|
|
28
|
+
if (props.multiLine) {
|
|
29
|
+
return /*#__PURE__*/React.createElement(MultiLineInput, props);
|
|
30
|
+
}
|
|
31
|
+
return /*#__PURE__*/React.createElement(SimpleInput, props);
|
|
32
|
+
};
|
|
33
|
+
Factory.defaultProps = {
|
|
34
|
+
multiLine: false,
|
|
35
|
+
type: null
|
|
36
|
+
};
|
|
37
|
+
export default props => Factory(props);
|
package/components/Input/spec.js
CHANGED
|
@@ -1 +1,122 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount, shallow } from 'enzyme';
|
|
3
|
+
import Input from "./index";
|
|
4
|
+
describe('<Input />', () => {
|
|
5
|
+
it('should render a simple input field', () => {
|
|
6
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, null));
|
|
7
|
+
expect(wrapper).toMatchSnapshot();
|
|
8
|
+
expect(wrapper.find('input').length).toBe(1);
|
|
9
|
+
});
|
|
10
|
+
it('should render the input as password', () => {
|
|
11
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
12
|
+
password: true
|
|
13
|
+
}));
|
|
14
|
+
expect(wrapper).toMatchSnapshot();
|
|
15
|
+
expect(wrapper.find('input[type="password"]').length).toBe(1);
|
|
16
|
+
});
|
|
17
|
+
it('should render the input with a default value', () => {
|
|
18
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
19
|
+
value: "FooBar"
|
|
20
|
+
}));
|
|
21
|
+
expect(wrapper).toMatchSnapshot();
|
|
22
|
+
expect(wrapper.find('input[value="FooBar"]').length).toBe(1);
|
|
23
|
+
});
|
|
24
|
+
it('should trigger the onChange callback', () => {
|
|
25
|
+
const onChangeMock = jest.fn();
|
|
26
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
27
|
+
onChange: onChangeMock
|
|
28
|
+
}));
|
|
29
|
+
wrapper.find('input').simulate('change', {
|
|
30
|
+
target: {
|
|
31
|
+
value: 'a'
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
expect(onChangeMock).toHaveBeenCalledTimes(2);
|
|
35
|
+
expect(wrapper.find('input').props().value).toEqual('a');
|
|
36
|
+
});
|
|
37
|
+
it('should receive the correct value while typing', () => {
|
|
38
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, null));
|
|
39
|
+
const input = wrapper.find('input');
|
|
40
|
+
input.simulate('change', {
|
|
41
|
+
target: {
|
|
42
|
+
value: 'foobar'
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
expect(wrapper).toMatchSnapshot();
|
|
46
|
+
expect(wrapper.find('SimpleInput').instance().value).toBe('foobar');
|
|
47
|
+
});
|
|
48
|
+
it('should sanitize the input', () => {
|
|
49
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
50
|
+
onSanitize: value => value.toUpperCase()
|
|
51
|
+
}));
|
|
52
|
+
const input = wrapper.find('input');
|
|
53
|
+
input.simulate('change', {
|
|
54
|
+
target: {
|
|
55
|
+
value: 'foobar'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
expect(wrapper).toMatchSnapshot();
|
|
59
|
+
expect(wrapper.find('SimpleInput').instance().value).toBe('FOOBAR');
|
|
60
|
+
});
|
|
61
|
+
it('should validate the input', () => {
|
|
62
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
63
|
+
onValidate: () => false
|
|
64
|
+
}));
|
|
65
|
+
expect(wrapper).toMatchSnapshot();
|
|
66
|
+
expect(wrapper.find('SimpleInput').instance().isValid).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
it('should focus the input', () => {
|
|
69
|
+
const onFocusMock = jest.fn();
|
|
70
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
71
|
+
onFocusChange: onFocusMock
|
|
72
|
+
}));
|
|
73
|
+
const input = wrapper.find('input');
|
|
74
|
+
expect(wrapper).toMatchSnapshot();
|
|
75
|
+
expect(wrapper.find('SimpleInput').instance().isFocused).toBe(false);
|
|
76
|
+
input.simulate('focus');
|
|
77
|
+
expect(wrapper.find('SimpleInput').instance().isFocused).toBe(true);
|
|
78
|
+
input.simulate('blur');
|
|
79
|
+
expect(wrapper.find('SimpleInput').instance().isFocused).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
it('should change the value on user input', () => {
|
|
82
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
83
|
+
value: "My initial value"
|
|
84
|
+
}));
|
|
85
|
+
expect(wrapper).toMatchSnapshot();
|
|
86
|
+
expect(wrapper.find('SimpleInput').instance().value).toBe('My initial value');
|
|
87
|
+
const input = wrapper.find('input');
|
|
88
|
+
input.simulate('change', {
|
|
89
|
+
target: {
|
|
90
|
+
value: 'foobar'
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
expect(wrapper.find('SimpleInput').instance().value).toBe('foobar');
|
|
94
|
+
});
|
|
95
|
+
it('should render a multiline input with empty content and react on change', () => {
|
|
96
|
+
const multiLineValue = `dfsdsdf
|
|
97
|
+
sdfdsff
|
|
98
|
+
dsf`;
|
|
99
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Input, {
|
|
100
|
+
value: "",
|
|
101
|
+
multiLine: true
|
|
102
|
+
}));
|
|
103
|
+
expect(wrapper).toMatchSnapshot();
|
|
104
|
+
expect(wrapper.find('MultiLineInput').instance().value).toEqual('');
|
|
105
|
+
wrapper.setProps({
|
|
106
|
+
value: multiLineValue
|
|
107
|
+
});
|
|
108
|
+
expect(wrapper.find('textarea').getDOMNode().innerHTML).toEqual(multiLineValue);
|
|
109
|
+
});
|
|
110
|
+
it('should render additional html attributes', () => {
|
|
111
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Input, {
|
|
112
|
+
type: "date",
|
|
113
|
+
attributes: {
|
|
114
|
+
min: '1970-01-01',
|
|
115
|
+
max: '2010-01-01'
|
|
116
|
+
}
|
|
117
|
+
})).dive();
|
|
118
|
+
expect(wrapper).toMatchSnapshot();
|
|
119
|
+
expect(wrapper.prop('min')).toEqual('1970-01-01');
|
|
120
|
+
expect(wrapper.prop('max')).toEqual('2010-01-01');
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -1,11 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
import { PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Event from '@shopgate/pwa-core/classes/Event';
|
|
4
|
+
import { EVENT_KEYBOARD_WILL_CHANGE } from '@shopgate/pwa-core/constants/AppEvents';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Keyboard state consumer.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
|
|
8
|
+
*/
|
|
9
|
+
class KeyboardConsumer extends PureComponent {
|
|
10
|
+
constructor(...args) {
|
|
11
|
+
super(...args);
|
|
12
|
+
this.state = {
|
|
13
|
+
open: false,
|
|
14
|
+
overlap: 0,
|
|
15
|
+
duration: 0
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Stores current keyboard state.
|
|
19
|
+
*/
|
|
20
|
+
this.handleKeyboardChange = ({
|
|
21
|
+
open,
|
|
22
|
+
overlap,
|
|
23
|
+
duration
|
|
24
|
+
}) => {
|
|
25
|
+
this.setState({
|
|
26
|
+
open,
|
|
27
|
+
overlap,
|
|
28
|
+
duration
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
6
33
|
* Listen to keyboard changes as soon as the component mounts.
|
|
7
|
-
*/
|
|
34
|
+
*/
|
|
35
|
+
componentDidMount() {
|
|
36
|
+
Event.addCallback(EVENT_KEYBOARD_WILL_CHANGE, this.handleKeyboardChange);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
8
40
|
* Remove listener when component will unmount.
|
|
9
|
-
*/
|
|
41
|
+
*/
|
|
42
|
+
componentWillUnmount() {
|
|
43
|
+
Event.removeCallback(EVENT_KEYBOARD_WILL_CHANGE, this.handleKeyboardChange);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
10
46
|
* @returns {JSX}
|
|
11
|
-
*/
|
|
47
|
+
*/
|
|
48
|
+
render() {
|
|
49
|
+
return this.props.children(this.state);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export default KeyboardConsumer;
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
import{connect}from'react-redux';
|
|
1
|
+
import { connect } from 'react-redux';
|
|
2
|
+
import { historyPush, historyReplace } from "../../actions/router";
|
|
3
|
+
const mapDispatchToProps = {
|
|
4
|
+
historyPush,
|
|
5
|
+
historyReplace
|
|
6
|
+
};
|
|
7
|
+
export default connect(null, mapDispatchToProps);
|
package/components/Link/index.js
CHANGED
|
@@ -1,18 +1,103 @@
|
|
|
1
|
-
|
|
1
|
+
import "core-js/modules/es.string.replace.js";
|
|
2
|
+
import React, { Component } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { hasWebBridge } from '@shopgate/engage/core';
|
|
5
|
+
import connect from "./connector";
|
|
6
|
+
import styles from "./style";
|
|
7
|
+
|
|
8
|
+
/**
|
|
2
9
|
* Link component.
|
|
3
10
|
* @param {Object} props Props for the component.
|
|
4
11
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
*/
|
|
13
|
+
class Link extends Component {
|
|
14
|
+
constructor(...args) {
|
|
15
|
+
super(...args);
|
|
16
|
+
/**
|
|
17
|
+
* Opens the link.
|
|
18
|
+
* @param {Event} e An event object.
|
|
19
|
+
*/
|
|
20
|
+
this.handleOpenLink = e => {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
if (this.props.disabled) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const params = {
|
|
26
|
+
pathname: this.props.href,
|
|
27
|
+
state: {
|
|
28
|
+
...(this.props.state || {}),
|
|
29
|
+
...(this.props.target ? {
|
|
30
|
+
target: this.props.target
|
|
31
|
+
} : {})
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// setTimeout prevents double click while VoiceOver is active
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
if (this.props.replace) {
|
|
38
|
+
this.props.historyReplace(params);
|
|
39
|
+
} else {
|
|
40
|
+
this.props.historyPush(params);
|
|
41
|
+
}
|
|
42
|
+
}, 0);
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* key listener for screen readers
|
|
46
|
+
* @param {Object} event The event object
|
|
47
|
+
*/
|
|
48
|
+
this.handleKeyDown = event => {
|
|
49
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
50
|
+
this.handleOpenLink(event);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
13
55
|
* Renders the component.
|
|
14
56
|
* @returns {JSX.Element}
|
|
15
|
-
*/
|
|
57
|
+
*/
|
|
58
|
+
render() {
|
|
59
|
+
const {
|
|
60
|
+
tag,
|
|
61
|
+
className,
|
|
62
|
+
href,
|
|
63
|
+
children,
|
|
64
|
+
role,
|
|
65
|
+
'aria-label': ariaLabel,
|
|
66
|
+
'aria-hidden': ariaHidden,
|
|
67
|
+
tabIndex
|
|
68
|
+
} = this.props;
|
|
69
|
+
let Tag = tag;
|
|
70
|
+
if (!hasWebBridge() && tag === 'a') {
|
|
71
|
+
/**
|
|
16
72
|
* Don't use link tags on apps. Sometimes links are really opened since the preventDefault
|
|
17
73
|
* doesn't work as expected which results in white pages.
|
|
18
|
-
*/
|
|
74
|
+
*/
|
|
75
|
+
Tag = 'span';
|
|
76
|
+
}
|
|
77
|
+
return /*#__PURE__*/React.createElement(Tag, {
|
|
78
|
+
className: `${styles} ${className} common__link`,
|
|
79
|
+
onClick: this.handleOpenLink,
|
|
80
|
+
onKeyDown: this.handleKeyDown,
|
|
81
|
+
role: role,
|
|
82
|
+
"data-test-id": `link: ${href}`,
|
|
83
|
+
"aria-label": ariaLabel,
|
|
84
|
+
tabIndex: tabIndex,
|
|
85
|
+
"aria-hidden": ariaHidden,
|
|
86
|
+
href: href && Tag === 'a' ? href : null
|
|
87
|
+
}, children);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
Link.defaultProps = {
|
|
91
|
+
'aria-hidden': null,
|
|
92
|
+
'aria-label': null,
|
|
93
|
+
className: '',
|
|
94
|
+
disabled: false,
|
|
95
|
+
replace: false,
|
|
96
|
+
role: 'link',
|
|
97
|
+
tag: 'div',
|
|
98
|
+
tabIndex: null,
|
|
99
|
+
target: null,
|
|
100
|
+
state: {}
|
|
101
|
+
};
|
|
102
|
+
export const Disconnected = Link;
|
|
103
|
+
export default connect(Link);
|