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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -0
  3. package/lib/commonjs/Dropdown.js +138 -0
  4. package/lib/commonjs/Dropdown.js.map +1 -0
  5. package/lib/commonjs/DropdownList.js +90 -0
  6. package/lib/commonjs/DropdownList.js.map +1 -0
  7. package/lib/commonjs/DropdownListItem.js +68 -0
  8. package/lib/commonjs/DropdownListItem.js.map +1 -0
  9. package/lib/commonjs/Modal.js +56 -0
  10. package/lib/commonjs/Modal.js.map +1 -0
  11. package/lib/commonjs/asset/arrow-down.png +0 -0
  12. package/lib/commonjs/index.js +129 -0
  13. package/lib/commonjs/index.js.map +1 -0
  14. package/lib/commonjs/styles/colors.js +16 -0
  15. package/lib/commonjs/styles/colors.js.map +1 -0
  16. package/lib/commonjs/styles/typography.js +20 -0
  17. package/lib/commonjs/styles/typography.js.map +1 -0
  18. package/lib/module/Dropdown.js +124 -0
  19. package/lib/module/Dropdown.js.map +1 -0
  20. package/lib/module/DropdownList.js +76 -0
  21. package/lib/module/DropdownList.js.map +1 -0
  22. package/lib/module/DropdownListItem.js +49 -0
  23. package/lib/module/DropdownListItem.js.map +1 -0
  24. package/lib/module/Modal.js +43 -0
  25. package/lib/module/Modal.js.map +1 -0
  26. package/lib/module/asset/arrow-down.png +0 -0
  27. package/lib/module/index.js +109 -0
  28. package/lib/module/index.js.map +1 -0
  29. package/lib/module/styles/colors.js +9 -0
  30. package/lib/module/styles/colors.js.map +1 -0
  31. package/lib/module/styles/typography.js +10 -0
  32. package/lib/module/styles/typography.js.map +1 -0
  33. package/lib/typescript/Dropdown.d.ts +2 -0
  34. package/lib/typescript/DropdownList.d.ts +2 -0
  35. package/lib/typescript/DropdownListItem.d.ts +3 -0
  36. package/lib/typescript/Modal.d.ts +2 -0
  37. package/lib/typescript/index.d.ts +2 -0
  38. package/lib/typescript/styles/colors.d.ts +1 -0
  39. package/lib/typescript/styles/typography.d.ts +1 -0
  40. package/package.json +151 -0
  41. package/src/Dropdown.tsx +125 -0
  42. package/src/DropdownList.tsx +76 -0
  43. package/src/DropdownListItem.tsx +51 -0
  44. package/src/Modal.tsx +57 -0
  45. package/src/asset/arrow-down.png +0 -0
  46. package/src/index.tsx +120 -0
  47. package/src/styles/colors.ts +8 -0
  48. 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
+ }
@@ -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;
@@ -0,0 +1,8 @@
1
+ export const colors: any = {
2
+ primary: '#EF8031',
3
+ black: '#000000',
4
+ white: '#FFFFFF',
5
+ dark: '#11142D',
6
+ gray: '#808191',
7
+ lightGray: '#F7F7F7',
8
+ };
@@ -0,0 +1,10 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export const typography: any = StyleSheet.create({
4
+ caption: {
5
+ fontStyle: 'normal',
6
+ fontWeight: 'normal',
7
+ fontSize: 12,
8
+ lineHeight: 15,
9
+ },
10
+ });