@momo-kits/stepper 0.0.61-beta.19 → 0.0.61-beta.2

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.
Files changed (2) hide show
  1. package/Stepper.js +297 -205
  2. package/package.json +2 -2
package/Stepper.js CHANGED
@@ -1,264 +1,356 @@
1
- import {
2
- Colors,
3
- Image,
4
- Radius,
5
- Spacing,
6
- Text,
7
- TouchableOpacity,
8
- } from '@momo-kits/core-v2';
1
+ import React, { Component } from 'react';
2
+ import { View, StyleSheet, TextInput, Keyboard } from 'react-native';
9
3
  import PropTypes from 'prop-types';
10
- import React, { useState } from 'react';
11
- import { StyleSheet, TextInput as Input, View } from 'react-native';
4
+ import { Text, Colors, Image, TouchableOpacity } from '@momo-kits/core';
12
5
 
13
6
  const minus =
14
7
  'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_minus_circle.png';
15
8
  const plus =
16
9
  'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_plus_circle.png';
17
10
 
18
- const Quantity = (props) => {
19
- const {
20
- disabled,
21
- min = 0,
22
- max = 5,
23
- defaultValue = 0,
24
- size,
25
- onChange,
26
- onIncreasePress,
27
- onDecreasePress,
28
- isInput = false,
29
- step = 1,
30
- style,
31
- } = props;
32
-
33
- const [value, setValue] = useState(defaultValue);
11
+ const styles = StyleSheet.create({
12
+ container: {
13
+ flexDirection: 'row',
14
+ },
15
+ icon: {
16
+ height: 24,
17
+ width: 24,
18
+ resizeMode: 'contain',
19
+ tintColor: Colors.pink_03,
20
+ },
21
+ text: {
22
+ color: Colors.black_17,
23
+ },
24
+ numberBox: {
25
+ justifyContent: 'center',
26
+ alignItems: 'center',
27
+ marginHorizontal: 6,
28
+ backgroundColor: Colors.white,
29
+ },
30
+ button: {
31
+ justifyContent: 'center',
32
+ alignItems: 'center',
33
+ backgroundColor: Colors.white,
34
+ borderColor: 'transparent',
35
+ },
36
+ borderBox: {
37
+ borderColor: Colors.black_04,
38
+ borderWidth: 1,
39
+ borderRadius: 6,
40
+ },
41
+ disabledIcon: {
42
+ tintColor: Colors.black_09,
43
+ },
44
+ disabledBox: {
45
+ borderColor: Colors.black_03,
46
+ backgroundColor: Colors.black_03,
47
+ },
48
+ });
34
49
 
35
- const getStyle = (size) => {
36
- switch (size) {
37
- case 'small':
38
- return {
39
- button: {
40
- width: 20,
41
- height: 20,
42
- borderRadius: Radius.S + Radius.XXS,
43
- },
44
- icon: { width: 16, height: 16 },
45
- input: {
46
- minWidth: 20,
47
- minHeight: 16,
48
- borderRadius: Radius.S,
49
- },
50
- text: {
51
- fontSize: 10,
52
- lineHeight: 14,
53
- },
54
- };
55
- case 'medium':
56
- return {
57
- button: {
58
- width: 28,
59
- height: 28,
60
- borderRadius: Radius.M + Radius.XXS,
61
- },
62
- icon: { width: 24, height: 24 },
63
- input: {
64
- minWidth: 28,
65
- minHeight: 24,
66
- borderRadius: Radius.S,
67
- },
68
- text: {
69
- fontSize: 12,
70
- lineHeight: 16,
71
- },
72
- };
73
- case 'large':
74
- return {
75
- button: {
76
- width: 36,
77
- height: 36,
78
- borderRadius: Radius.L + Radius.XXS,
79
- },
80
- icon: { width: 24, height: 24 },
81
- input: {
82
- minWidth: 32,
83
- minHeight: 26,
84
- borderRadius: Radius.S,
85
- },
86
- text: {
87
- fontSize: 12,
88
- lineHeight: 16,
89
- },
90
- };
91
- }
50
+ const getStyle = (type) => {
51
+ const objStyle = {
52
+ large: {
53
+ size: {
54
+ ...styles.borderBox,
55
+ width: 32, // height: 26
56
+ },
57
+ icon: {
58
+ width: 24,
59
+ height: 24,
60
+ resizeMode: 'contain',
61
+ },
62
+ text: 'Title',
63
+ },
64
+ medium: {
65
+ size: {
66
+ ...styles.borderBox,
67
+ width: 28, // height: 24
68
+ },
69
+ icon: {
70
+ width: 24,
71
+ height: 24,
72
+ resizeMode: 'contain',
73
+ },
74
+ text: 'SubTitle',
75
+ },
76
+ small: {
77
+ size: {
78
+ ...styles.borderBox,
79
+ width: 20, // height: 16
80
+ },
81
+ icon: {
82
+ width: 16,
83
+ height: 16,
84
+ resizeMode: 'contain',
85
+ },
86
+ text: 'Caption',
87
+ },
92
88
  };
89
+ return objStyle[type] || objStyle.medium;
90
+ };
93
91
 
94
- const validateValue = (value) => {
95
- if (value < min) value = min;
96
- if (value > max) value = max;
97
- return value;
92
+ const getSize = (type) => {
93
+ const objStyle = {
94
+ large: {
95
+ size: {
96
+ width: 32,
97
+ height: 24, // height: 26
98
+ },
99
+ },
100
+ medium: {
101
+ size: {
102
+ width: 28,
103
+ height: 24, // height: 24
104
+ },
105
+ },
106
+ small: {
107
+ size: {
108
+ width: 20,
109
+ height: 16, // height: 16
110
+ },
111
+ },
98
112
  };
113
+ return objStyle[type] || objStyle.medium;
114
+ };
99
115
 
100
- const onDecrease = () => {
101
- let newValue = value;
102
- if (value > min) {
103
- newValue = value - step;
104
- }
105
- if (newValue < min) newValue = min;
116
+ export default class Quantity extends Component {
117
+ constructor(props) {
118
+ super(props);
119
+ this.state = {
120
+ value: props.defaultValue || props.min,
121
+ ownUpdate: false,
122
+ };
123
+ }
106
124
 
107
- if (onDecreasePress && typeof onDecreasePress === 'function')
108
- onDecreasePress(newValue);
125
+ componentDidMount() {
126
+ Keyboard.addListener(
127
+ 'keyboardDidHide',
128
+ this.checkData(
129
+ this.state.value,
130
+ 'increase',
131
+ this.props.min,
132
+ this.props.max,
133
+ ),
134
+ );
135
+ }
109
136
 
110
- setValue(newValue);
111
- };
137
+ componentWillUnmount() {
138
+ Keyboard.removeAllListeners('keyboardDidHide');
139
+ }
112
140
 
113
- const onIncrease = () => {
114
- let newValue = value;
115
- if (value < max) {
116
- newValue = value + step;
141
+ static getDerivedStateFromProps(nextProps, prevState) {
142
+ const { value = undefined } = this?.props || {};
143
+ if (prevState.ownUpdate) {
144
+ return {
145
+ ownUpdate: false,
146
+ };
117
147
  }
118
- if (newValue > max) newValue = max;
119
-
120
- if (onIncreasePress && typeof onIncreasePress === 'function')
121
- onIncreasePress(newValue);
148
+ if (nextProps.value !== value && nextProps.value !== prevState.value) {
149
+ return { value: nextProps.value };
150
+ }
151
+ return null;
152
+ }
122
153
 
123
- setValue(newValue);
154
+ onChangeValue = (value, type) => {
155
+ const { onChange } = this.props;
156
+ return (
157
+ onChange && typeof onChange === 'function' && onChange(value, type)
158
+ );
124
159
  };
125
160
 
126
- const onPressButton = (type) => {
127
- if (type === 'plus') onIncrease();
128
- else onDecrease();
161
+ getValue = (key, step) => {
162
+ const { isIncreaseValue, isDecreaseValue } = this.props;
163
+ const value = {
164
+ increase: isIncreaseValue ? parseInt(step) : 0,
165
+ decrease: isDecreaseValue ? parseInt(step) : 0,
166
+ };
167
+ return value[key];
129
168
  };
130
- const renderButton = (type, size, icon) => {
131
- let disabledStatus = props.disabled;
132
- if (type === 'plus' && value === max) disabledStatus = true;
133
- if (type === 'minus' && value === min) disabledStatus = true;
134
169
 
135
- if (onPressButton)
136
- return (
137
- <TouchableOpacity
138
- disabled={disabledStatus}
139
- onPress={() => onPressButton(type)}
140
- style={[getStyle(size).button, styles.button]}>
141
- <Image
142
- source={icon}
143
- style={[
144
- getStyle(size).icon,
145
- styles.icon,
146
- disabledStatus && styles.disabledButton,
147
- ]}
148
- />
149
- </TouchableOpacity>
150
- );
170
+ setValue = (newValue = 0, type) => {
171
+ this.setState(
172
+ {
173
+ value: newValue,
174
+ ownUpdate: true,
175
+ },
176
+ () => {
177
+ this.onChangeValue(newValue, type);
178
+ },
179
+ );
151
180
  };
152
181
 
153
- const onChangeText = (value) => {
154
- let newValue = validateValue(parseInt(value)) || '0';
155
- if (value.length > 1 && value[0] === 0) {
156
- newValue = value.substring(1);
182
+ checkData = (value, type, min, max) => () => {
183
+ if (value < min) {
184
+ this.setState({ value: min, ownUpdate: true }, () => {
185
+ this.onChangeValue(value, type);
186
+ });
187
+ } else if (value > max) {
188
+ this.setState({ value: max, ownUpdate: true }, () => {
189
+ this.onChangeValue(value, type);
190
+ });
157
191
  }
158
192
 
159
- if (onChange && typeof onChange === 'function') onChange(newValue);
160
-
161
- setValue(newValue);
193
+ console.log(value, min, max);
162
194
  };
163
195
 
164
- console.log(value);
196
+ onPress =
197
+ (isIncrease = true, step) =>
198
+ () => {
199
+ const { isChangeValue, onConditionCheck } = this.props;
200
+ const { value } = this.state;
201
+ const type = isIncrease ? 'increase' : 'decrease';
202
+ if (isChangeValue && value !== '') {
203
+ const newValue = isIncrease
204
+ ? parseInt(value) + this.getValue('increase', step)
205
+ : parseInt(value) - this.getValue('decrease', step);
206
+ if (typeof onConditionCheck === 'function') {
207
+ const passCondition = onConditionCheck(newValue, type);
208
+ if (passCondition) {
209
+ this.setValue(newValue, type);
210
+ }
211
+ } else {
212
+ this.setValue(newValue, type);
213
+ }
214
+ } else {
215
+ this.onChangeValue(value, type);
216
+ }
217
+ };
218
+
219
+ render() {
220
+ const { value } = this.state;
221
+ const {
222
+ style,
223
+ valueStyle,
224
+ size,
225
+ tintColor,
226
+ isIncreaseValue,
227
+ isSingle,
228
+ iconStyle,
229
+ isInput,
230
+ disabled,
231
+ step,
232
+ } = this.props;
233
+ const { min } = this.props || 1;
234
+ const { max } = this.props || 999;
235
+ if (isSingle && value === 0) {
236
+ return (
237
+ <View style={[styles.container, style]}>
238
+ <IconButton
239
+ tintColor={tintColor}
240
+ size={size}
241
+ disabled={value >= max || !isIncreaseValue}
242
+ onPress={this.onPress(true, step)}
243
+ icon={plus}
244
+ />
245
+ </View>
246
+ );
247
+ }
248
+ const TextComp = Text[getStyle(size).text];
165
249
 
166
- return (
167
- <View style={style}>
168
- <View style={styles.container}>
169
- {renderButton('minus', size, minus)}
170
- <View style={styles.inputContainer}>
250
+ return (
251
+ <View style={[styles.container, style]}>
252
+ <IconButton
253
+ style={iconStyle}
254
+ tintColor={tintColor}
255
+ size={size}
256
+ disabled={value === min || disabled}
257
+ onPress={this.onPress(false, step)}
258
+ icon={minus}
259
+ />
260
+ <View
261
+ style={[styles.numberBox, getStyle(size).size, valueStyle]}>
171
262
  {isInput ? (
172
- <Input
173
- textAlign="center"
174
- keyboardType="number-pad"
175
- inputMode="numeric"
176
- selectionColor={Colors.pink_03}
263
+ <TextInput
177
264
  style={[
178
- getStyle(size).input,
179
- styles.input,
180
- disabled && styles.disabledInput,
181
265
  {
182
- fontSize: size === 'small' ? 10 : 12,
183
- color: Colors.black_17,
266
+ textAlignVertical: 'center',
267
+ padding: 0,
184
268
  },
269
+ getSize(size).size,
185
270
  ]}
271
+ underlineColorAndroid="transparent"
186
272
  value={value.toString()}
187
- onChangeText={onChangeText}
188
- defaultValue={defaultValue.toString()}
273
+ textAlign="center"
274
+ maxLength={3}
275
+ keyboardType="number-pad"
276
+ editable={!disabled}
277
+ onChangeText={(text) => {
278
+ if (text[0] !== '0') {
279
+ this.setValue(text);
280
+ }
281
+ }}
282
+ onEndEditing={this.checkData(
283
+ value,
284
+ 'increase',
285
+ min,
286
+ max,
287
+ )}
189
288
  />
190
289
  ) : (
191
- <View
192
- style={[
193
- getStyle(size).input,
194
- styles.input,
195
- disabled && styles.disabledInput,
196
- ]}>
197
- <Text style={getStyle(size).text}>
198
- {value.toString()}
199
- </Text>
200
- </View>
290
+ <TextComp weight="bold" style={styles.text}>
291
+ {value.toString()}
292
+ </TextComp>
201
293
  )}
202
294
  </View>
203
- {renderButton('plus', size, plus)}
295
+ <IconButton
296
+ tintColor={tintColor}
297
+ style={iconStyle}
298
+ size={size}
299
+ disabled={value >= max || !isIncreaseValue || disabled}
300
+ onPress={this.onPress(true, step)}
301
+ icon={plus}
302
+ />
204
303
  </View>
205
- </View>
206
- );
207
- };
304
+ );
305
+ }
306
+ }
208
307
 
209
- const styles = StyleSheet.create({
210
- button: {
211
- backgroundColor: Colors.black_03,
212
- justifyContent: 'center',
213
- alignItems: 'center',
214
- },
215
- icon: {
216
- tintColor: Colors.pink_03,
217
- },
218
- container: {
219
- flexDirection: 'row',
220
- },
221
- input: {
222
- borderWidth: 1,
223
- borderColor: Colors.black_04,
224
- marginHorizontal: Spacing.M,
225
- justifyContent: 'center',
226
- alignItems: 'center',
227
- paddingHorizontal: Spacing.XS,
228
- },
229
- inputContainer: {
230
- alignItems: 'center',
231
- justifyContent: 'center',
232
- },
233
- disabledButton: {
234
- tintColor: Colors.black_08,
235
- },
236
- disabledInput: {
237
- opacity: 0.4,
238
- },
239
- });
308
+ const IconButton = ({ disabled, onPress, icon, size, tintColor, style }) => (
309
+ <TouchableOpacity
310
+ style={[getStyle(size).size, styles.button, style]} // disabled && styles.disabledBox
311
+ disabled={disabled}
312
+ onPress={onPress}>
313
+ <Image
314
+ source={icon}
315
+ style={[
316
+ getStyle(size).icon,
317
+ { tintColor },
318
+ disabled && styles.disabledIcon,
319
+ ]}
320
+ />
321
+ </TouchableOpacity>
322
+ );
240
323
 
241
324
  Quantity.propTypes = {
242
325
  size: PropTypes.oneOf(['large', 'medium', 'small']),
243
326
  style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
327
+ valueStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
244
328
  min: PropTypes.number,
245
329
  max: PropTypes.number,
330
+ value: PropTypes.number,
246
331
  defaultValue: PropTypes.number,
247
332
  onChange: PropTypes.func,
333
+ isChangeValue: PropTypes.bool,
334
+ isIncreaseValue: PropTypes.bool,
335
+ isDecreaseValue: PropTypes.bool,
336
+ isSingle: PropTypes.bool,
248
337
  disabled: PropTypes.bool,
338
+ tintColor: PropTypes.string,
339
+ iconStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
249
340
  isInput: PropTypes.bool,
250
341
  step: PropTypes.number,
251
- onIncreasePress: PropTypes.func,
252
- onDecreasePress: PropTypes.func,
253
342
  };
254
343
 
255
344
  Quantity.defaultProps = {
256
- min: 0,
257
- max: 5,
345
+ min: 1,
346
+ max: 100,
347
+ isChangeValue: true,
348
+ isIncreaseValue: true,
349
+ isDecreaseValue: true,
350
+ isSingle: false,
258
351
  size: 'medium',
352
+ tintColor: Colors.pink_05_b,
259
353
  isInput: false,
260
354
  disabled: false,
261
355
  step: 1,
262
356
  };
263
-
264
- export default Quantity;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@momo-kits/stepper",
3
- "version": "0.0.61-beta.19",
3
+ "version": "0.0.61-beta.2",
4
4
  "private": false,
5
5
  "main": "index.js",
6
6
  "dependencies": {},
7
7
  "peerDependencies": {
8
- "@momo-kits/core-v2": ">=0.0.5-beta",
8
+ "@momo-kits/core": ">=0.0.5-beta",
9
9
  "prop-types": "^15.7.2",
10
10
  "react": "16.9.0",
11
11
  "react-native": ">=0.55"