react-native-input-select 0.2.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/LICENSE +21 -0
- package/README.md +69 -0
- package/lib/commonjs/Dropdown.js +138 -0
- package/lib/commonjs/Dropdown.js.map +1 -0
- package/lib/commonjs/DropdownList.js +90 -0
- package/lib/commonjs/DropdownList.js.map +1 -0
- package/lib/commonjs/DropdownListItem.js +68 -0
- package/lib/commonjs/DropdownListItem.js.map +1 -0
- package/lib/commonjs/Modal.js +56 -0
- package/lib/commonjs/Modal.js.map +1 -0
- package/lib/commonjs/asset/arrow-down.png +0 -0
- package/lib/commonjs/index.js +129 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/styles/colors.js +16 -0
- package/lib/commonjs/styles/colors.js.map +1 -0
- package/lib/commonjs/styles/typography.js +20 -0
- package/lib/commonjs/styles/typography.js.map +1 -0
- package/lib/module/Dropdown.js +124 -0
- package/lib/module/Dropdown.js.map +1 -0
- package/lib/module/DropdownList.js +76 -0
- package/lib/module/DropdownList.js.map +1 -0
- package/lib/module/DropdownListItem.js +49 -0
- package/lib/module/DropdownListItem.js.map +1 -0
- package/lib/module/Modal.js +43 -0
- package/lib/module/Modal.js.map +1 -0
- package/lib/module/asset/arrow-down.png +0 -0
- package/lib/module/index.js +109 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/styles/colors.js +9 -0
- package/lib/module/styles/colors.js.map +1 -0
- package/lib/module/styles/typography.js +10 -0
- package/lib/module/styles/typography.js.map +1 -0
- package/lib/typescript/Dropdown.d.ts +2 -0
- package/lib/typescript/DropdownList.d.ts +2 -0
- package/lib/typescript/DropdownListItem.d.ts +3 -0
- package/lib/typescript/Modal.d.ts +2 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/styles/colors.d.ts +1 -0
- package/lib/typescript/styles/typography.d.ts +1 -0
- package/package.json +151 -0
- package/src/Dropdown.tsx +125 -0
- package/src/DropdownList.tsx +76 -0
- package/src/DropdownListItem.tsx +51 -0
- package/src/Modal.tsx +57 -0
- package/src/asset/arrow-down.png +0 -0
- package/src/index.tsx +120 -0
- package/src/styles/colors.ts +8 -0
- package/src/styles/typography.ts +10 -0
package/package.json
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-input-select",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Dropdown package for react-native",
|
|
5
|
+
"main": "lib/commonjs/index",
|
|
6
|
+
"module": "lib/module/index",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index",
|
|
9
|
+
"source": "src/index",
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"lib",
|
|
13
|
+
"android",
|
|
14
|
+
"ios",
|
|
15
|
+
"cpp",
|
|
16
|
+
"react-native-select.podspec",
|
|
17
|
+
"!lib/typescript/example",
|
|
18
|
+
"!android/build",
|
|
19
|
+
"!ios/build",
|
|
20
|
+
"!**/__tests__",
|
|
21
|
+
"!**/__fixtures__",
|
|
22
|
+
"!**/__mocks__"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"test": "jest",
|
|
26
|
+
"typescript": "tsc --noEmit",
|
|
27
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
28
|
+
"prepare": "bob build",
|
|
29
|
+
"release": "release-it -- minor --ci",
|
|
30
|
+
"example": "yarn --cwd example",
|
|
31
|
+
"pods": "cd example && pod-install --quiet",
|
|
32
|
+
"bootstrap": "yarn example && yarn && yarn pods"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"react-native",
|
|
36
|
+
"ios",
|
|
37
|
+
"android"
|
|
38
|
+
],
|
|
39
|
+
"repository": "https://github.com/azeezat/react-native-select",
|
|
40
|
+
"author": "Azeezat <azeezat94@gmail.com> (https://github.com/azeezat)",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/azeezat/react-native-select/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/azeezat/react-native-select#readme",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"registry": "https://registry.npmjs.org/"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@commitlint/config-conventional": "^11.0.0",
|
|
51
|
+
"@react-native-community/eslint-config": "^2.0.0",
|
|
52
|
+
"@release-it/conventional-changelog": "^2.0.0",
|
|
53
|
+
"@types/jest": "^26.0.0",
|
|
54
|
+
"@types/react": "^16.9.19",
|
|
55
|
+
"@types/react-native": "^0.66.11",
|
|
56
|
+
"commitlint": "^11.0.0",
|
|
57
|
+
"eslint": "^7.2.0",
|
|
58
|
+
"eslint-config-prettier": "^7.0.0",
|
|
59
|
+
"eslint-plugin-prettier": "^3.1.3",
|
|
60
|
+
"husky": "^6.0.0",
|
|
61
|
+
"jest": "^26.0.1",
|
|
62
|
+
"pod-install": "^0.1.0",
|
|
63
|
+
"prettier": "^2.0.5",
|
|
64
|
+
"react": "16.13.1",
|
|
65
|
+
"react-native": "0.63.4",
|
|
66
|
+
"react-native-builder-bob": "^0.18.2",
|
|
67
|
+
"release-it": "^14.11.8",
|
|
68
|
+
"typescript": "^4.1.3"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@react-native-community/checkbox": "^0.5.9",
|
|
72
|
+
"react": "*",
|
|
73
|
+
"react-native": "*"
|
|
74
|
+
},
|
|
75
|
+
"jest": {
|
|
76
|
+
"preset": "react-native",
|
|
77
|
+
"modulePathIgnorePatterns": [
|
|
78
|
+
"<rootDir>/example/node_modules",
|
|
79
|
+
"<rootDir>/lib/"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
"commitlint": {
|
|
83
|
+
"extends": [
|
|
84
|
+
"@commitlint/config-conventional"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"release-it": {
|
|
88
|
+
"git": {
|
|
89
|
+
"commitMessage": "chore: release ${version}",
|
|
90
|
+
"tagName": "v${version}"
|
|
91
|
+
},
|
|
92
|
+
"npm": {
|
|
93
|
+
"publish": true
|
|
94
|
+
},
|
|
95
|
+
"github": {
|
|
96
|
+
"release": true
|
|
97
|
+
},
|
|
98
|
+
"plugins": {
|
|
99
|
+
"@release-it/conventional-changelog": {
|
|
100
|
+
"preset": "angular"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"eslintConfig": {
|
|
105
|
+
"root": true,
|
|
106
|
+
"extends": [
|
|
107
|
+
"@react-native-community",
|
|
108
|
+
"prettier"
|
|
109
|
+
],
|
|
110
|
+
"rules": {
|
|
111
|
+
"prettier/prettier": [
|
|
112
|
+
"error",
|
|
113
|
+
{
|
|
114
|
+
"quoteProps": "consistent",
|
|
115
|
+
"singleQuote": true,
|
|
116
|
+
"tabWidth": 2,
|
|
117
|
+
"trailingComma": "es5",
|
|
118
|
+
"useTabs": false
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"eslintIgnore": [
|
|
124
|
+
"node_modules/",
|
|
125
|
+
"lib/"
|
|
126
|
+
],
|
|
127
|
+
"prettier": {
|
|
128
|
+
"quoteProps": "consistent",
|
|
129
|
+
"singleQuote": true,
|
|
130
|
+
"tabWidth": 2,
|
|
131
|
+
"trailingComma": "es5",
|
|
132
|
+
"useTabs": false
|
|
133
|
+
},
|
|
134
|
+
"react-native-builder-bob": {
|
|
135
|
+
"source": "src",
|
|
136
|
+
"output": "lib",
|
|
137
|
+
"targets": [
|
|
138
|
+
"commonjs",
|
|
139
|
+
"module",
|
|
140
|
+
[
|
|
141
|
+
"typescript",
|
|
142
|
+
{
|
|
143
|
+
"project": "tsconfig.build.json"
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
"dependencies": {
|
|
149
|
+
"@react-native-community/checkbox": "^0.5.9"
|
|
150
|
+
}
|
|
151
|
+
}
|
package/src/Dropdown.tsx
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
Pressable,
|
|
6
|
+
ScrollView,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
Image,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import { colors } from './styles/colors';
|
|
11
|
+
import { typography } from './styles/typography';
|
|
12
|
+
|
|
13
|
+
const Dropdown = ({
|
|
14
|
+
label,
|
|
15
|
+
placeholder,
|
|
16
|
+
helperText,
|
|
17
|
+
error,
|
|
18
|
+
getSelectedItemsLabel,
|
|
19
|
+
setOpen,
|
|
20
|
+
open,
|
|
21
|
+
isMultiple,
|
|
22
|
+
selectedItem,
|
|
23
|
+
selectedItems,
|
|
24
|
+
labelStyle,
|
|
25
|
+
dropdownStyle,
|
|
26
|
+
dropdownContainerStyle,
|
|
27
|
+
selectedItemStyle,
|
|
28
|
+
}: any) => {
|
|
29
|
+
return (
|
|
30
|
+
<View style={[styles.dropdownInputContainer, dropdownContainerStyle]}>
|
|
31
|
+
{label && label !== '' && (
|
|
32
|
+
<Text style={[styles.label, labelStyle]}>{label}</Text>
|
|
33
|
+
)}
|
|
34
|
+
<Pressable
|
|
35
|
+
onPress={() => setOpen(!open)}
|
|
36
|
+
style={({ pressed }) => [
|
|
37
|
+
pressed && styles.inputFocusState,
|
|
38
|
+
styles.input,
|
|
39
|
+
dropdownStyle,
|
|
40
|
+
]}
|
|
41
|
+
>
|
|
42
|
+
<ScrollView
|
|
43
|
+
horizontal
|
|
44
|
+
alwaysBounceHorizontal
|
|
45
|
+
showsHorizontalScrollIndicator={false}
|
|
46
|
+
>
|
|
47
|
+
<View
|
|
48
|
+
style={styles.selectedItemsContainer}
|
|
49
|
+
onStartShouldSetResponder={() => true}
|
|
50
|
+
>
|
|
51
|
+
{isMultiple ? (
|
|
52
|
+
getSelectedItemsLabel().map((item: any, i: Number) => (
|
|
53
|
+
<Text
|
|
54
|
+
key={`SelectedItems${i}`}
|
|
55
|
+
style={[styles.selectedItems, selectedItemStyle]}
|
|
56
|
+
>
|
|
57
|
+
{item}
|
|
58
|
+
</Text>
|
|
59
|
+
))
|
|
60
|
+
) : (
|
|
61
|
+
<Text style={styles.blackText}>{getSelectedItemsLabel()}</Text>
|
|
62
|
+
)}
|
|
63
|
+
</View>
|
|
64
|
+
|
|
65
|
+
{!selectedItem && selectedItems?.length === 0 && (
|
|
66
|
+
<Text style={styles.blackText}>
|
|
67
|
+
{placeholder ?? 'Select an option'}
|
|
68
|
+
</Text>
|
|
69
|
+
)}
|
|
70
|
+
</ScrollView>
|
|
71
|
+
<View style={styles.iconStyle}>
|
|
72
|
+
<Image source={require('../src/asset/arrow-down.png')} />
|
|
73
|
+
</View>
|
|
74
|
+
</Pressable>
|
|
75
|
+
|
|
76
|
+
{error && error !== '' && <Text style={styles.error}>{error}</Text>}
|
|
77
|
+
|
|
78
|
+
{helperText && helperText !== '' && !error && (
|
|
79
|
+
<Text style={styles.helper}>{helperText}</Text>
|
|
80
|
+
)}
|
|
81
|
+
</View>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const styles = StyleSheet.create({
|
|
86
|
+
label: { marginBottom: 16, color: colors.gray, ...typography.caption },
|
|
87
|
+
input: {
|
|
88
|
+
paddingVertical: 18,
|
|
89
|
+
paddingHorizontal: 23,
|
|
90
|
+
backgroundColor: colors.lightGray,
|
|
91
|
+
borderRadius: 8,
|
|
92
|
+
borderColor: colors.dark,
|
|
93
|
+
borderWidth: 1,
|
|
94
|
+
color: colors.dark,
|
|
95
|
+
width: '100%',
|
|
96
|
+
minHeight: 64,
|
|
97
|
+
},
|
|
98
|
+
inputFocusState: {
|
|
99
|
+
borderWidth: 2,
|
|
100
|
+
borderStyle: 'solid',
|
|
101
|
+
borderColor: colors.primary,
|
|
102
|
+
borderRadius: 8,
|
|
103
|
+
},
|
|
104
|
+
inputFocusErrorState: {
|
|
105
|
+
borderWidth: 2,
|
|
106
|
+
borderStyle: 'solid',
|
|
107
|
+
borderColor: colors.cliqkiRed,
|
|
108
|
+
},
|
|
109
|
+
iconStyle: { position: 'absolute', right: 25, top: 25 },
|
|
110
|
+
error: { color: colors.cliqkiRed, marginTop: 8, ...typography.caption },
|
|
111
|
+
helper: { marginTop: 8, color: colors.primary, ...typography.caption },
|
|
112
|
+
dropdownInputContainer: { marginBottom: 23, width: '100%' },
|
|
113
|
+
selectedItemsContainer: { flexDirection: 'row', flexWrap: 'nowrap' },
|
|
114
|
+
selectedItems: {
|
|
115
|
+
color: colors.white,
|
|
116
|
+
paddingHorizontal: 10,
|
|
117
|
+
paddingVertical: 5,
|
|
118
|
+
borderRadius: 10,
|
|
119
|
+
backgroundColor: colors.primary,
|
|
120
|
+
marginRight: 10,
|
|
121
|
+
},
|
|
122
|
+
blackText: { color: colors.black },
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
export default Dropdown;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, FlatList, StyleSheet } from 'react-native';
|
|
3
|
+
import DropdownListItem from './DropdownListItem';
|
|
4
|
+
import { colors } from './styles/colors';
|
|
5
|
+
|
|
6
|
+
const DropdownList = ({
|
|
7
|
+
options,
|
|
8
|
+
optionLabel,
|
|
9
|
+
optionValue,
|
|
10
|
+
isMultiple,
|
|
11
|
+
selectedItems,
|
|
12
|
+
selectedItem,
|
|
13
|
+
handleMultipleSelections,
|
|
14
|
+
handleSingleSelection,
|
|
15
|
+
}: any) => {
|
|
16
|
+
return (
|
|
17
|
+
<FlatList
|
|
18
|
+
data={options}
|
|
19
|
+
extraData={isMultiple ? selectedItems : selectedItem}
|
|
20
|
+
initialNumToRender={5}
|
|
21
|
+
// ListEmptyComponent={
|
|
22
|
+
// <EmptyStateComponent
|
|
23
|
+
// style={{alignItems: 'flex-start', marginTop: 30}}
|
|
24
|
+
// message="Be the first to reply"
|
|
25
|
+
// />
|
|
26
|
+
// }
|
|
27
|
+
ItemSeparatorComponent={() => <View style={styles.itemSeparatorStyle} />}
|
|
28
|
+
renderItem={(item) =>
|
|
29
|
+
_renderItem(item, {
|
|
30
|
+
optionLabel,
|
|
31
|
+
optionValue,
|
|
32
|
+
isMultiple,
|
|
33
|
+
selectedOption: isMultiple ? selectedItems : selectedItem,
|
|
34
|
+
onChange: isMultiple
|
|
35
|
+
? handleMultipleSelections
|
|
36
|
+
: handleSingleSelection,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
keyExtractor={(_item, index) => `Options${index}`}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const _renderItem = ({ item }: any, props: any) => {
|
|
45
|
+
return (
|
|
46
|
+
<DropdownListItem
|
|
47
|
+
item={item}
|
|
48
|
+
optionLabel={props.optionLabel}
|
|
49
|
+
optionValue={props.optionValue}
|
|
50
|
+
isMultiple={props.isMultiple}
|
|
51
|
+
selectedOption={props.selectedOption}
|
|
52
|
+
onChange={props.onChange}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const styles = StyleSheet.create({
|
|
58
|
+
modalContainer: {
|
|
59
|
+
flex: 1,
|
|
60
|
+
justifyContent: 'flex-end',
|
|
61
|
+
},
|
|
62
|
+
modalBackgroundStyle: { backgroundColor: 'rgba(0, 0, 0, 0.5)' },
|
|
63
|
+
modalOptionsContainer: {
|
|
64
|
+
maxHeight: '50%',
|
|
65
|
+
backgroundColor: colors.white,
|
|
66
|
+
borderTopLeftRadius: 16,
|
|
67
|
+
borderTopRightRadius: 16,
|
|
68
|
+
},
|
|
69
|
+
itemSeparatorStyle: {
|
|
70
|
+
backgroundColor: colors.gray,
|
|
71
|
+
height: 1,
|
|
72
|
+
opacity: 0.15,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export default DropdownList;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
|
|
3
|
+
import CheckBox from '@react-native-community/checkbox';
|
|
4
|
+
import { colors } from './styles/colors';
|
|
5
|
+
|
|
6
|
+
const DropdownListItem = ({
|
|
7
|
+
item,
|
|
8
|
+
optionLabel,
|
|
9
|
+
optionValue,
|
|
10
|
+
isMultiple,
|
|
11
|
+
selectedOption,
|
|
12
|
+
onChange,
|
|
13
|
+
}: any) => {
|
|
14
|
+
const selectedOptionValue = optionValue ?? 'value';
|
|
15
|
+
return (
|
|
16
|
+
<TouchableOpacity
|
|
17
|
+
style={styles.modalOptions}
|
|
18
|
+
onPress={() => onChange(item[selectedOptionValue])}
|
|
19
|
+
>
|
|
20
|
+
<View style={styles.spacing}>
|
|
21
|
+
<CheckBox
|
|
22
|
+
value={
|
|
23
|
+
isMultiple
|
|
24
|
+
? selectedOption.includes(item[selectedOptionValue])
|
|
25
|
+
: [selectedOption].includes(item[selectedOptionValue])
|
|
26
|
+
}
|
|
27
|
+
onChange={() => onChange(item[selectedOptionValue])}
|
|
28
|
+
boxType="circle" //works on ios only
|
|
29
|
+
tintColors={{ true: colors.primary }} //android control
|
|
30
|
+
onCheckColor={colors.primary} //ios checkmark colour control
|
|
31
|
+
onTintColor={colors.primary} //ios box colour control
|
|
32
|
+
/>
|
|
33
|
+
</View>
|
|
34
|
+
<View>
|
|
35
|
+
<Text>{item[optionLabel ?? 'label']}</Text>
|
|
36
|
+
</View>
|
|
37
|
+
</TouchableOpacity>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const styles = StyleSheet.create({
|
|
42
|
+
spacing: { marginRight: 10 },
|
|
43
|
+
modalOptions: {
|
|
44
|
+
paddingHorizontal: 20,
|
|
45
|
+
paddingVertical: 10,
|
|
46
|
+
flexDirection: 'row',
|
|
47
|
+
alignItems: 'center',
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export default memo(DropdownListItem);
|
package/src/Modal.tsx
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Modal,
|
|
4
|
+
TouchableOpacity,
|
|
5
|
+
SafeAreaView,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import { colors } from './styles/colors';
|
|
9
|
+
|
|
10
|
+
const CustomModal = ({
|
|
11
|
+
open,
|
|
12
|
+
setOpen,
|
|
13
|
+
onRequestClose,
|
|
14
|
+
modalBackgroundStyle,
|
|
15
|
+
modalOptionsContainerStyle,
|
|
16
|
+
children,
|
|
17
|
+
}: any) => {
|
|
18
|
+
return (
|
|
19
|
+
<Modal
|
|
20
|
+
transparent={true}
|
|
21
|
+
visible={open}
|
|
22
|
+
onRequestClose={() => onRequestClose()}
|
|
23
|
+
animationType="fade"
|
|
24
|
+
>
|
|
25
|
+
<TouchableOpacity
|
|
26
|
+
onPress={() => setOpen(!open)}
|
|
27
|
+
style={[
|
|
28
|
+
styles.modalContainer,
|
|
29
|
+
styles.modalBackgroundStyle,
|
|
30
|
+
modalBackgroundStyle,
|
|
31
|
+
]}
|
|
32
|
+
>
|
|
33
|
+
<SafeAreaView
|
|
34
|
+
style={[styles.modalOptionsContainer, modalOptionsContainerStyle]}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</SafeAreaView>
|
|
38
|
+
</TouchableOpacity>
|
|
39
|
+
</Modal>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const styles = StyleSheet.create({
|
|
44
|
+
modalContainer: {
|
|
45
|
+
flex: 1,
|
|
46
|
+
justifyContent: 'flex-end',
|
|
47
|
+
},
|
|
48
|
+
modalBackgroundStyle: { backgroundColor: 'rgba(0, 0, 0, 0.5)' },
|
|
49
|
+
modalOptionsContainer: {
|
|
50
|
+
maxHeight: '50%',
|
|
51
|
+
backgroundColor: colors.white,
|
|
52
|
+
borderTopLeftRadius: 16,
|
|
53
|
+
borderTopRightRadius: 16,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export default CustomModal;
|
|
Binary file
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import Dropdown from './Dropdown';
|
|
3
|
+
import CustomModal from './Modal';
|
|
4
|
+
import DropdownList from './DropdownList';
|
|
5
|
+
|
|
6
|
+
export const DropdownSelect = ({
|
|
7
|
+
placeholder,
|
|
8
|
+
label,
|
|
9
|
+
error,
|
|
10
|
+
helperText,
|
|
11
|
+
options,
|
|
12
|
+
optionLabel,
|
|
13
|
+
optionValue,
|
|
14
|
+
onValueChange,
|
|
15
|
+
selectedValue,
|
|
16
|
+
isMultiple,
|
|
17
|
+
labelStyle,
|
|
18
|
+
dropdownStyle,
|
|
19
|
+
dropdownContainerStyle,
|
|
20
|
+
selectedItemStyle,
|
|
21
|
+
modalBackgroundStyle,
|
|
22
|
+
modalOptionsContainer,
|
|
23
|
+
}: any) => {
|
|
24
|
+
const [open, setOpen] = useState(false);
|
|
25
|
+
const [selectedItem, setSelectedItem] = useState(selectedValue); //for single selection
|
|
26
|
+
const [selectedItems, setSelectedItems] = useState(
|
|
27
|
+
Array.isArray(selectedValue) ? selectedValue : []
|
|
28
|
+
); //for multiple selection
|
|
29
|
+
|
|
30
|
+
/*===========================================
|
|
31
|
+
* Selection handlers
|
|
32
|
+
*==========================================*/
|
|
33
|
+
const handleSingleSelection = (value: any) => {
|
|
34
|
+
if (selectedItem === value) {
|
|
35
|
+
setSelectedItem(null);
|
|
36
|
+
} else {
|
|
37
|
+
setSelectedItem(value);
|
|
38
|
+
onValueChange(value); //send value to parent
|
|
39
|
+
setOpen(false); //close modal upon selection
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const handleMultipleSelections = (value: any) => {
|
|
44
|
+
let selectedValues = [...selectedItems];
|
|
45
|
+
|
|
46
|
+
if (selectedValues.includes(value)) {
|
|
47
|
+
selectedValues = selectedValues.filter((item) => item !== value);
|
|
48
|
+
} else {
|
|
49
|
+
selectedValues.push(value);
|
|
50
|
+
}
|
|
51
|
+
setSelectedItems(selectedValues);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/*===========================================
|
|
55
|
+
* Get label handler
|
|
56
|
+
*==========================================*/
|
|
57
|
+
const getSelectedItemsLabel = () => {
|
|
58
|
+
if (isMultiple) {
|
|
59
|
+
let selectedLabels: Array<string> = [];
|
|
60
|
+
selectedItems &&
|
|
61
|
+
selectedItems.forEach((element) => {
|
|
62
|
+
let selectedItemLabel =
|
|
63
|
+
options &&
|
|
64
|
+
options.find(
|
|
65
|
+
(item: string) => item[optionValue ?? 'value'] === element
|
|
66
|
+
)?.[optionLabel];
|
|
67
|
+
selectedLabels.push(selectedItemLabel);
|
|
68
|
+
});
|
|
69
|
+
return selectedLabels;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let selectedItemLabel =
|
|
73
|
+
options &&
|
|
74
|
+
options.find(
|
|
75
|
+
(item: string) => item[optionValue ?? 'value'] === selectedItem
|
|
76
|
+
);
|
|
77
|
+
return selectedItemLabel?.[optionLabel];
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<>
|
|
82
|
+
<Dropdown
|
|
83
|
+
label={label}
|
|
84
|
+
placeholder={placeholder}
|
|
85
|
+
helperText={helperText}
|
|
86
|
+
error={error}
|
|
87
|
+
getSelectedItemsLabel={getSelectedItemsLabel}
|
|
88
|
+
selectedItem={selectedItem}
|
|
89
|
+
selectedItems={selectedItems}
|
|
90
|
+
setOpen={setOpen}
|
|
91
|
+
open={open}
|
|
92
|
+
labelStyle={labelStyle}
|
|
93
|
+
dropdownStyle={dropdownStyle}
|
|
94
|
+
dropdownContainerStyle={dropdownContainerStyle}
|
|
95
|
+
selectedItemStyle={selectedItemStyle}
|
|
96
|
+
isMultiple={isMultiple}
|
|
97
|
+
/>
|
|
98
|
+
<CustomModal
|
|
99
|
+
open={open}
|
|
100
|
+
setOpen={setOpen}
|
|
101
|
+
modalBackgroundStyle={modalBackgroundStyle}
|
|
102
|
+
modalOptionsContainer={modalOptionsContainer}
|
|
103
|
+
onRequestClose={() => {}}
|
|
104
|
+
>
|
|
105
|
+
<DropdownList
|
|
106
|
+
options={options}
|
|
107
|
+
optionLabel={optionLabel}
|
|
108
|
+
optionValue={optionValue}
|
|
109
|
+
isMultiple={isMultiple}
|
|
110
|
+
selectedItems={selectedItems}
|
|
111
|
+
selectedItem={selectedItem}
|
|
112
|
+
handleMultipleSelections={handleMultipleSelections}
|
|
113
|
+
handleSingleSelection={handleSingleSelection}
|
|
114
|
+
/>
|
|
115
|
+
</CustomModal>
|
|
116
|
+
</>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default DropdownSelect;
|