@janiscommerce/ui-native 1.3.0 → 1.5.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/{src/components → components}/BaseButton/index.d.ts +2 -2
- package/dist/{src/components → components}/Input/utils/index.d.ts +3 -3
- package/dist/components/LayoutWithBottomButtons/index.d.ts +11 -0
- package/dist/components/LayoutWithBottomButtons/index.js +71 -0
- package/dist/components/LayoutWithBottomButtons/utils/index.d.ts +362 -0
- package/dist/components/LayoutWithBottomButtons/utils/index.js +135 -0
- package/dist/components/Select/Components/Dropdown/index.d.ts +10 -0
- package/dist/components/Select/Components/Dropdown/index.js +23 -0
- package/dist/components/Select/Components/Modal/index.d.ts +8 -0
- package/dist/components/Select/Components/Modal/index.js +65 -0
- package/dist/components/Select/Components/Options/index.d.ts +18 -0
- package/dist/{src/components/Select/Components/Dropdown → components/Select/Components/Options}/index.js +22 -32
- package/dist/components/Select/Components/SwitcherComponent/index.d.ts +13 -0
- package/dist/components/Select/Components/SwitcherComponent/index.js +8 -0
- package/dist/{src/components → components}/Select/index.d.ts +12 -2
- package/dist/{src/components → components}/Select/index.js +48 -30
- package/dist/{src/components → components}/Select/utils/index.d.ts +1 -1
- package/dist/components/Select/utils/index.js +7 -0
- package/dist/{src/index.d.ts → index.d.ts} +2 -1
- package/dist/{src/index.js → index.js} +2 -1
- package/dist/{src/scale → scale}/index.js +2 -2
- package/dist/{src/theme → theme}/palette.d.ts +2 -13
- package/dist/{src/ts → ts}/interfaces/colors.d.ts +17 -0
- package/package.json +1 -1
- package/dist/env.json +0 -1
- package/dist/src/components/Select/Components/Dropdown/index.d.ts +0 -13
- package/dist/src/components/Select/Components/Icons/Chevron/index.d.ts +0 -17
- package/dist/src/components/Select/Components/Icons/Chevron/index.js +0 -20
- package/dist/src/components/Select/Components/Icons/Delete/index.d.ts +0 -17
- package/dist/src/components/Select/Components/Icons/Delete/index.js +0 -20
- package/dist/src/components/Select/utils/index.js +0 -8
- /package/dist/{src/components → components}/Avatar/index.d.ts +0 -0
- /package/dist/{src/components → components}/Avatar/index.js +0 -0
- /package/dist/{src/components → components}/Avatar/utils/formatPlaceholder/index.d.ts +0 -0
- /package/dist/{src/components → components}/Avatar/utils/formatPlaceholder/index.js +0 -0
- /package/dist/{src/components → components}/BaseButton/index.js +0 -0
- /package/dist/{src/components → components}/Carousel/index.d.ts +0 -0
- /package/dist/{src/components → components}/Carousel/index.js +0 -0
- /package/dist/{src/components → components}/Carousel/utils/index.d.ts +0 -0
- /package/dist/{src/components → components}/Carousel/utils/index.js +0 -0
- /package/dist/{src/components → components}/CheckBox/icon/CheckedIcon.d.ts +0 -0
- /package/dist/{src/components → components}/CheckBox/icon/CheckedIcon.js +0 -0
- /package/dist/{src/components → components}/CheckBox/index.d.ts +0 -0
- /package/dist/{src/components → components}/CheckBox/index.js +0 -0
- /package/dist/{src/components → components}/Icon/assets/fonts/selection.json +0 -0
- /package/dist/{src/components → components}/Icon/index.d.ts +0 -0
- /package/dist/{src/components → components}/Icon/index.js +0 -0
- /package/dist/{src/components → components}/Image/index.d.ts +0 -0
- /package/dist/{src/components → components}/Image/index.js +0 -0
- /package/dist/{src/components → components}/Input/index.d.ts +0 -0
- /package/dist/{src/components → components}/Input/index.js +0 -0
- /package/dist/{src/components → components}/Input/utils/index.js +0 -0
- /package/dist/{src/components → components}/List/index.d.ts +0 -0
- /package/dist/{src/components → components}/List/index.js +0 -0
- /package/dist/{src/components → components}/Loading/LoadingSvg/index.d.ts +0 -0
- /package/dist/{src/components → components}/Loading/LoadingSvg/index.js +0 -0
- /package/dist/{src/components → components}/Loading/index.d.ts +0 -0
- /package/dist/{src/components → components}/Loading/index.js +0 -0
- /package/dist/{src/components → components}/LoadingFullScreen/index.d.ts +0 -0
- /package/dist/{src/components → components}/LoadingFullScreen/index.js +0 -0
- /package/dist/{src/components → components}/ProgressBar/index.d.ts +0 -0
- /package/dist/{src/components → components}/ProgressBar/index.js +0 -0
- /package/dist/{src/components → components}/ProgressBar/utils/index.d.ts +0 -0
- /package/dist/{src/components → components}/ProgressBar/utils/index.js +0 -0
- /package/dist/{src/components → components}/RadioButton/index.d.ts +0 -0
- /package/dist/{src/components → components}/RadioButton/index.js +0 -0
- /package/dist/{src/components → components}/StatusChip/index.d.ts +0 -0
- /package/dist/{src/components → components}/StatusChip/index.js +0 -0
- /package/dist/{src/components → components}/Svg/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/index.js +0 -0
- /package/dist/{src/components → components}/Svg/svgs/EmptyIllustration/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/svgs/EmptyIllustration/index.js +0 -0
- /package/dist/{src/components → components}/Svg/svgs/EmptyListIllustration/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/svgs/EmptyListIllustration/index.js +0 -0
- /package/dist/{src/components → components}/Svg/svgs/JanisLogo/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/svgs/JanisLogo/index.js +0 -0
- /package/dist/{src/components → components}/Svg/svgs/JanisLogoColor/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/svgs/JanisLogoColor/index.js +0 -0
- /package/dist/{src/components → components}/Svg/svgs/LoginIllustration/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/svgs/LoginIllustration/index.js +0 -0
- /package/dist/{src/components → components}/Svg/svgs/NoNotifications/index.d.ts +0 -0
- /package/dist/{src/components → components}/Svg/svgs/NoNotifications/index.js +0 -0
- /package/dist/{src/components → components}/SwipeUp/childComponents/index.d.ts +0 -0
- /package/dist/{src/components → components}/SwipeUp/childComponents/index.js +0 -0
- /package/dist/{src/components → components}/SwipeUp/index.d.ts +0 -0
- /package/dist/{src/components → components}/SwipeUp/index.js +0 -0
- /package/dist/{src/components → components}/Text/index.d.ts +0 -0
- /package/dist/{src/components → components}/Text/index.js +0 -0
- /package/dist/{src/scale → scale}/index.d.ts +0 -0
- /package/dist/{src/theme → theme}/palette.js +0 -0
- /package/dist/{src/ts → ts}/interfaces/colors.js +0 -0
- /package/dist/{src/ts → ts}/interfaces/svgs.d.ts +0 -0
- /package/dist/{src/ts → ts}/interfaces/svgs.js +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Modal as ModalComponent, StyleSheet, View } from 'react-native';
|
|
3
|
+
import { base, primary, white } from '../../../../theme/palette';
|
|
4
|
+
import BaseButton from '../../../BaseButton';
|
|
5
|
+
import { moderateScale, scaledForDevice } from '../../../../scale';
|
|
6
|
+
const Modal = ({ show, setShow, isMulti, modalAcceptText, children }) => {
|
|
7
|
+
const validBottom = scaledForDevice(20, moderateScale);
|
|
8
|
+
const validMinWidth = scaledForDevice(270, moderateScale);
|
|
9
|
+
const validPaddingTop = scaledForDevice(24, moderateScale);
|
|
10
|
+
const validPaddingBottom = scaledForDevice(12, moderateScale);
|
|
11
|
+
const validPaddingHorizontal = scaledForDevice(20, moderateScale);
|
|
12
|
+
const validLeft = scaledForDevice(8, moderateScale);
|
|
13
|
+
const validTop = scaledForDevice(4, moderateScale);
|
|
14
|
+
const validFontSize = scaledForDevice(13, moderateScale);
|
|
15
|
+
const styles = StyleSheet.create({
|
|
16
|
+
background: {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
justifyContent: 'center',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
width: '100%',
|
|
21
|
+
height: '100%',
|
|
22
|
+
backgroundColor: '#0009',
|
|
23
|
+
},
|
|
24
|
+
containerModal: {
|
|
25
|
+
justifyContent: 'space-between',
|
|
26
|
+
},
|
|
27
|
+
contentWrapper: {
|
|
28
|
+
bottom: validBottom,
|
|
29
|
+
minWidth: validMinWidth,
|
|
30
|
+
paddingTop: validPaddingTop,
|
|
31
|
+
paddingBottom: validPaddingBottom,
|
|
32
|
+
paddingLeft: validPaddingHorizontal,
|
|
33
|
+
paddingRight: validPaddingHorizontal,
|
|
34
|
+
backgroundColor: base.white,
|
|
35
|
+
elevation: 5,
|
|
36
|
+
},
|
|
37
|
+
buttonWrapper: {
|
|
38
|
+
flexDirection: 'row',
|
|
39
|
+
justifyContent: 'flex-end',
|
|
40
|
+
flexWrap: 'wrap',
|
|
41
|
+
left: validLeft,
|
|
42
|
+
top: validTop,
|
|
43
|
+
},
|
|
44
|
+
button: {
|
|
45
|
+
backgroundColor: base.white,
|
|
46
|
+
},
|
|
47
|
+
buttonText: {
|
|
48
|
+
color: primary.main,
|
|
49
|
+
fontSize: validFontSize,
|
|
50
|
+
fontWeight: '700',
|
|
51
|
+
textTransform: 'uppercase',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
return (<ModalComponent animationType="fade" transparent visible={show}>
|
|
55
|
+
<View style={styles.background}>
|
|
56
|
+
<View style={styles.contentWrapper}>
|
|
57
|
+
<View style={styles.containerModal}>{children}</View>
|
|
58
|
+
{isMulti && (<View style={styles.buttonWrapper}>
|
|
59
|
+
<BaseButton title={modalAcceptText} iconRight={false} pressedColor={white.main} style={styles.button} textStyle={styles.buttonText} onPress={() => setShow(false)}/>
|
|
60
|
+
</View>)}
|
|
61
|
+
</View>
|
|
62
|
+
</View>
|
|
63
|
+
</ModalComponent>);
|
|
64
|
+
};
|
|
65
|
+
export default Modal;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { CustomOptionComponent, DropdownMeasures, Option, VariantOptions } from '../..';
|
|
3
|
+
interface OptionsProps {
|
|
4
|
+
variantOptions: VariantOptions;
|
|
5
|
+
dropdownMeasures: DropdownMeasures;
|
|
6
|
+
isShowedOptions: boolean;
|
|
7
|
+
setIsShowedOptions: (isShowed: boolean) => void;
|
|
8
|
+
filteredOptions: Option[];
|
|
9
|
+
selectedOptions: Option[];
|
|
10
|
+
noOptionsMessage: string;
|
|
11
|
+
optionStyles?: {};
|
|
12
|
+
callbackOption: (option: Option) => void;
|
|
13
|
+
customOptionComponent?: CustomOptionComponent | null;
|
|
14
|
+
isMulti: boolean;
|
|
15
|
+
modalAcceptText: string;
|
|
16
|
+
}
|
|
17
|
+
declare const Options: FC<OptionsProps>;
|
|
18
|
+
export default Options;
|
|
@@ -1,57 +1,45 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, StyleSheet, TouchableOpacity, ScrollView, Text } from 'react-native';
|
|
3
3
|
import { base, black, grey, primary, white } from '../../../../theme/palette';
|
|
4
|
-
import
|
|
5
|
-
const
|
|
6
|
-
const {
|
|
7
|
-
if (!isShowedDropdown) {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
4
|
+
import SwitcherComponent from '../SwitcherComponent';
|
|
5
|
+
const Options = (props) => {
|
|
6
|
+
const { variantOptions, dropdownMeasures, isShowedOptions, setIsShowedOptions, filteredOptions, callbackOption, selectedOptions, noOptionsMessage, optionStyles, customOptionComponent = null, isMulti, modalAcceptText, } = props;
|
|
10
7
|
const handleSelectedOption = (option) => callbackOption(option);
|
|
11
|
-
const
|
|
12
|
-
const validMaxHeight = scaledForDevice(168, moderateScale);
|
|
13
|
-
const validTop = scaledForDevice(60, moderateScale);
|
|
14
|
-
const validMarginBottom = scaledForDevice(20, moderateScale);
|
|
15
|
-
const validElevation = scaledForDevice(5, moderateScale);
|
|
16
|
-
const validHeight = scaledForDevice(42, moderateScale);
|
|
17
|
-
const validLeft = scaledForDevice(8, horizontalScale);
|
|
18
|
-
const validFontSize = scaledForDevice(14, moderateScale);
|
|
19
|
-
const validPaddingVertical = scaledForDevice(10, moderateScale);
|
|
8
|
+
const isModal = variantOptions === 'Modal';
|
|
20
9
|
const styles = StyleSheet.create({
|
|
21
10
|
container: {
|
|
11
|
+
position: 'relative',
|
|
22
12
|
width: '100%',
|
|
23
|
-
padding:
|
|
13
|
+
padding: !isModal ? 8 : 0,
|
|
24
14
|
},
|
|
25
15
|
optionWrapper: {
|
|
26
|
-
position: 'absolute',
|
|
27
|
-
maxHeight:
|
|
16
|
+
position: !isModal ? 'absolute' : 'relative',
|
|
17
|
+
maxHeight: 168,
|
|
18
|
+
minHeight: 'auto',
|
|
28
19
|
borderColor: grey[200],
|
|
29
20
|
backgroundColor: base.white,
|
|
30
21
|
width: '100%',
|
|
31
|
-
top:
|
|
32
|
-
marginBottom:
|
|
33
|
-
elevation:
|
|
34
|
-
zIndex: 10,
|
|
22
|
+
top: !isModal ? 60 : 0,
|
|
23
|
+
marginBottom: 20,
|
|
24
|
+
elevation: !isModal ? 5 : 0,
|
|
35
25
|
flex: 1,
|
|
36
26
|
},
|
|
37
27
|
option: {
|
|
38
28
|
width: '100%',
|
|
39
|
-
height:
|
|
29
|
+
height: 42,
|
|
40
30
|
justifyContent: 'center',
|
|
41
31
|
alignItems: 'stretch',
|
|
42
|
-
paddingLeft:
|
|
32
|
+
paddingLeft: 8,
|
|
43
33
|
},
|
|
44
34
|
optionText: {
|
|
45
|
-
fontSize: validFontSize,
|
|
46
35
|
color: black.main,
|
|
47
36
|
fontWeight: '400',
|
|
48
37
|
},
|
|
49
38
|
noOptionText: {
|
|
50
|
-
fontSize: validFontSize,
|
|
51
39
|
color: grey[500],
|
|
52
40
|
fontWeight: '400',
|
|
53
|
-
paddingLeft:
|
|
54
|
-
paddingVertical:
|
|
41
|
+
paddingLeft: 8,
|
|
42
|
+
paddingVertical: 10,
|
|
55
43
|
},
|
|
56
44
|
});
|
|
57
45
|
const renderOptions = filteredOptions?.length &&
|
|
@@ -78,8 +66,10 @@ const Dropdown = (props) => {
|
|
|
78
66
|
const noRenderOptions = (<View aria-disabled>
|
|
79
67
|
<Text style={styles.noOptionText}> {noOptionsMessage}</Text>
|
|
80
68
|
</View>);
|
|
81
|
-
return (<
|
|
82
|
-
{
|
|
83
|
-
|
|
69
|
+
return (<SwitcherComponent measures={dropdownMeasures} variant={variantOptions} show={isShowedOptions} setShow={setIsShowedOptions} isMulti={isMulti} modalAcceptText={modalAcceptText}>
|
|
70
|
+
<ScrollView style={styles.optionWrapper} contentContainerStyle={styles.container}>
|
|
71
|
+
{filteredOptions?.length ? renderOptions : noRenderOptions}
|
|
72
|
+
</ScrollView>
|
|
73
|
+
</SwitcherComponent>);
|
|
84
74
|
};
|
|
85
|
-
export default
|
|
75
|
+
export default Options;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
import { DropdownMeasures, VariantOptions } from '../..';
|
|
3
|
+
interface SwitcherProps {
|
|
4
|
+
show: boolean;
|
|
5
|
+
isMulti: boolean;
|
|
6
|
+
variant: VariantOptions;
|
|
7
|
+
measures: DropdownMeasures;
|
|
8
|
+
children: React.Component | React.ReactNode;
|
|
9
|
+
modalAcceptText: string;
|
|
10
|
+
setShow: (isShowed: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const SwitcherComponent: FC<SwitcherProps>;
|
|
13
|
+
export default SwitcherComponent;
|
|
@@ -9,6 +9,15 @@ declare enum KeyboardTypes {
|
|
|
9
9
|
PhonePad = "phone-pad",
|
|
10
10
|
URL = "url"
|
|
11
11
|
}
|
|
12
|
+
export declare enum VariantOptions {
|
|
13
|
+
Dropdown = "Dropdown",
|
|
14
|
+
Modal = "Modal"
|
|
15
|
+
}
|
|
16
|
+
export interface DropdownMeasures {
|
|
17
|
+
width: number;
|
|
18
|
+
pageY: number;
|
|
19
|
+
pageX: number;
|
|
20
|
+
}
|
|
12
21
|
export interface Option {
|
|
13
22
|
label: string;
|
|
14
23
|
value: string | number;
|
|
@@ -23,11 +32,11 @@ export type CustomOptionComponent = (props: CustomOptionComponentProps) => React
|
|
|
23
32
|
interface SelectProps {
|
|
24
33
|
options: Option[];
|
|
25
34
|
label: string;
|
|
26
|
-
value?:
|
|
35
|
+
value?: Option[];
|
|
36
|
+
variantOptions?: VariantOptions;
|
|
27
37
|
optionStyles?: {};
|
|
28
38
|
placeholder?: string;
|
|
29
39
|
inputProps?: TextInput;
|
|
30
|
-
isSearchable?: boolean;
|
|
31
40
|
isMulti?: boolean;
|
|
32
41
|
isDisabled?: boolean;
|
|
33
42
|
noOptionsMessage?: string;
|
|
@@ -36,6 +45,7 @@ interface SelectProps {
|
|
|
36
45
|
onFocus?: () => void;
|
|
37
46
|
onSelectOption?: (selectedOptions: Option[]) => void;
|
|
38
47
|
customOptionComponent?: CustomOptionComponent | null;
|
|
48
|
+
modalAcceptText?: string;
|
|
39
49
|
}
|
|
40
50
|
declare const Select: FC<SelectProps>;
|
|
41
51
|
export default Select;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/* istanbul ignore file */
|
|
2
2
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
3
|
-
import { Keyboard, StyleSheet, Text, TextInput, View } from 'react-native';
|
|
3
|
+
import { Keyboard, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
|
|
4
4
|
import { black, grey, primary } from '../../theme/palette';
|
|
5
5
|
import { formatPlaceholderMulti } from './utils';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import Dropdown from './Components/Dropdown';
|
|
6
|
+
import Options from './Components/Options';
|
|
7
|
+
import Icon from '../Icon';
|
|
9
8
|
import { horizontalScale, moderateScale, scaledForDevice } from '../../scale';
|
|
10
9
|
var KeyboardTypes;
|
|
11
10
|
(function (KeyboardTypes) {
|
|
@@ -17,16 +16,26 @@ var KeyboardTypes;
|
|
|
17
16
|
KeyboardTypes["PhonePad"] = "phone-pad";
|
|
18
17
|
KeyboardTypes["URL"] = "url";
|
|
19
18
|
})(KeyboardTypes || (KeyboardTypes = {}));
|
|
20
|
-
|
|
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 }) => {
|
|
21
25
|
const [inputValue, setInputValue] = useState('');
|
|
22
26
|
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
23
27
|
const [filteredOptions, setFilteredOptions] = useState(options);
|
|
24
|
-
const [
|
|
28
|
+
const [isShowedOptions, setIsShowedOptions] = useState(false);
|
|
29
|
+
const [dropdownMeasures, setDropdownMeasures] = useState({
|
|
30
|
+
width: 0,
|
|
31
|
+
pageY: 0,
|
|
32
|
+
pageX: 0,
|
|
33
|
+
});
|
|
25
34
|
const inputRef = useRef(null);
|
|
26
|
-
const hasDefaultValue = value && options?.
|
|
27
|
-
const isMoveLabel =
|
|
35
|
+
const hasDefaultValue = !!value?.length && options?.some((option) => option?.label === value[0]?.label);
|
|
36
|
+
const isMoveLabel = isShowedOptions || inputValue;
|
|
28
37
|
const showDeleteIcon = isDisabled ? false : !!inputValue && !!selectedOptions?.length;
|
|
29
|
-
const isArrowRotated =
|
|
38
|
+
const isArrowRotated = isShowedOptions ? '180deg' : '0deg';
|
|
30
39
|
const filterOptions = (textValue) => {
|
|
31
40
|
if (typeof textValue !== 'string' || !textValue.length) {
|
|
32
41
|
return setFilteredOptions(options);
|
|
@@ -39,21 +48,19 @@ const Select = ({ options, label, value = null, placeholder = '', optionStyles =
|
|
|
39
48
|
filterOptions(textValue);
|
|
40
49
|
};
|
|
41
50
|
const handleOnFocus = () => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
51
|
+
Keyboard.dismiss();
|
|
52
|
+
setIsShowedOptions(true);
|
|
45
53
|
onFocus();
|
|
46
|
-
setIsShowedDropdown(true);
|
|
47
54
|
};
|
|
48
55
|
const setSingleOption = (option) => {
|
|
49
|
-
|
|
56
|
+
setIsShowedOptions(false);
|
|
50
57
|
setSelectedOptions([option]);
|
|
51
58
|
setInputValue(option.label);
|
|
52
59
|
};
|
|
53
60
|
const setMultiOptions = (option) => {
|
|
54
|
-
const optionMatcher = selectedOptions.
|
|
61
|
+
const optionMatcher = !!selectedOptions.find((previewOption) => previewOption.value === option.value);
|
|
55
62
|
const updateOption = optionMatcher
|
|
56
|
-
? selectedOptions.filter((previewOption) => previewOption !== option)
|
|
63
|
+
? selectedOptions.filter((previewOption) => previewOption.value !== option.value)
|
|
57
64
|
: [...selectedOptions, option];
|
|
58
65
|
setSelectedOptions(updateOption);
|
|
59
66
|
setInputValue(formatPlaceholderMulti(updateOption, multiOptionsText));
|
|
@@ -63,11 +70,11 @@ const Select = ({ options, label, value = null, placeholder = '', optionStyles =
|
|
|
63
70
|
if (isDisabled) {
|
|
64
71
|
return null;
|
|
65
72
|
}
|
|
66
|
-
|
|
73
|
+
setIsShowedOptions(!isShowedOptions);
|
|
67
74
|
inputRef.current?.blur();
|
|
68
75
|
};
|
|
69
76
|
const handleResetOptions = () => {
|
|
70
|
-
|
|
77
|
+
setIsShowedOptions(false);
|
|
71
78
|
setInputValue('');
|
|
72
79
|
setSelectedOptions([]);
|
|
73
80
|
};
|
|
@@ -75,16 +82,23 @@ const Select = ({ options, label, value = null, placeholder = '', optionStyles =
|
|
|
75
82
|
if (!!selectedOptions?.length && !!inputValue) {
|
|
76
83
|
onSelectOption(selectedOptions);
|
|
77
84
|
}
|
|
78
|
-
|
|
85
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
+
}, [selectedOptions]);
|
|
79
87
|
useEffect(() => {
|
|
80
88
|
memoizedSelectedOptions();
|
|
81
|
-
}, [selectedOptions,
|
|
89
|
+
}, [selectedOptions, memoizedSelectedOptions]);
|
|
82
90
|
useEffect(() => {
|
|
83
91
|
if (hasDefaultValue) {
|
|
84
|
-
setSelectedOptions(
|
|
85
|
-
setInputValue(value);
|
|
92
|
+
setSelectedOptions(value);
|
|
93
|
+
setInputValue(formatPlaceholderMulti(value, multiOptionsText));
|
|
86
94
|
}
|
|
95
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
87
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]);
|
|
88
102
|
const moveLabel = isMoveLabel ? 38 : 10;
|
|
89
103
|
const validFontSize = scaledForDevice(16, moderateScale);
|
|
90
104
|
const validMarginBottom = scaledForDevice(10, moderateScale);
|
|
@@ -100,7 +114,7 @@ const Select = ({ options, label, value = null, placeholder = '', optionStyles =
|
|
|
100
114
|
width: '100%',
|
|
101
115
|
marginBottom: validMarginBottom,
|
|
102
116
|
position: 'relative',
|
|
103
|
-
zIndex:
|
|
117
|
+
zIndex: isShowedOptions ? 10 : 0,
|
|
104
118
|
},
|
|
105
119
|
wrapperInput: {
|
|
106
120
|
position: 'relative',
|
|
@@ -127,7 +141,7 @@ const Select = ({ options, label, value = null, placeholder = '', optionStyles =
|
|
|
127
141
|
letterSpacing: 0,
|
|
128
142
|
borderBottomWidth: validBorderBottomWidth,
|
|
129
143
|
color: black.main,
|
|
130
|
-
borderBottomColor:
|
|
144
|
+
borderBottomColor: isShowedOptions ? primary.main : grey[200],
|
|
131
145
|
},
|
|
132
146
|
arrowIcon: {
|
|
133
147
|
position: 'absolute',
|
|
@@ -145,16 +159,20 @@ const Select = ({ options, label, value = null, placeholder = '', optionStyles =
|
|
|
145
159
|
zIndex: 1,
|
|
146
160
|
},
|
|
147
161
|
});
|
|
148
|
-
return (<View style={styles.wrapper}>
|
|
149
|
-
<View style={styles.wrapperInput}
|
|
150
|
-
{showDeleteIcon && <
|
|
151
|
-
|
|
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>
|
|
152
170
|
|
|
153
171
|
<Text style={styles.label}>{label}</Text>
|
|
154
|
-
<TextInput ref={inputRef} style={styles.input} value={inputValue} placeholder={isMoveLabel && placeholder} showSoftInputOnFocus={
|
|
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}/>
|
|
155
173
|
</View>
|
|
156
174
|
|
|
157
|
-
<
|
|
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}/>
|
|
158
176
|
</View>);
|
|
159
177
|
};
|
|
160
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
|
+
};
|
|
@@ -17,5 +17,6 @@ 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
|
+
import LayoutWithBottomButtons from './components/LayoutWithBottomButtons';
|
|
20
21
|
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, };
|
|
22
|
+
export { Text, Avatar, CheckBox, Icon, Image, Loading, Svg, StatusChip, Input, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, getScale, LayoutWithBottomButtons, };
|
|
@@ -17,5 +17,6 @@ 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
|
+
import LayoutWithBottomButtons from './components/LayoutWithBottomButtons';
|
|
20
21
|
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, };
|
|
22
|
+
export { Text, Avatar, CheckBox, Icon, Image, Loading, Svg, StatusChip, Input, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, getScale, LayoutWithBottomButtons, };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Dimensions, PixelRatio, Platform } from 'react-native';
|
|
2
|
-
import { WEB_MODE } from '../../env.json';
|
|
3
2
|
const guidelineBaseWidth = 360;
|
|
4
3
|
const guidelineBaseHeight = 720;
|
|
5
4
|
const isIOS = Platform.OS === 'ios';
|
|
5
|
+
const isWeb = Platform.OS === 'web';
|
|
6
6
|
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
|
|
7
7
|
const isSmallDevice = (minWidth = 365) => viewportWidth <= minWidth;
|
|
8
8
|
const horizontalScale = (size) => PixelRatio.roundToNearestPixel((viewportWidth / guidelineBaseWidth) * size);
|
|
9
9
|
const verticalScale = (size) => PixelRatio.roundToNearestPixel((viewportHeight / guidelineBaseHeight) * size);
|
|
10
10
|
const moderateScale = (size, factor = 1) => size + (horizontalScale(size) - size) * factor;
|
|
11
11
|
/* istanbul ignore next */
|
|
12
|
-
const scaledForDevice = (size, scaleCallback) =>
|
|
12
|
+
const scaledForDevice = (size, scaleCallback) => isWeb ? size : scaleCallback(size);
|
|
13
13
|
export { isIOS, viewportWidth, viewportHeight, isSmallDevice, horizontalScale, verticalScale, moderateScale, scaledForDevice, };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Alert, Base, Black, Env, Error, GreyScale, Primary, Success, Warning, White } from '../ts/interfaces/colors';
|
|
1
|
+
import { Alert, Base, Black, Env, Error, GreyScale, Primary, Success, Warning, White, Palette } from '../ts/interfaces/colors';
|
|
2
2
|
declare const primary: Primary;
|
|
3
3
|
declare const black: Black;
|
|
4
4
|
declare const white: White;
|
|
@@ -9,16 +9,5 @@ declare const error: Error;
|
|
|
9
9
|
declare const warning: Warning;
|
|
10
10
|
declare const alert: Alert;
|
|
11
11
|
declare const environment: Env;
|
|
12
|
-
declare const palette:
|
|
13
|
-
primary: Primary;
|
|
14
|
-
black: Black;
|
|
15
|
-
white: White;
|
|
16
|
-
grey: GreyScale;
|
|
17
|
-
base: Base;
|
|
18
|
-
success: Success;
|
|
19
|
-
error: Error;
|
|
20
|
-
warning: Warning;
|
|
21
|
-
alert: Alert;
|
|
22
|
-
environment: Env;
|
|
23
|
-
};
|
|
12
|
+
declare const palette: Palette;
|
|
24
13
|
export { primary, black, white, grey, base, success, error, warning, alert, environment, palette };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export interface GreyScale {
|
|
2
|
+
[key: string]: string;
|
|
2
3
|
100: string;
|
|
3
4
|
200: string;
|
|
4
5
|
300: string;
|
|
@@ -8,14 +9,17 @@ export interface GreyScale {
|
|
|
8
9
|
700: string;
|
|
9
10
|
}
|
|
10
11
|
export interface Env {
|
|
12
|
+
[key: string]: string;
|
|
11
13
|
qa: string;
|
|
12
14
|
beta: string;
|
|
13
15
|
}
|
|
14
16
|
export interface Base {
|
|
17
|
+
[key: string]: string;
|
|
15
18
|
black: string;
|
|
16
19
|
white: string;
|
|
17
20
|
}
|
|
18
21
|
export interface gamaColor {
|
|
22
|
+
[key: string]: string;
|
|
19
23
|
main: string;
|
|
20
24
|
dark: string;
|
|
21
25
|
}
|
|
@@ -36,3 +40,16 @@ export interface White extends Primary {
|
|
|
36
40
|
export interface Black extends gamaColor {
|
|
37
41
|
semiTransparent: string;
|
|
38
42
|
}
|
|
43
|
+
export interface Palette {
|
|
44
|
+
[key: string]: any;
|
|
45
|
+
primary: Primary;
|
|
46
|
+
black: Black;
|
|
47
|
+
white: White;
|
|
48
|
+
grey: GreyScale;
|
|
49
|
+
base: Base;
|
|
50
|
+
success: Success;
|
|
51
|
+
error: Error;
|
|
52
|
+
warning: Warning;
|
|
53
|
+
alert: Alert;
|
|
54
|
+
environment: Env;
|
|
55
|
+
}
|
package/package.json
CHANGED
package/dist/env.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "LOAD_STORYBOOK": true, "WEB_MODE": false }
|
|
@@ -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,17 +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
|
-
onPress: () => void;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
export default Chevron;
|
|
@@ -1,20 +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
|
-
import { moderateScale, scaledForDevice } from '../../../../../scale';
|
|
6
|
-
const Chevron = ({ style, color, size = 21, onPress, ...props }) => {
|
|
7
|
-
const validSize = scaledForDevice(size, moderateScale);
|
|
8
|
-
return (<Pressable onPress={onPress} style={style} {...props}>
|
|
9
|
-
<View>
|
|
10
|
-
<Svg width={validSize} height={validSize} viewBox="0 0 16 16">
|
|
11
|
-
<Path d="M8.17432 11.1055L3 6.49316L4.33106 5L8.17627 8.42773L12.0132 5.01904L13.3413 6.51416L8.17432 11.1055Z" fill={color}/>
|
|
12
|
-
</Svg>
|
|
13
|
-
</View>
|
|
14
|
-
</Pressable>);
|
|
15
|
-
};
|
|
16
|
-
Chevron.defaultProps = {
|
|
17
|
-
color: primary.main,
|
|
18
|
-
onPress: () => { },
|
|
19
|
-
};
|
|
20
|
-
export default Chevron;
|
|
@@ -1,17 +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
|
-
onPress: () => void;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
export default Delete;
|
|
@@ -1,20 +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
|
-
import { moderateScale, scaledForDevice } from '../../../../../scale';
|
|
6
|
-
const Delete = ({ style, color, size = 21, onPress, ...props }) => {
|
|
7
|
-
const validSize = scaledForDevice(size, moderateScale);
|
|
8
|
-
return (<Pressable onPress={onPress} style={style} {...props}>
|
|
9
|
-
<View>
|
|
10
|
-
<Svg width={validSize} height={validSize} viewBox="0 0 16 16">
|
|
11
|
-
<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}/>
|
|
12
|
-
</Svg>
|
|
13
|
-
</View>
|
|
14
|
-
</Pressable>);
|
|
15
|
-
};
|
|
16
|
-
Delete.defaultProps = {
|
|
17
|
-
color: black.main,
|
|
18
|
-
onPress: () => { },
|
|
19
|
-
};
|
|
20
|
-
export default Delete;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|