@janiscommerce/ui-native 1.2.0 → 1.4.0
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/dist/env.json +1 -0
- package/dist/{components → src/components}/Avatar/index.js +14 -8
- package/dist/{components → src/components}/BaseButton/index.d.ts +2 -2
- package/dist/{components → src/components}/BaseButton/index.js +13 -6
- package/dist/{components → src/components}/CheckBox/index.js +16 -9
- package/dist/{components → src/components}/Icon/index.js +3 -1
- package/dist/{components → src/components}/Input/index.js +15 -8
- package/dist/{components → src/components}/Loading/index.js +7 -3
- package/dist/{components → src/components}/LoadingFullScreen/index.js +10 -4
- package/dist/{components → src/components}/ProgressBar/index.js +10 -5
- package/dist/{components → src/components}/RadioButton/index.js +9 -5
- package/dist/src/components/Select/Components/Dropdown/index.d.ts +10 -0
- package/dist/src/components/Select/Components/Dropdown/index.js +23 -0
- package/dist/src/components/Select/Components/Modal/index.d.ts +8 -0
- package/dist/src/components/Select/Components/Modal/index.js +65 -0
- package/dist/src/components/Select/Components/Options/index.d.ts +18 -0
- package/dist/{components/Select/Components/Dropdown → src/components/Select/Components/Options}/index.js +16 -14
- package/dist/src/components/Select/Components/SwitcherComponent/index.d.ts +13 -0
- package/dist/src/components/Select/Components/SwitcherComponent/index.js +8 -0
- package/dist/{components → src/components}/Select/index.d.ts +12 -2
- package/dist/src/components/Select/index.js +178 -0
- package/dist/{components → src/components}/Select/utils/index.d.ts +1 -1
- package/dist/src/components/Select/utils/index.js +7 -0
- package/dist/{components → src/components}/StatusChip/index.js +14 -7
- package/dist/{components → src/components}/Svg/index.js +8 -1
- package/dist/{components → src/components}/Text/index.js +3 -1
- package/dist/{index.d.ts → src/index.d.ts} +2 -1
- package/dist/{index.js → src/index.js} +2 -1
- package/dist/src/scale/index.d.ts +8 -0
- package/dist/src/scale/index.js +13 -0
- package/dist/{theme → src/theme}/palette.js +2 -1
- package/dist/{ts → src/ts}/interfaces/colors.d.ts +3 -2
- package/package.json +3 -3
- package/dist/components/Select/Components/Dropdown/index.d.ts +0 -13
- package/dist/components/Select/Components/Icons/Chevron/index.d.ts +0 -18
- package/dist/components/Select/Components/Icons/Chevron/index.js +0 -19
- package/dist/components/Select/Components/Icons/Delete/index.d.ts +0 -18
- package/dist/components/Select/Components/Icons/Delete/index.js +0 -19
- package/dist/components/Select/index.js +0 -148
- package/dist/components/Select/utils/index.js +0 -8
- /package/dist/{components → src/components}/Avatar/index.d.ts +0 -0
- /package/dist/{components → src/components}/Avatar/utils/formatPlaceholder/index.d.ts +0 -0
- /package/dist/{components → src/components}/Avatar/utils/formatPlaceholder/index.js +0 -0
- /package/dist/{components → src/components}/Carousel/index.d.ts +0 -0
- /package/dist/{components → src/components}/Carousel/index.js +0 -0
- /package/dist/{components → src/components}/Carousel/utils/index.d.ts +0 -0
- /package/dist/{components → src/components}/Carousel/utils/index.js +0 -0
- /package/dist/{components → src/components}/CheckBox/icon/CheckedIcon.d.ts +0 -0
- /package/dist/{components → src/components}/CheckBox/icon/CheckedIcon.js +0 -0
- /package/dist/{components → src/components}/CheckBox/index.d.ts +0 -0
- /package/dist/{components → src/components}/Icon/assets/fonts/selection.json +0 -0
- /package/dist/{components → src/components}/Icon/index.d.ts +0 -0
- /package/dist/{components → src/components}/Image/index.d.ts +0 -0
- /package/dist/{components → src/components}/Image/index.js +0 -0
- /package/dist/{components → src/components}/Input/index.d.ts +0 -0
- /package/dist/{components → src/components}/Input/utils/index.d.ts +0 -0
- /package/dist/{components → src/components}/Input/utils/index.js +0 -0
- /package/dist/{components → src/components}/List/index.d.ts +0 -0
- /package/dist/{components → src/components}/List/index.js +0 -0
- /package/dist/{components → src/components}/Loading/LoadingSvg/index.d.ts +0 -0
- /package/dist/{components → src/components}/Loading/LoadingSvg/index.js +0 -0
- /package/dist/{components → src/components}/Loading/index.d.ts +0 -0
- /package/dist/{components → src/components}/LoadingFullScreen/index.d.ts +0 -0
- /package/dist/{components → src/components}/ProgressBar/index.d.ts +0 -0
- /package/dist/{components → src/components}/ProgressBar/utils/index.d.ts +0 -0
- /package/dist/{components → src/components}/ProgressBar/utils/index.js +0 -0
- /package/dist/{components → src/components}/RadioButton/index.d.ts +0 -0
- /package/dist/{components → src/components}/StatusChip/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/EmptyIllustration/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/EmptyIllustration/index.js +0 -0
- /package/dist/{components → src/components}/Svg/svgs/EmptyListIllustration/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/EmptyListIllustration/index.js +0 -0
- /package/dist/{components → src/components}/Svg/svgs/JanisLogo/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/JanisLogo/index.js +0 -0
- /package/dist/{components → src/components}/Svg/svgs/JanisLogoColor/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/JanisLogoColor/index.js +0 -0
- /package/dist/{components → src/components}/Svg/svgs/LoginIllustration/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/LoginIllustration/index.js +0 -0
- /package/dist/{components → src/components}/Svg/svgs/NoNotifications/index.d.ts +0 -0
- /package/dist/{components → src/components}/Svg/svgs/NoNotifications/index.js +0 -0
- /package/dist/{components → src/components}/SwipeUp/childComponents/index.d.ts +0 -0
- /package/dist/{components → src/components}/SwipeUp/childComponents/index.js +0 -0
- /package/dist/{components → src/components}/SwipeUp/index.d.ts +0 -0
- /package/dist/{components → src/components}/SwipeUp/index.js +0 -0
- /package/dist/{components → src/components}/Text/index.d.ts +0 -0
- /package/dist/{theme → src/theme}/palette.d.ts +0 -0
- /package/dist/{ts → src/ts}/interfaces/colors.js +0 -0
- /package/dist/{ts → src/ts}/interfaces/svgs.d.ts +0 -0
- /package/dist/{ts → src/ts}/interfaces/svgs.js +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/* istanbul ignore file */
|
|
2
|
+
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
3
|
+
import { Keyboard, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
|
|
4
|
+
import { black, grey, primary } from '../../theme/palette';
|
|
5
|
+
import { formatPlaceholderMulti } from './utils';
|
|
6
|
+
import Options from './Components/Options';
|
|
7
|
+
import Icon from '../Icon';
|
|
8
|
+
import { horizontalScale, moderateScale, scaledForDevice } from '../../scale';
|
|
9
|
+
var KeyboardTypes;
|
|
10
|
+
(function (KeyboardTypes) {
|
|
11
|
+
KeyboardTypes["Default"] = "default";
|
|
12
|
+
KeyboardTypes["NumberPad"] = "number-pad";
|
|
13
|
+
KeyboardTypes["DecimalPad"] = "decimal-pad";
|
|
14
|
+
KeyboardTypes["Numeric"] = "numeric";
|
|
15
|
+
KeyboardTypes["EmailAddress"] = "email-address";
|
|
16
|
+
KeyboardTypes["PhonePad"] = "phone-pad";
|
|
17
|
+
KeyboardTypes["URL"] = "url";
|
|
18
|
+
})(KeyboardTypes || (KeyboardTypes = {}));
|
|
19
|
+
export var VariantOptions;
|
|
20
|
+
(function (VariantOptions) {
|
|
21
|
+
VariantOptions["Dropdown"] = "Dropdown";
|
|
22
|
+
VariantOptions["Modal"] = "Modal";
|
|
23
|
+
})(VariantOptions || (VariantOptions = {}));
|
|
24
|
+
const Select = ({ options, label, value = null, variantOptions = VariantOptions.Dropdown, placeholder = '', optionStyles = {}, inputProps = {}, isMulti = false, isDisabled = false, noOptionsMessage = 'no options', multiOptionsText = null, keyboardType = KeyboardTypes.Default, onFocus = () => { }, onSelectOption = () => { }, customOptionComponent = null, modalAcceptText = 'accept', ...props }) => {
|
|
25
|
+
const [inputValue, setInputValue] = useState('');
|
|
26
|
+
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
27
|
+
const [filteredOptions, setFilteredOptions] = useState(options);
|
|
28
|
+
const [isShowedOptions, setIsShowedOptions] = useState(false);
|
|
29
|
+
const [dropdownMeasures, setDropdownMeasures] = useState({
|
|
30
|
+
width: 0,
|
|
31
|
+
pageY: 0,
|
|
32
|
+
pageX: 0,
|
|
33
|
+
});
|
|
34
|
+
const inputRef = useRef(null);
|
|
35
|
+
const hasDefaultValue = !!value?.length && options?.some((option) => option?.label === value[0]?.label);
|
|
36
|
+
const isMoveLabel = isShowedOptions || inputValue;
|
|
37
|
+
const showDeleteIcon = isDisabled ? false : !!inputValue && !!selectedOptions?.length;
|
|
38
|
+
const isArrowRotated = isShowedOptions ? '180deg' : '0deg';
|
|
39
|
+
const filterOptions = (textValue) => {
|
|
40
|
+
if (typeof textValue !== 'string' || !textValue.length) {
|
|
41
|
+
return setFilteredOptions(options);
|
|
42
|
+
}
|
|
43
|
+
const filtered = options?.filter((option) => option.label.toLowerCase().includes(textValue.toLowerCase()));
|
|
44
|
+
return setFilteredOptions(filtered);
|
|
45
|
+
};
|
|
46
|
+
const handleChange = (textValue) => {
|
|
47
|
+
setInputValue(textValue);
|
|
48
|
+
filterOptions(textValue);
|
|
49
|
+
};
|
|
50
|
+
const handleOnFocus = () => {
|
|
51
|
+
Keyboard.dismiss();
|
|
52
|
+
setIsShowedOptions(true);
|
|
53
|
+
onFocus();
|
|
54
|
+
};
|
|
55
|
+
const setSingleOption = (option) => {
|
|
56
|
+
setIsShowedOptions(false);
|
|
57
|
+
setSelectedOptions([option]);
|
|
58
|
+
setInputValue(option.label);
|
|
59
|
+
};
|
|
60
|
+
const setMultiOptions = (option) => {
|
|
61
|
+
const optionMatcher = !!selectedOptions.find((previewOption) => previewOption.value === option.value);
|
|
62
|
+
const updateOption = optionMatcher
|
|
63
|
+
? selectedOptions.filter((previewOption) => previewOption.value !== option.value)
|
|
64
|
+
: [...selectedOptions, option];
|
|
65
|
+
setSelectedOptions(updateOption);
|
|
66
|
+
setInputValue(formatPlaceholderMulti(updateOption, multiOptionsText));
|
|
67
|
+
};
|
|
68
|
+
const handleSelectedOption = (option) => isMulti ? setMultiOptions(option) : setSingleOption(option);
|
|
69
|
+
const handleCloseDropdown = () => {
|
|
70
|
+
if (isDisabled) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
setIsShowedOptions(!isShowedOptions);
|
|
74
|
+
inputRef.current?.blur();
|
|
75
|
+
};
|
|
76
|
+
const handleResetOptions = () => {
|
|
77
|
+
setIsShowedOptions(false);
|
|
78
|
+
setInputValue('');
|
|
79
|
+
setSelectedOptions([]);
|
|
80
|
+
};
|
|
81
|
+
const memoizedSelectedOptions = useCallback(() => {
|
|
82
|
+
if (!!selectedOptions?.length && !!inputValue) {
|
|
83
|
+
onSelectOption(selectedOptions);
|
|
84
|
+
}
|
|
85
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
+
}, [selectedOptions]);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
memoizedSelectedOptions();
|
|
89
|
+
}, [selectedOptions, memoizedSelectedOptions]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (hasDefaultValue) {
|
|
92
|
+
setSelectedOptions(value);
|
|
93
|
+
setInputValue(formatPlaceholderMulti(value, multiOptionsText));
|
|
94
|
+
}
|
|
95
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
96
|
+
}, [hasDefaultValue, value]);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (inputRef.current) {
|
|
99
|
+
inputRef.current.measure((x, y, width, height, pageX, pageY) => setDropdownMeasures({ width, pageX, pageY: pageY - 15 }));
|
|
100
|
+
}
|
|
101
|
+
}, [isShowedOptions]);
|
|
102
|
+
const moveLabel = isMoveLabel ? 38 : 10;
|
|
103
|
+
const validFontSize = scaledForDevice(16, moderateScale);
|
|
104
|
+
const validMarginBottom = scaledForDevice(10, moderateScale);
|
|
105
|
+
const validMarginTop = scaledForDevice(18, moderateScale);
|
|
106
|
+
const validHeightLabel = scaledForDevice(19, moderateScale);
|
|
107
|
+
const validPadding = scaledForDevice(8, moderateScale);
|
|
108
|
+
const validBottomLabel = scaledForDevice(moveLabel, moderateScale);
|
|
109
|
+
const validHeightInput = scaledForDevice(38, moderateScale);
|
|
110
|
+
const validRight = scaledForDevice(30, horizontalScale);
|
|
111
|
+
const validBorderBottomWidth = scaledForDevice(1, moderateScale);
|
|
112
|
+
const styles = StyleSheet.create({
|
|
113
|
+
wrapper: {
|
|
114
|
+
width: '100%',
|
|
115
|
+
marginBottom: validMarginBottom,
|
|
116
|
+
position: 'relative',
|
|
117
|
+
zIndex: isShowedOptions ? 10 : 0,
|
|
118
|
+
},
|
|
119
|
+
wrapperInput: {
|
|
120
|
+
position: 'relative',
|
|
121
|
+
width: '100%',
|
|
122
|
+
marginBottom: 0,
|
|
123
|
+
marginTop: validMarginTop,
|
|
124
|
+
},
|
|
125
|
+
label: {
|
|
126
|
+
position: 'absolute',
|
|
127
|
+
color: isMoveLabel && !isDisabled ? primary.main : black.main,
|
|
128
|
+
fontSize: validFontSize,
|
|
129
|
+
lineHeight: validHeightLabel,
|
|
130
|
+
letterSpacing: 0,
|
|
131
|
+
left: 0,
|
|
132
|
+
fontWeight: isMoveLabel ? '600' : '400',
|
|
133
|
+
bottom: validBottomLabel,
|
|
134
|
+
},
|
|
135
|
+
input: {
|
|
136
|
+
width: '100%',
|
|
137
|
+
height: validHeightInput,
|
|
138
|
+
padding: 0,
|
|
139
|
+
fontSize: validFontSize,
|
|
140
|
+
lineHeight: validHeightLabel,
|
|
141
|
+
letterSpacing: 0,
|
|
142
|
+
borderBottomWidth: validBorderBottomWidth,
|
|
143
|
+
color: black.main,
|
|
144
|
+
borderBottomColor: isShowedOptions ? primary.main : grey[200],
|
|
145
|
+
},
|
|
146
|
+
arrowIcon: {
|
|
147
|
+
position: 'absolute',
|
|
148
|
+
padding: validPadding,
|
|
149
|
+
right: 0,
|
|
150
|
+
bottom: 0,
|
|
151
|
+
zIndex: 1,
|
|
152
|
+
transform: [{ rotate: isArrowRotated }],
|
|
153
|
+
},
|
|
154
|
+
deleteIcon: {
|
|
155
|
+
position: 'absolute',
|
|
156
|
+
padding: validPadding,
|
|
157
|
+
right: validRight,
|
|
158
|
+
bottom: 0,
|
|
159
|
+
zIndex: 1,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
return (<View style={styles.wrapper} {...props}>
|
|
163
|
+
<View style={styles.wrapperInput}>
|
|
164
|
+
{isMulti && showDeleteIcon && (<Pressable onPress={handleResetOptions} style={styles.deleteIcon}>
|
|
165
|
+
<Icon size={20} color={black.main} name="cross_circle_flat"/>
|
|
166
|
+
</Pressable>)}
|
|
167
|
+
<Pressable style={styles.arrowIcon} onPress={handleCloseDropdown}>
|
|
168
|
+
<Icon size={20} color={isDisabled ? black.main : primary.main} name="chevron_down"/>
|
|
169
|
+
</Pressable>
|
|
170
|
+
|
|
171
|
+
<Text style={styles.label}>{label}</Text>
|
|
172
|
+
<TextInput ref={inputRef} style={styles.input} value={inputValue} placeholder={isMoveLabel && placeholder} showSoftInputOnFocus={false} caretHidden={true} keyboardType={keyboardType} editable={!isDisabled} onFocus={handleOnFocus} onChangeText={handleChange} {...inputProps}/>
|
|
173
|
+
</View>
|
|
174
|
+
|
|
175
|
+
<Options variantOptions={variantOptions} dropdownMeasures={dropdownMeasures} setIsShowedOptions={setIsShowedOptions} isShowedOptions={isShowedOptions} filteredOptions={filteredOptions} selectedOptions={selectedOptions} noOptionsMessage={noOptionsMessage} optionStyles={optionStyles} callbackOption={handleSelectedOption} customOptionComponent={customOptionComponent} isMulti={isMulti} modalAcceptText={modalAcceptText}/>
|
|
176
|
+
</View>);
|
|
177
|
+
};
|
|
178
|
+
export default Select;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Option } from '..';
|
|
2
|
-
export declare const formatPlaceholderMulti: (options: Option[], optionsText: string) => string;
|
|
2
|
+
export declare const formatPlaceholderMulti: (options: Option[], optionsText: string | null) => string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const formatPlaceholderMulti = (options, optionsText) => {
|
|
2
|
+
if (!options.length) {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
const validOptionText = `(+${options.length - 1}${optionsText ? ` ${optionsText}` : ''})`;
|
|
6
|
+
return options.length > 1 ? `${options[0].label} ${validOptionText}` : options[0].label;
|
|
7
|
+
};
|
|
@@ -2,21 +2,28 @@ import React, { isValidElement } from 'react';
|
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import { base, grey, primary } from '../../theme/palette';
|
|
4
4
|
import Text from '../Text';
|
|
5
|
+
import { horizontalScale, moderateScale, scaledForDevice } from '../../scale';
|
|
6
|
+
const validHeight = scaledForDevice(24, moderateScale);
|
|
7
|
+
const validPadding = scaledForDevice(12, horizontalScale);
|
|
8
|
+
const validBorderRadius = scaledForDevice(12, moderateScale);
|
|
9
|
+
const validBorderWidth = scaledForDevice(1, moderateScale);
|
|
10
|
+
const validFontSize = scaledForDevice(13, moderateScale);
|
|
11
|
+
const validLineHeight = scaledForDevice(18, moderateScale);
|
|
5
12
|
const styles = ({ background }) => StyleSheet.create({
|
|
6
13
|
ViewStyles: {
|
|
7
|
-
height:
|
|
14
|
+
height: validHeight,
|
|
8
15
|
flexDirection: 'row',
|
|
9
16
|
alignItems: 'center',
|
|
10
|
-
paddingLeft:
|
|
11
|
-
paddingRight:
|
|
12
|
-
borderRadius:
|
|
17
|
+
paddingLeft: validPadding,
|
|
18
|
+
paddingRight: validPadding,
|
|
19
|
+
borderRadius: validBorderRadius,
|
|
13
20
|
backgroundColor: background ?? base.white,
|
|
14
|
-
borderWidth:
|
|
21
|
+
borderWidth: validBorderWidth,
|
|
15
22
|
borderColor: background ?? grey['300'],
|
|
16
23
|
},
|
|
17
24
|
TextStyles: {
|
|
18
|
-
fontSize:
|
|
19
|
-
lineHeight:
|
|
25
|
+
fontSize: validFontSize,
|
|
26
|
+
lineHeight: validLineHeight,
|
|
20
27
|
fontFamily: 'Roboto',
|
|
21
28
|
fontWeight: '900',
|
|
22
29
|
textAlign: 'center',
|
|
@@ -7,6 +7,7 @@ import JanisLogo from './svgs/JanisLogo';
|
|
|
7
7
|
import JanisLogoColor from './svgs/JanisLogoColor';
|
|
8
8
|
import LoginIllustration from './svgs/LoginIllustration';
|
|
9
9
|
import NoNotifications from './svgs/NoNotifications';
|
|
10
|
+
import { horizontalScale, moderateScale, scaledForDevice } from '../../scale';
|
|
10
11
|
const svgs = {
|
|
11
12
|
'empty-illustration': EmptyIllustration,
|
|
12
13
|
'empty-list-illustration': EmptyListIllustration,
|
|
@@ -20,8 +21,14 @@ const Svg = ({ name, width, height, size, ...props }) => {
|
|
|
20
21
|
return null;
|
|
21
22
|
}
|
|
22
23
|
const SvgSelected = svgs[name];
|
|
24
|
+
const selectedWidth = size ?? width;
|
|
25
|
+
const selectedHeight = size ?? height;
|
|
26
|
+
const parseSelectedWidth = selectedWidth || 0;
|
|
27
|
+
const parseSelectedHeight = selectedHeight || 0;
|
|
28
|
+
const validateWidth = scaledForDevice(parseSelectedWidth, horizontalScale);
|
|
29
|
+
const validateHeight = scaledForDevice(parseSelectedHeight, moderateScale);
|
|
23
30
|
return (<View {...props}>
|
|
24
|
-
<SvgSelected width={
|
|
31
|
+
<SvgSelected width={validateWidth} height={validateHeight} {...props}/>
|
|
25
32
|
</View>);
|
|
26
33
|
};
|
|
27
34
|
export default Svg;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { StyleSheet, Text as TextComponent, } from 'react-native';
|
|
3
|
+
import { moderateScale, scaledForDevice } from '../../scale';
|
|
3
4
|
const Text = ({ children, style, ...props }) => {
|
|
4
5
|
if (!children) {
|
|
5
6
|
return null;
|
|
6
7
|
}
|
|
8
|
+
const validFontSize = scaledForDevice(13, moderateScale);
|
|
7
9
|
const styles = StyleSheet.create({
|
|
8
10
|
TextStyles: {
|
|
9
|
-
fontSize:
|
|
11
|
+
fontSize: validFontSize,
|
|
10
12
|
fontFamily: 'Roboto',
|
|
11
13
|
},
|
|
12
14
|
});
|
|
@@ -17,4 +17,5 @@ import Carousel from './components/Carousel';
|
|
|
17
17
|
import ProgressBar from './components/ProgressBar';
|
|
18
18
|
import List from './components/List';
|
|
19
19
|
import BaseButton from './components/BaseButton';
|
|
20
|
-
|
|
20
|
+
import * as getScale from './scale';
|
|
21
|
+
export { Text, Avatar, CheckBox, Icon, Image, Loading, Svg, StatusChip, Input, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, getScale, };
|
|
@@ -17,4 +17,5 @@ import Carousel from './components/Carousel';
|
|
|
17
17
|
import ProgressBar from './components/ProgressBar';
|
|
18
18
|
import List from './components/List';
|
|
19
19
|
import BaseButton from './components/BaseButton';
|
|
20
|
-
|
|
20
|
+
import * as getScale from './scale';
|
|
21
|
+
export { Text, Avatar, CheckBox, Icon, Image, Loading, Svg, StatusChip, Input, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, getScale, };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare const isIOS: boolean;
|
|
2
|
+
declare const viewportWidth: number, viewportHeight: number;
|
|
3
|
+
declare const isSmallDevice: (minWidth?: number) => boolean;
|
|
4
|
+
declare const horizontalScale: (size: number) => number;
|
|
5
|
+
declare const verticalScale: (size: number) => number;
|
|
6
|
+
declare const moderateScale: (size: number, factor?: number) => number;
|
|
7
|
+
declare const scaledForDevice: (size: number, scaleCallback: (size: number) => number) => number;
|
|
8
|
+
export { isIOS, viewportWidth, viewportHeight, isSmallDevice, horizontalScale, verticalScale, moderateScale, scaledForDevice, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Dimensions, PixelRatio, Platform } from 'react-native';
|
|
2
|
+
import { WEB_MODE } from '../../env.json';
|
|
3
|
+
const guidelineBaseWidth = 360;
|
|
4
|
+
const guidelineBaseHeight = 720;
|
|
5
|
+
const isIOS = Platform.OS === 'ios';
|
|
6
|
+
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
|
|
7
|
+
const isSmallDevice = (minWidth = 365) => viewportWidth <= minWidth;
|
|
8
|
+
const horizontalScale = (size) => PixelRatio.roundToNearestPixel((viewportWidth / guidelineBaseWidth) * size);
|
|
9
|
+
const verticalScale = (size) => PixelRatio.roundToNearestPixel((viewportHeight / guidelineBaseHeight) * size);
|
|
10
|
+
const moderateScale = (size, factor = 1) => size + (horizontalScale(size) - size) * factor;
|
|
11
|
+
/* istanbul ignore next */
|
|
12
|
+
const scaledForDevice = (size, scaleCallback) => WEB_MODE ? size : scaleCallback(size);
|
|
13
|
+
export { isIOS, viewportWidth, viewportHeight, isSmallDevice, horizontalScale, verticalScale, moderateScale, scaledForDevice, };
|
|
@@ -6,12 +6,13 @@ const primary = {
|
|
|
6
6
|
const black = {
|
|
7
7
|
main: '#2F2F2F',
|
|
8
8
|
dark: '#050505',
|
|
9
|
+
semiTransparent: '#0000001a',
|
|
9
10
|
};
|
|
10
11
|
const white = {
|
|
11
12
|
main: '#E8EAF6',
|
|
12
13
|
dark: '#D0D3E3',
|
|
13
14
|
light: '#F4F5FB',
|
|
14
|
-
semiTransparent: '
|
|
15
|
+
semiTransparent: '#ffffffbf',
|
|
15
16
|
};
|
|
16
17
|
const grey = {
|
|
17
18
|
100: '#DDDFE2',
|
|
@@ -19,8 +19,6 @@ export interface gamaColor {
|
|
|
19
19
|
main: string;
|
|
20
20
|
dark: string;
|
|
21
21
|
}
|
|
22
|
-
export interface Black extends gamaColor {
|
|
23
|
-
}
|
|
24
22
|
export interface Success extends gamaColor {
|
|
25
23
|
}
|
|
26
24
|
export interface Error extends gamaColor {
|
|
@@ -35,3 +33,6 @@ export interface Primary extends gamaColor {
|
|
|
35
33
|
export interface White extends Primary {
|
|
36
34
|
semiTransparent: string;
|
|
37
35
|
}
|
|
36
|
+
export interface Black extends gamaColor {
|
|
37
|
+
semiTransparent: string;
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@janiscommerce/ui-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "components library for Janis app",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"storybook-server": "react-native-storybook-server",
|
|
24
24
|
"storybook-watcher": "sb-rn-watcher --config-path .ondevice",
|
|
25
25
|
"update-stories": "sb-rn-get-stories --config-path .ondevice",
|
|
26
|
-
"storybook-web": " npm run storybook-web-build && start-storybook -p 6006 --config-dir ./.storybook",
|
|
27
|
-
"storybook-web-build": "build-storybook --config-dir ./.storybook --output-dir ./.storybook_static",
|
|
26
|
+
"storybook-web": "node scripts/set-app-mode.js web && npm run storybook-web-build && start-storybook -p 6006 --config-dir ./.storybook",
|
|
27
|
+
"storybook-web-build": "node scripts/set-app-mode.js web && build-storybook --config-dir ./.storybook --output-dir ./.storybook_static",
|
|
28
28
|
"storybook-web-docs": "build-storybook --config-dir ./.storybook --output-dir ./docs"
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
2
|
-
import { CustomOptionComponent, Option } from '../..';
|
|
3
|
-
interface DropdownProps {
|
|
4
|
-
isShowedDropdown: boolean;
|
|
5
|
-
filteredOptions: Option[];
|
|
6
|
-
selectedOptions: Option[];
|
|
7
|
-
noOptionsMessage: string;
|
|
8
|
-
optionStyles?: {};
|
|
9
|
-
callbackOption: (option: Option) => void;
|
|
10
|
-
customOptionComponent?: CustomOptionComponent | null;
|
|
11
|
-
}
|
|
12
|
-
declare const Dropdown: FC<DropdownProps>;
|
|
13
|
-
export default Dropdown;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ViewStyle } from 'react-native';
|
|
3
|
-
interface IconProps {
|
|
4
|
-
color?: string;
|
|
5
|
-
size?: number;
|
|
6
|
-
iconStyles?: {};
|
|
7
|
-
style?: ViewStyle;
|
|
8
|
-
onPress?: () => void;
|
|
9
|
-
}
|
|
10
|
-
declare const Chevron: {
|
|
11
|
-
({ style, color, size, onPress, ...props }: IconProps): React.JSX.Element;
|
|
12
|
-
defaultProps: {
|
|
13
|
-
color: string;
|
|
14
|
-
size: number;
|
|
15
|
-
onPress: () => void;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
export default Chevron;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Pressable, View } from 'react-native';
|
|
3
|
-
import { primary } from '../../../../../theme/palette';
|
|
4
|
-
import Svg, { Path } from 'react-native-svg';
|
|
5
|
-
const Chevron = ({ style, color, size, onPress, ...props }) => {
|
|
6
|
-
return (<Pressable onPress={onPress} style={style} {...props}>
|
|
7
|
-
<View>
|
|
8
|
-
<Svg width={size} height={size} viewBox="0 0 16 16">
|
|
9
|
-
<Path d="M8.17432 11.1055L3 6.49316L4.33106 5L8.17627 8.42773L12.0132 5.01904L13.3413 6.51416L8.17432 11.1055Z" fill={color}/>
|
|
10
|
-
</Svg>
|
|
11
|
-
</View>
|
|
12
|
-
</Pressable>);
|
|
13
|
-
};
|
|
14
|
-
Chevron.defaultProps = {
|
|
15
|
-
color: primary.main,
|
|
16
|
-
size: 21,
|
|
17
|
-
onPress: () => { },
|
|
18
|
-
};
|
|
19
|
-
export default Chevron;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ViewStyle } from 'react-native';
|
|
3
|
-
interface IconProps {
|
|
4
|
-
color?: string;
|
|
5
|
-
size?: number;
|
|
6
|
-
iconStyles?: {};
|
|
7
|
-
style?: ViewStyle;
|
|
8
|
-
onPress?: () => void;
|
|
9
|
-
}
|
|
10
|
-
declare const Delete: {
|
|
11
|
-
({ style, color, size, onPress, ...props }: IconProps): React.JSX.Element;
|
|
12
|
-
defaultProps: {
|
|
13
|
-
color: string;
|
|
14
|
-
size: number;
|
|
15
|
-
onPress: () => void;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
export default Delete;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Pressable, View } from 'react-native';
|
|
3
|
-
import { black } from '../../../../../theme/palette';
|
|
4
|
-
import Svg, { Path } from 'react-native-svg';
|
|
5
|
-
const Delete = ({ style, color, size, onPress, ...props }) => {
|
|
6
|
-
return (<Pressable onPress={onPress} style={style} {...props}>
|
|
7
|
-
<View>
|
|
8
|
-
<Svg width={size} height={size} viewBox="0 0 16 16">
|
|
9
|
-
<Path fill-rule="evenodd" clip-rule="evenodd" d="M1 8C1 4.13403 4.13397 1 8 1C11.866 1 15 4.13403 15 8C15 11.866 11.866 15 8 15C4.13397 15 1 11.866 1 8ZM10.03 11.4441L11.4441 10.03L9.41406 8L11.4441 5.96997L10.03 4.55591L8 6.58594L5.96997 4.55591L4.55591 5.96997L6.58594 8L4.55591 10.03L5.96997 11.4441L8 9.41406L10.03 11.4441Z" fill={color}/>
|
|
10
|
-
</Svg>
|
|
11
|
-
</View>
|
|
12
|
-
</Pressable>);
|
|
13
|
-
};
|
|
14
|
-
Delete.defaultProps = {
|
|
15
|
-
color: black.main,
|
|
16
|
-
size: 21,
|
|
17
|
-
onPress: () => { },
|
|
18
|
-
};
|
|
19
|
-
export default Delete;
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
-
import { Keyboard, StyleSheet, Text, TextInput, View } from 'react-native';
|
|
3
|
-
import { black, grey, primary } from '../../theme/palette';
|
|
4
|
-
import { formatPlaceholderMulti } from './utils';
|
|
5
|
-
import ChevronIcon from './Components/Icons/Chevron';
|
|
6
|
-
import DeleteIcon from './Components/Icons/Delete';
|
|
7
|
-
import Dropdown from './Components/Dropdown';
|
|
8
|
-
var KeyboardTypes;
|
|
9
|
-
(function (KeyboardTypes) {
|
|
10
|
-
KeyboardTypes["Default"] = "default";
|
|
11
|
-
KeyboardTypes["NumberPad"] = "number-pad";
|
|
12
|
-
KeyboardTypes["DecimalPad"] = "decimal-pad";
|
|
13
|
-
KeyboardTypes["Numeric"] = "numeric";
|
|
14
|
-
KeyboardTypes["EmailAddress"] = "email-address";
|
|
15
|
-
KeyboardTypes["PhonePad"] = "phone-pad";
|
|
16
|
-
KeyboardTypes["URL"] = "url";
|
|
17
|
-
})(KeyboardTypes || (KeyboardTypes = {}));
|
|
18
|
-
const Select = ({ options, label, value = null, placeholder = '', optionStyles = {}, inputProps = {}, isSearchable = false, isMulti = false, isDisabled = false, noOptionsMessage = 'no options', multiOptionsText = '', keyboardType = KeyboardTypes.Default, onFocus = () => { }, onSelectOption = () => { }, customOptionComponent = null, ...props }) => {
|
|
19
|
-
const [inputValue, setInputValue] = useState('');
|
|
20
|
-
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
21
|
-
const [filteredOptions, setFilteredOptions] = useState(options);
|
|
22
|
-
const [isShowedDropdown, setIsShowedDropdown] = useState(false);
|
|
23
|
-
const inputRef = useRef(null);
|
|
24
|
-
const hasDefaultValue = value && options?.find((option) => option.label === value);
|
|
25
|
-
const isMoveLabel = isShowedDropdown || inputValue;
|
|
26
|
-
const showDeleteIcon = isDisabled ? false : !!inputValue && !!selectedOptions?.length;
|
|
27
|
-
const isArrowRotated = isShowedDropdown ? '180deg' : '0deg';
|
|
28
|
-
const filterOptions = (textValue) => {
|
|
29
|
-
if (typeof textValue !== 'string' || !textValue.length) {
|
|
30
|
-
return setFilteredOptions(options);
|
|
31
|
-
}
|
|
32
|
-
const filtered = options?.filter((option) => option.label.toLowerCase().includes(textValue.toLowerCase()));
|
|
33
|
-
return setFilteredOptions(filtered);
|
|
34
|
-
};
|
|
35
|
-
const handleChange = (textValue) => {
|
|
36
|
-
setInputValue(textValue);
|
|
37
|
-
filterOptions(textValue);
|
|
38
|
-
};
|
|
39
|
-
const handleOnFocus = () => {
|
|
40
|
-
if (!isSearchable || isMulti) {
|
|
41
|
-
Keyboard.dismiss();
|
|
42
|
-
}
|
|
43
|
-
onFocus();
|
|
44
|
-
setIsShowedDropdown(true);
|
|
45
|
-
};
|
|
46
|
-
const setSingleOption = (option) => {
|
|
47
|
-
setIsShowedDropdown(false);
|
|
48
|
-
setSelectedOptions([option]);
|
|
49
|
-
setInputValue(option.label);
|
|
50
|
-
};
|
|
51
|
-
const setMultiOptions = (option) => {
|
|
52
|
-
const optionMatcher = selectedOptions.some((previewOption) => previewOption === option);
|
|
53
|
-
const updateOption = optionMatcher
|
|
54
|
-
? selectedOptions.filter((previewOption) => previewOption !== option)
|
|
55
|
-
: [...selectedOptions, option];
|
|
56
|
-
setSelectedOptions(updateOption);
|
|
57
|
-
setInputValue(formatPlaceholderMulti(updateOption, multiOptionsText));
|
|
58
|
-
};
|
|
59
|
-
const handleSelectedOption = (option) => isMulti ? setMultiOptions(option) : setSingleOption(option);
|
|
60
|
-
const handleCloseDropdown = () => {
|
|
61
|
-
if (isDisabled) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
setIsShowedDropdown(!isShowedDropdown);
|
|
65
|
-
inputRef.current?.blur();
|
|
66
|
-
};
|
|
67
|
-
const handleResetOptions = () => {
|
|
68
|
-
setIsShowedDropdown(false);
|
|
69
|
-
setInputValue('');
|
|
70
|
-
setSelectedOptions([]);
|
|
71
|
-
};
|
|
72
|
-
const memoizedSelectedOptions = useCallback(() => {
|
|
73
|
-
if (!!selectedOptions?.length && !!inputValue) {
|
|
74
|
-
onSelectOption(selectedOptions);
|
|
75
|
-
}
|
|
76
|
-
}, [inputValue, onSelectOption, selectedOptions]);
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
memoizedSelectedOptions();
|
|
79
|
-
}, [selectedOptions, inputValue, memoizedSelectedOptions]);
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
if (hasDefaultValue) {
|
|
82
|
-
setSelectedOptions([hasDefaultValue]);
|
|
83
|
-
setInputValue(value);
|
|
84
|
-
}
|
|
85
|
-
}, [hasDefaultValue, value]);
|
|
86
|
-
const styles = StyleSheet.create({
|
|
87
|
-
wrapper: {
|
|
88
|
-
width: '100%',
|
|
89
|
-
marginBottom: 10,
|
|
90
|
-
position: 'relative',
|
|
91
|
-
zIndex: isShowedDropdown ? 10 : 0,
|
|
92
|
-
},
|
|
93
|
-
wrapperInput: {
|
|
94
|
-
position: 'relative',
|
|
95
|
-
width: '100%',
|
|
96
|
-
marginBottom: 0,
|
|
97
|
-
marginTop: 18,
|
|
98
|
-
},
|
|
99
|
-
label: {
|
|
100
|
-
position: 'absolute',
|
|
101
|
-
color: isMoveLabel && !isDisabled ? primary.main : black.main,
|
|
102
|
-
fontSize: 16,
|
|
103
|
-
lineHeight: 19,
|
|
104
|
-
letterSpacing: 0,
|
|
105
|
-
left: 0,
|
|
106
|
-
fontWeight: isMoveLabel ? '600' : '400',
|
|
107
|
-
bottom: isMoveLabel ? 38 : 10,
|
|
108
|
-
},
|
|
109
|
-
input: {
|
|
110
|
-
width: '100%',
|
|
111
|
-
height: 38,
|
|
112
|
-
padding: 0,
|
|
113
|
-
fontSize: 16,
|
|
114
|
-
lineHeight: 19,
|
|
115
|
-
letterSpacing: 0,
|
|
116
|
-
borderBottomWidth: 1,
|
|
117
|
-
color: black.main,
|
|
118
|
-
borderBottomColor: isShowedDropdown ? primary.main : grey[200],
|
|
119
|
-
},
|
|
120
|
-
arrowIcon: {
|
|
121
|
-
position: 'absolute',
|
|
122
|
-
padding: 8,
|
|
123
|
-
right: 0,
|
|
124
|
-
bottom: 0,
|
|
125
|
-
zIndex: 1,
|
|
126
|
-
transform: [{ rotate: isArrowRotated }],
|
|
127
|
-
},
|
|
128
|
-
deleteIcon: {
|
|
129
|
-
position: 'absolute',
|
|
130
|
-
padding: 8,
|
|
131
|
-
right: 30,
|
|
132
|
-
bottom: 0,
|
|
133
|
-
zIndex: 1,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
return (<View style={styles.wrapper}>
|
|
137
|
-
<View style={styles.wrapperInput} {...props}>
|
|
138
|
-
{showDeleteIcon && <DeleteIcon style={styles.deleteIcon} onPress={handleResetOptions}/>}
|
|
139
|
-
<ChevronIcon style={styles.arrowIcon} color={isDisabled ? black.main : primary.main} onPress={handleCloseDropdown}/>
|
|
140
|
-
|
|
141
|
-
<Text style={styles.label}>{label}</Text>
|
|
142
|
-
<TextInput ref={inputRef} style={styles.input} value={inputValue} placeholder={isMoveLabel && placeholder} showSoftInputOnFocus={!isMulti && isSearchable} caretHidden={!isSearchable} keyboardType={keyboardType} editable={!isDisabled} onFocus={handleOnFocus} onChangeText={handleChange} {...inputProps}/>
|
|
143
|
-
</View>
|
|
144
|
-
|
|
145
|
-
<Dropdown isShowedDropdown={isShowedDropdown} filteredOptions={filteredOptions} selectedOptions={selectedOptions} noOptionsMessage={noOptionsMessage} optionStyles={optionStyles} callbackOption={handleSelectedOption} customOptionComponent={customOptionComponent}/>
|
|
146
|
-
</View>);
|
|
147
|
-
};
|
|
148
|
-
export default Select;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|