@momo-kits/stepper 0.73.3-beta.5 → 0.74.2-react-native.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.
- package/NumberView.tsx +47 -0
- package/StepperButton.tsx +30 -0
- package/index.tsx +95 -0
- package/package.json +11 -9
- package/styles.ts +54 -0
- package/types.ts +135 -0
- package/Stepper.js +0 -256
- package/Stepper.web.js +0 -258
- package/index.js +0 -3
package/NumberView.tsx
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {TextInput, View} from 'react-native';
|
|
3
|
+
import {StepperValueProps} from './types';
|
|
4
|
+
import {ApplicationContext} from '@momo-kits/foundation';
|
|
5
|
+
import styles from './styles';
|
|
6
|
+
|
|
7
|
+
const NumberView: FC<StepperValueProps> = ({
|
|
8
|
+
value = 0,
|
|
9
|
+
size = 'large',
|
|
10
|
+
editable = false,
|
|
11
|
+
onValueChange,
|
|
12
|
+
disabled,
|
|
13
|
+
}) => {
|
|
14
|
+
const {theme} = useContext(ApplicationContext);
|
|
15
|
+
const sizeStyle =
|
|
16
|
+
size === 'large' ? styles.numberView : styles.numberViewSmall;
|
|
17
|
+
|
|
18
|
+
const formattedNumber = (value: number) => {
|
|
19
|
+
if (isNaN(value)) {
|
|
20
|
+
return '0';
|
|
21
|
+
} else {
|
|
22
|
+
return value.toString();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const textColor = disabled
|
|
27
|
+
? theme.colors.text.disable
|
|
28
|
+
: theme.colors.text.default;
|
|
29
|
+
|
|
30
|
+
const borderColor = disabled
|
|
31
|
+
? theme.colors.border.disable
|
|
32
|
+
: theme.colors.border.default;
|
|
33
|
+
return (
|
|
34
|
+
<View style={[sizeStyle, {borderColor}]}>
|
|
35
|
+
<TextInput
|
|
36
|
+
editable={editable}
|
|
37
|
+
style={[styles.input, {color: textColor}]}
|
|
38
|
+
value={formattedNumber(value)}
|
|
39
|
+
onChangeText={onValueChange}
|
|
40
|
+
keyboardType={'number-pad'}
|
|
41
|
+
selectionColor={theme.colors.primary}
|
|
42
|
+
/>
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default NumberView;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {TouchableOpacity} from 'react-native';
|
|
3
|
+
import styles from './styles';
|
|
4
|
+
import {StepperButtonProps} from './types';
|
|
5
|
+
import {ApplicationContext, Icon} from '@momo-kits/foundation';
|
|
6
|
+
|
|
7
|
+
const StepperButton: FC<StepperButtonProps> = ({
|
|
8
|
+
disabled = false,
|
|
9
|
+
sign = '+',
|
|
10
|
+
size = 'large',
|
|
11
|
+
onPress,
|
|
12
|
+
}) => {
|
|
13
|
+
const ICON_SIZE = 12;
|
|
14
|
+
const {theme} = useContext(ApplicationContext);
|
|
15
|
+
|
|
16
|
+
const sizeStyle = size === 'large' ? styles.button : styles.smallButton;
|
|
17
|
+
const buttonIcon =
|
|
18
|
+
sign === '-' ? '24_navigation_minus_circle' : '24_navigation_plus_circle';
|
|
19
|
+
const buttonColor = disabled
|
|
20
|
+
? theme.colors.text.disable
|
|
21
|
+
: theme.colors.primary;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<TouchableOpacity disabled={disabled} onPress={onPress} style={[sizeStyle]}>
|
|
25
|
+
<Icon size={22} color={buttonColor} source={buttonIcon} />
|
|
26
|
+
</TouchableOpacity>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default StepperButton;
|
package/index.tsx
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, {FC, useState} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import StepperButton from './StepperButton';
|
|
4
|
+
import {DisabledStatus, StepperProps} from './types';
|
|
5
|
+
import styles from './styles';
|
|
6
|
+
import NumberView from './NumberView';
|
|
7
|
+
|
|
8
|
+
const Stepper: FC<StepperProps> = ({
|
|
9
|
+
size = 'large',
|
|
10
|
+
defaultValue = 0,
|
|
11
|
+
min = 0,
|
|
12
|
+
max = 100,
|
|
13
|
+
disabled = false,
|
|
14
|
+
step = 1,
|
|
15
|
+
editable = false,
|
|
16
|
+
onValueChange,
|
|
17
|
+
}) => {
|
|
18
|
+
const [value, setValue] = useState(defaultValue);
|
|
19
|
+
|
|
20
|
+
const onPlus = () => {
|
|
21
|
+
let newValue = value + step;
|
|
22
|
+
_onValueChange(newValue.toString());
|
|
23
|
+
};
|
|
24
|
+
const onMinus = () => {
|
|
25
|
+
let newValue = value - step;
|
|
26
|
+
_onValueChange(newValue.toString());
|
|
27
|
+
};
|
|
28
|
+
const _onValueChange = (num: string) => {
|
|
29
|
+
let newValue = parseInt(num);
|
|
30
|
+
|
|
31
|
+
if (isNaN(newValue)) {
|
|
32
|
+
newValue = 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (newValue > max) {
|
|
36
|
+
newValue = max;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (newValue < min) {
|
|
40
|
+
newValue = min;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setValue(newValue);
|
|
44
|
+
onValueChange?.(newValue);
|
|
45
|
+
};
|
|
46
|
+
const getViewDisabledStatus = () => {
|
|
47
|
+
let disabledStatus: DisabledStatus;
|
|
48
|
+
|
|
49
|
+
if (Array.isArray(disabled)) {
|
|
50
|
+
disabledStatus = {
|
|
51
|
+
plus: disabled[1],
|
|
52
|
+
minus: disabled[0],
|
|
53
|
+
number: disabled[0] && disabled[1],
|
|
54
|
+
};
|
|
55
|
+
} else {
|
|
56
|
+
disabledStatus = {
|
|
57
|
+
plus: disabled,
|
|
58
|
+
minus: disabled,
|
|
59
|
+
number: disabled,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (value === min) {
|
|
64
|
+
disabledStatus.minus = true;
|
|
65
|
+
}
|
|
66
|
+
if (value === max) {
|
|
67
|
+
disabledStatus.plus = true;
|
|
68
|
+
}
|
|
69
|
+
return disabledStatus;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const viewStatus = getViewDisabledStatus();
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<View style={styles.stepper}>
|
|
76
|
+
<StepperButton
|
|
77
|
+
onPress={onMinus}
|
|
78
|
+
sign={'-'}
|
|
79
|
+
size={size}
|
|
80
|
+
disabled={viewStatus.minus}
|
|
81
|
+
/>
|
|
82
|
+
<NumberView
|
|
83
|
+
onValueChange={_onValueChange}
|
|
84
|
+
size={size}
|
|
85
|
+
value={value}
|
|
86
|
+
disabled={viewStatus.number}
|
|
87
|
+
editable={editable}
|
|
88
|
+
/>
|
|
89
|
+
<StepperButton onPress={onPlus} size={size} disabled={viewStatus.plus} />
|
|
90
|
+
</View>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export {Stepper};
|
|
95
|
+
export type {StepperProps};
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/stepper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.74.2-react-native.2",
|
|
4
4
|
"private": false,
|
|
5
|
-
"main": "index.
|
|
6
|
-
"dependencies": {},
|
|
5
|
+
"main": "index.tsx",
|
|
7
6
|
"peerDependencies": {
|
|
8
|
-
"@momo-kits/
|
|
9
|
-
"
|
|
10
|
-
"react": "
|
|
11
|
-
"
|
|
7
|
+
"@momo-kits/foundation": "latest",
|
|
8
|
+
"react": "*",
|
|
9
|
+
"react-native": "*",
|
|
10
|
+
"prop-types": "15.7.2"
|
|
12
11
|
},
|
|
13
|
-
"devDependencies": {
|
|
14
|
-
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@momo-platform/versions": "4.1.11"
|
|
14
|
+
},
|
|
15
|
+
"license": "MoMo",
|
|
16
|
+
"dependencies": {}
|
|
15
17
|
}
|
package/styles.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {StyleSheet} from 'react-native';
|
|
2
|
+
import {Colors, Radius, Spacing} from '@momo-kits/foundation';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
button: {
|
|
6
|
+
width: 36,
|
|
7
|
+
height: 36,
|
|
8
|
+
borderRadius: Radius.XL,
|
|
9
|
+
backgroundColor: Colors.black_03,
|
|
10
|
+
justifyContent: 'center',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
},
|
|
13
|
+
smallButton: {
|
|
14
|
+
width: 28,
|
|
15
|
+
height: 28,
|
|
16
|
+
borderRadius: Radius.L,
|
|
17
|
+
backgroundColor: Colors.black_03,
|
|
18
|
+
justifyContent: 'center',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
},
|
|
21
|
+
iconWrapper: {
|
|
22
|
+
width: 22,
|
|
23
|
+
height: 22,
|
|
24
|
+
borderWidth: 2,
|
|
25
|
+
borderRadius: Radius.M,
|
|
26
|
+
justifyContent: 'center',
|
|
27
|
+
alignItems: 'center',
|
|
28
|
+
},
|
|
29
|
+
stepper: {
|
|
30
|
+
flexDirection: 'row',
|
|
31
|
+
alignItems: 'center',
|
|
32
|
+
},
|
|
33
|
+
numberView: {
|
|
34
|
+
width: 32,
|
|
35
|
+
height: 28,
|
|
36
|
+
borderWidth: 1,
|
|
37
|
+
borderRadius: Radius.S,
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
marginHorizontal: Spacing.S,
|
|
41
|
+
},
|
|
42
|
+
numberViewSmall: {
|
|
43
|
+
width: 28,
|
|
44
|
+
height: 24,
|
|
45
|
+
borderWidth: 1,
|
|
46
|
+
borderRadius: Radius.S,
|
|
47
|
+
justifyContent: 'center',
|
|
48
|
+
alignItems: 'center',
|
|
49
|
+
marginHorizontal: Spacing.S,
|
|
50
|
+
},
|
|
51
|
+
input: {
|
|
52
|
+
fontSize: 12,
|
|
53
|
+
},
|
|
54
|
+
});
|
package/types.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {ViewStyle} from 'react-native';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Properties for the StepperButton component, which represents the individual
|
|
5
|
+
* increment and decrement buttons in a stepper control.
|
|
6
|
+
*/
|
|
7
|
+
export type StepperButtonProps = {
|
|
8
|
+
/**
|
|
9
|
+
* Optional. If `true`, the button is disabled and not interactive.
|
|
10
|
+
* Defaults to `false` if not provided.
|
|
11
|
+
*/
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Determines the button's function in the stepper, either increment ('+') or decrement ('-').
|
|
16
|
+
*/
|
|
17
|
+
sign?: '+' | '-';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Optional. Specifies the size of the button. If not provided, a default size is used.
|
|
21
|
+
*/
|
|
22
|
+
size?: 'large' | 'small';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A callback function that is triggered when the button is pressed.
|
|
26
|
+
*/
|
|
27
|
+
onPress: () => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Properties for the StepperValue component, which displays the current value
|
|
32
|
+
* within a stepper control and allows for direct input.
|
|
33
|
+
*/
|
|
34
|
+
export type StepperValueProps = {
|
|
35
|
+
/**
|
|
36
|
+
* The current numeric value displayed by the stepper.
|
|
37
|
+
*/
|
|
38
|
+
value: number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Optional. If `true`, the value display is disabled and not interactive.
|
|
42
|
+
* Defaults to `false` if not provided.
|
|
43
|
+
*/
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Optional. Specifies the size of the value display. If not provided, a default size is used.
|
|
48
|
+
*/
|
|
49
|
+
size?: 'large' | 'small';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Optional. If `true`, the value display is editable, and users can input values directly.
|
|
53
|
+
* Defaults to `false` if not provided.
|
|
54
|
+
*/
|
|
55
|
+
editable?: boolean;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Optional. A callback function that is triggered when the value changes, receiving the new value as a parameter.
|
|
59
|
+
*/
|
|
60
|
+
onValueChange?: (value: string) => void;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* General properties for the Stepper component, which combines the buttons and value display
|
|
65
|
+
* to provide a full feature numeric stepper control.
|
|
66
|
+
*/
|
|
67
|
+
export type StepperProps = {
|
|
68
|
+
/**
|
|
69
|
+
* The initial value when the stepper is first rendered.
|
|
70
|
+
*/
|
|
71
|
+
defaultValue: number;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Optional. The minimum allowable value for the stepper. If not provided, there is no minimum.
|
|
75
|
+
*/
|
|
76
|
+
min?: number;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Optional. The maximum allowable value for the stepper. If not provided, there is no maximum.
|
|
80
|
+
*/
|
|
81
|
+
max?: number;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Optional. Specifies whether the entire stepper control or specific parts are disabled.
|
|
85
|
+
* Can be a single boolean (to disable all) or an array of booleans (to control individual components).
|
|
86
|
+
*/
|
|
87
|
+
disabled?: boolean | boolean[];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Optional. The step increment used for each button press. Defaults to 1 if not provided.
|
|
91
|
+
*/
|
|
92
|
+
step?: number;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Optional. Specifies the size of the stepper components. If not provided, a default size is used.
|
|
96
|
+
*/
|
|
97
|
+
size?: 'large' | 'small';
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Optional. If `true`, the value display is editable, and users can input values directly.
|
|
101
|
+
* Defaults to `false` if not provided.
|
|
102
|
+
*/
|
|
103
|
+
editable?: boolean;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Optional. A callback function that is triggered when the stepper's value changes, receiving the new value as a parameter.
|
|
107
|
+
*/
|
|
108
|
+
onValueChange?: (value: number) => void;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Optional. Custom styles to apply to the Stepper component. Can be used to adjust the visual presentation or layout.
|
|
112
|
+
*/
|
|
113
|
+
style?: ViewStyle | ViewStyle[];
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Specifies the disabled state for each part of the Stepper component, allowing
|
|
118
|
+
* individual parts to be disabled as needed.
|
|
119
|
+
*/
|
|
120
|
+
export type DisabledStatus = {
|
|
121
|
+
/**
|
|
122
|
+
* If `true`, the increment (plus) button is disabled.
|
|
123
|
+
*/
|
|
124
|
+
plus: boolean;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* If `true`, the decrement (minus) button is disabled.
|
|
128
|
+
*/
|
|
129
|
+
minus: boolean;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* If `true`, the value display (number) is disabled, preventing direct input.
|
|
133
|
+
*/
|
|
134
|
+
number: boolean;
|
|
135
|
+
};
|
package/Stepper.js
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Colors,
|
|
3
|
-
Image,
|
|
4
|
-
Radius,
|
|
5
|
-
Spacing,
|
|
6
|
-
Text,
|
|
7
|
-
TouchableOpacity,
|
|
8
|
-
} from '@momo-kits/core-v2';
|
|
9
|
-
import PropTypes from 'prop-types';
|
|
10
|
-
import React, {useState} from 'react';
|
|
11
|
-
import {StyleSheet, TextInput as Input, View} from 'react-native';
|
|
12
|
-
|
|
13
|
-
const minus =
|
|
14
|
-
'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_minus_circle.png';
|
|
15
|
-
const plus =
|
|
16
|
-
'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_plus_circle.png';
|
|
17
|
-
|
|
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
|
-
tintColor,
|
|
32
|
-
} = props;
|
|
33
|
-
|
|
34
|
-
const [value, setValue] = useState(defaultValue);
|
|
35
|
-
|
|
36
|
-
const getStyle = size => {
|
|
37
|
-
switch (size) {
|
|
38
|
-
case 'medium':
|
|
39
|
-
return {
|
|
40
|
-
button: {
|
|
41
|
-
width: 28,
|
|
42
|
-
height: 28,
|
|
43
|
-
borderRadius: Radius.M + Radius.XXS,
|
|
44
|
-
},
|
|
45
|
-
icon: {
|
|
46
|
-
width: 24,
|
|
47
|
-
height: 24,
|
|
48
|
-
},
|
|
49
|
-
input: {
|
|
50
|
-
minWidth: 28,
|
|
51
|
-
minHeight: 24,
|
|
52
|
-
borderRadius: Radius.S,
|
|
53
|
-
},
|
|
54
|
-
text: {
|
|
55
|
-
fontSize: 12,
|
|
56
|
-
lineHeight: 16,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
case 'large':
|
|
60
|
-
return {
|
|
61
|
-
button: {
|
|
62
|
-
width: 36,
|
|
63
|
-
height: 36,
|
|
64
|
-
borderRadius: Radius.L + Radius.XXS,
|
|
65
|
-
},
|
|
66
|
-
icon: {
|
|
67
|
-
width: 24,
|
|
68
|
-
height: 24,
|
|
69
|
-
},
|
|
70
|
-
input: {
|
|
71
|
-
minWidth: 32,
|
|
72
|
-
minHeight: 26,
|
|
73
|
-
borderRadius: Radius.S,
|
|
74
|
-
},
|
|
75
|
-
text: {
|
|
76
|
-
fontSize: 12,
|
|
77
|
-
lineHeight: 16,
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const validateValue = value => {
|
|
84
|
-
if (value < min) value = min;
|
|
85
|
-
if (value > max) value = max;
|
|
86
|
-
return value;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const onDecrease = () => {
|
|
90
|
-
let newValue = value;
|
|
91
|
-
if (value > min) {
|
|
92
|
-
newValue = value - step;
|
|
93
|
-
}
|
|
94
|
-
if (newValue < min) newValue = min;
|
|
95
|
-
|
|
96
|
-
if (onDecreasePress && typeof onDecreasePress === 'function') {
|
|
97
|
-
onDecreasePress(newValue);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
setValue(newValue);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const onIncrease = () => {
|
|
104
|
-
let newValue = value;
|
|
105
|
-
if (value < max) {
|
|
106
|
-
newValue = value + step;
|
|
107
|
-
}
|
|
108
|
-
if (newValue > max) newValue = max;
|
|
109
|
-
|
|
110
|
-
if (onIncreasePress && typeof onIncreasePress === 'function') {
|
|
111
|
-
onIncreasePress(newValue);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
setValue(newValue);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const onPressButton = type => {
|
|
118
|
-
if (type === 'plus') {
|
|
119
|
-
onIncrease();
|
|
120
|
-
} else {
|
|
121
|
-
onDecrease();
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
const renderButton = (type, size, icon) => {
|
|
125
|
-
let disabledStatus = props.disabled;
|
|
126
|
-
if (type === 'plus' && value === max) disabledStatus = true;
|
|
127
|
-
if (type === 'minus' && value === min) disabledStatus = true;
|
|
128
|
-
|
|
129
|
-
if (onPressButton) {
|
|
130
|
-
return (
|
|
131
|
-
<TouchableOpacity
|
|
132
|
-
disabled={disabledStatus}
|
|
133
|
-
onPress={() => onPressButton(type)}
|
|
134
|
-
style={[getStyle(size)?.button, styles.button]}>
|
|
135
|
-
<Image
|
|
136
|
-
source={icon}
|
|
137
|
-
style={[
|
|
138
|
-
getStyle(size)?.icon,
|
|
139
|
-
{tintColor},
|
|
140
|
-
disabledStatus && styles.disabledButton,
|
|
141
|
-
]}
|
|
142
|
-
/>
|
|
143
|
-
</TouchableOpacity>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const onChangeText = value => {
|
|
149
|
-
let newValue = validateValue(parseInt(value)) || '0';
|
|
150
|
-
if (value.length > 1 && value[0] === 0) {
|
|
151
|
-
newValue = value.substring(1);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (onChange && typeof onChange === 'function') onChange(newValue);
|
|
155
|
-
|
|
156
|
-
setValue(newValue);
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
return (
|
|
160
|
-
<View style={style}>
|
|
161
|
-
<View style={styles.container}>
|
|
162
|
-
{renderButton('minus', size, minus)}
|
|
163
|
-
<View style={styles.inputContainer}>
|
|
164
|
-
{isInput ? (
|
|
165
|
-
<Input
|
|
166
|
-
textAlign="center"
|
|
167
|
-
keyboardType="number-pad"
|
|
168
|
-
inputMode="numeric"
|
|
169
|
-
selectionColor={Colors.pink_03}
|
|
170
|
-
style={[
|
|
171
|
-
getStyle(size)?.input,
|
|
172
|
-
styles.input,
|
|
173
|
-
disabled && styles.disabledInput,
|
|
174
|
-
{
|
|
175
|
-
fontSize: size === 'small' ? 10 : 12,
|
|
176
|
-
color: Colors.black_17,
|
|
177
|
-
},
|
|
178
|
-
]}
|
|
179
|
-
value={value.toString()}
|
|
180
|
-
onChangeText={onChangeText}
|
|
181
|
-
defaultValue={defaultValue.toString()}
|
|
182
|
-
/>
|
|
183
|
-
) : (
|
|
184
|
-
<View
|
|
185
|
-
style={[
|
|
186
|
-
getStyle(size)?.input,
|
|
187
|
-
styles.input,
|
|
188
|
-
disabled && styles.disabledInput,
|
|
189
|
-
]}>
|
|
190
|
-
<Text style={getStyle(size)?.text}>{value.toString()}</Text>
|
|
191
|
-
</View>
|
|
192
|
-
)}
|
|
193
|
-
</View>
|
|
194
|
-
{renderButton('plus', size, plus)}
|
|
195
|
-
</View>
|
|
196
|
-
</View>
|
|
197
|
-
);
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
const styles = StyleSheet.create({
|
|
201
|
-
button: {
|
|
202
|
-
backgroundColor: Colors.black_03,
|
|
203
|
-
justifyContent: 'center',
|
|
204
|
-
alignItems: 'center',
|
|
205
|
-
},
|
|
206
|
-
icon: {},
|
|
207
|
-
container: {
|
|
208
|
-
flexDirection: 'row',
|
|
209
|
-
},
|
|
210
|
-
input: {
|
|
211
|
-
borderWidth: 1,
|
|
212
|
-
borderColor: Colors.black_04,
|
|
213
|
-
marginHorizontal: Spacing.M,
|
|
214
|
-
justifyContent: 'center',
|
|
215
|
-
alignItems: 'center',
|
|
216
|
-
paddingHorizontal: Spacing.XS,
|
|
217
|
-
paddingVertical: Spacing.ZERO,
|
|
218
|
-
},
|
|
219
|
-
inputContainer: {
|
|
220
|
-
alignItems: 'center',
|
|
221
|
-
justifyContent: 'center',
|
|
222
|
-
},
|
|
223
|
-
disabledButton: {
|
|
224
|
-
tintColor: Colors.black_08,
|
|
225
|
-
},
|
|
226
|
-
disabledInput: {
|
|
227
|
-
opacity: 0.4,
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
Quantity.propTypes = {
|
|
232
|
-
size: PropTypes.oneOf(['large', 'medium']),
|
|
233
|
-
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
|
234
|
-
min: PropTypes.number,
|
|
235
|
-
max: PropTypes.number,
|
|
236
|
-
defaultValue: PropTypes.number,
|
|
237
|
-
onChange: PropTypes.func,
|
|
238
|
-
disabled: PropTypes.bool,
|
|
239
|
-
isInput: PropTypes.bool,
|
|
240
|
-
step: PropTypes.number,
|
|
241
|
-
onIncreasePress: PropTypes.func,
|
|
242
|
-
onDecreasePress: PropTypes.func,
|
|
243
|
-
tintColor: PropTypes.string,
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
Quantity.defaultProps = {
|
|
247
|
-
min: 0,
|
|
248
|
-
max: 5,
|
|
249
|
-
size: 'medium',
|
|
250
|
-
isInput: false,
|
|
251
|
-
disabled: false,
|
|
252
|
-
step: 1,
|
|
253
|
-
tintColor: Colors.pink_03,
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
export default Quantity;
|
package/Stepper.web.js
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import React, {Component, useState} from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
StyleSheet,
|
|
5
|
-
TouchableOpacity,
|
|
6
|
-
Image,
|
|
7
|
-
TextInput as Input,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
import PropTypes from 'prop-types';
|
|
10
|
-
import Text from '../../core/components/typography';
|
|
11
|
-
import Colors from '../../core-v2/colors';
|
|
12
|
-
import Radius from '../../core-v2/radius';
|
|
13
|
-
import Spacing from '../../core-v2/spacing';
|
|
14
|
-
|
|
15
|
-
const minus =
|
|
16
|
-
'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_minus_circle.png';
|
|
17
|
-
const plus =
|
|
18
|
-
'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_plus_circle.png';
|
|
19
|
-
|
|
20
|
-
const Quantity = props => {
|
|
21
|
-
const {
|
|
22
|
-
disabled,
|
|
23
|
-
min = 0,
|
|
24
|
-
max = 5,
|
|
25
|
-
defaultValue = 0,
|
|
26
|
-
size,
|
|
27
|
-
onChange,
|
|
28
|
-
onIncreasePress,
|
|
29
|
-
onDecreasePress,
|
|
30
|
-
isInput = false,
|
|
31
|
-
step = 1,
|
|
32
|
-
style,
|
|
33
|
-
tintColor,
|
|
34
|
-
} = props;
|
|
35
|
-
|
|
36
|
-
const [value, setValue] = useState(defaultValue);
|
|
37
|
-
|
|
38
|
-
const getStyle = size => {
|
|
39
|
-
switch (size) {
|
|
40
|
-
case 'medium':
|
|
41
|
-
return {
|
|
42
|
-
button: {
|
|
43
|
-
width: 28,
|
|
44
|
-
height: 28,
|
|
45
|
-
borderRadius: Radius.M + Radius.XXS,
|
|
46
|
-
},
|
|
47
|
-
icon: {
|
|
48
|
-
width: 24,
|
|
49
|
-
height: 24,
|
|
50
|
-
},
|
|
51
|
-
input: {
|
|
52
|
-
minWidth: 28,
|
|
53
|
-
minHeight: 24,
|
|
54
|
-
borderRadius: Radius.S,
|
|
55
|
-
},
|
|
56
|
-
text: {
|
|
57
|
-
fontSize: 12,
|
|
58
|
-
lineHeight: 16,
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
case 'large':
|
|
62
|
-
return {
|
|
63
|
-
button: {
|
|
64
|
-
width: 36,
|
|
65
|
-
height: 36,
|
|
66
|
-
borderRadius: Radius.L + Radius.XXS,
|
|
67
|
-
},
|
|
68
|
-
icon: {
|
|
69
|
-
width: 24,
|
|
70
|
-
height: 24,
|
|
71
|
-
},
|
|
72
|
-
input: {
|
|
73
|
-
minWidth: 32,
|
|
74
|
-
minHeight: 26,
|
|
75
|
-
borderRadius: Radius.S,
|
|
76
|
-
},
|
|
77
|
-
text: {
|
|
78
|
-
fontSize: 12,
|
|
79
|
-
lineHeight: 16,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const validateValue = value => {
|
|
86
|
-
if (value < min) value = min;
|
|
87
|
-
if (value > max) value = max;
|
|
88
|
-
return value;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const onDecrease = () => {
|
|
92
|
-
let newValue = value;
|
|
93
|
-
if (value > min) {
|
|
94
|
-
newValue = value - step;
|
|
95
|
-
}
|
|
96
|
-
if (newValue < min) newValue = min;
|
|
97
|
-
|
|
98
|
-
if (onDecreasePress && typeof onDecreasePress === 'function') {
|
|
99
|
-
onDecreasePress(newValue);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
setValue(newValue);
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const onIncrease = () => {
|
|
106
|
-
let newValue = value;
|
|
107
|
-
if (value < max) {
|
|
108
|
-
newValue = value + step;
|
|
109
|
-
}
|
|
110
|
-
if (newValue > max) newValue = max;
|
|
111
|
-
|
|
112
|
-
if (onIncreasePress && typeof onIncreasePress === 'function') {
|
|
113
|
-
onIncreasePress(newValue);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
setValue(newValue);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const onPressButton = type => {
|
|
120
|
-
if (type === 'plus') {
|
|
121
|
-
onIncrease();
|
|
122
|
-
} else {
|
|
123
|
-
onDecrease();
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
const renderButton = (type, size, icon) => {
|
|
127
|
-
let disabledStatus = props.disabled;
|
|
128
|
-
if (type === 'plus' && value === max) disabledStatus = true;
|
|
129
|
-
if (type === 'minus' && value === min) disabledStatus = true;
|
|
130
|
-
|
|
131
|
-
if (onPressButton) {
|
|
132
|
-
return (
|
|
133
|
-
<TouchableOpacity
|
|
134
|
-
disabled={disabledStatus}
|
|
135
|
-
onPress={() => onPressButton(type)}
|
|
136
|
-
style={[getStyle(size)?.button, styles.button]}>
|
|
137
|
-
<Image
|
|
138
|
-
source={icon}
|
|
139
|
-
style={[
|
|
140
|
-
getStyle(size)?.icon,
|
|
141
|
-
disabledStatus && styles.disabledButton,
|
|
142
|
-
{tintColor},
|
|
143
|
-
]}
|
|
144
|
-
/>
|
|
145
|
-
</TouchableOpacity>
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const onChangeText = value => {
|
|
151
|
-
let newValue = validateValue(parseInt(value)) || '0';
|
|
152
|
-
if (value.length > 1 && value[0] === 0) {
|
|
153
|
-
newValue = value.substring(1);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (onChange && typeof onChange === 'function') onChange(newValue);
|
|
157
|
-
|
|
158
|
-
setValue(newValue);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<View style={style}>
|
|
163
|
-
<View style={styles.container}>
|
|
164
|
-
{renderButton('minus', size, minus)}
|
|
165
|
-
<View style={styles.inputContainer}>
|
|
166
|
-
{isInput ? (
|
|
167
|
-
<Input
|
|
168
|
-
textAlign="center"
|
|
169
|
-
keyboardType="number-pad"
|
|
170
|
-
inputMode="numeric"
|
|
171
|
-
selectionColor={Colors.pink_03}
|
|
172
|
-
style={[
|
|
173
|
-
getStyle(size)?.input,
|
|
174
|
-
styles.input,
|
|
175
|
-
disabled && styles.disabledInput,
|
|
176
|
-
{
|
|
177
|
-
fontSize: size === 'small' ? 10 : 12,
|
|
178
|
-
color: Colors.black_17,
|
|
179
|
-
},
|
|
180
|
-
]}
|
|
181
|
-
value={value.toString()}
|
|
182
|
-
onChangeText={onChangeText}
|
|
183
|
-
defaultValue={defaultValue.toString()}
|
|
184
|
-
/>
|
|
185
|
-
) : (
|
|
186
|
-
<View
|
|
187
|
-
style={[
|
|
188
|
-
getStyle(size)?.input,
|
|
189
|
-
styles.input,
|
|
190
|
-
disabled && styles.disabledInput,
|
|
191
|
-
]}>
|
|
192
|
-
<Text style={getStyle(size)?.text}>{value.toString()}</Text>
|
|
193
|
-
</View>
|
|
194
|
-
)}
|
|
195
|
-
</View>
|
|
196
|
-
{renderButton('plus', size, plus)}
|
|
197
|
-
</View>
|
|
198
|
-
</View>
|
|
199
|
-
);
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
const styles = StyleSheet.create({
|
|
203
|
-
button: {
|
|
204
|
-
backgroundColor: Colors.black_03,
|
|
205
|
-
justifyContent: 'center',
|
|
206
|
-
alignItems: 'center',
|
|
207
|
-
},
|
|
208
|
-
icon: {},
|
|
209
|
-
container: {
|
|
210
|
-
flexDirection: 'row',
|
|
211
|
-
},
|
|
212
|
-
input: {
|
|
213
|
-
borderWidth: 1,
|
|
214
|
-
borderColor: Colors.black_04,
|
|
215
|
-
marginHorizontal: Spacing.M,
|
|
216
|
-
justifyContent: 'center',
|
|
217
|
-
alignItems: 'center',
|
|
218
|
-
paddingHorizontal: Spacing.XS,
|
|
219
|
-
paddingVertical: Spacing.ZERO,
|
|
220
|
-
},
|
|
221
|
-
inputContainer: {
|
|
222
|
-
alignItems: 'center',
|
|
223
|
-
justifyContent: 'center',
|
|
224
|
-
},
|
|
225
|
-
disabledButton: {
|
|
226
|
-
tintColor: Colors.black_08,
|
|
227
|
-
},
|
|
228
|
-
disabledInput: {
|
|
229
|
-
opacity: 0.4,
|
|
230
|
-
},
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
Quantity.propTypes = {
|
|
234
|
-
size: PropTypes.oneOf(['large', 'medium']),
|
|
235
|
-
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
|
236
|
-
min: PropTypes.number,
|
|
237
|
-
max: PropTypes.number,
|
|
238
|
-
defaultValue: PropTypes.number,
|
|
239
|
-
onChange: PropTypes.func,
|
|
240
|
-
disabled: PropTypes.bool,
|
|
241
|
-
isInput: PropTypes.bool,
|
|
242
|
-
step: PropTypes.number,
|
|
243
|
-
onIncreasePress: PropTypes.func,
|
|
244
|
-
onDecreasePress: PropTypes.func,
|
|
245
|
-
tintColor: PropTypes.string,
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
Quantity.defaultProps = {
|
|
249
|
-
min: 0,
|
|
250
|
-
max: 5,
|
|
251
|
-
size: 'medium',
|
|
252
|
-
isInput: false,
|
|
253
|
-
disabled: false,
|
|
254
|
-
step: 1,
|
|
255
|
-
tintColor: Colors.pink_03,
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
export default Quantity;
|
package/index.js
DELETED