Skip to content

Commit 954088f

Browse files
committed
feat: initial package
1 parent 9dca233 commit 954088f

File tree

23 files changed

+1059
-28
lines changed

23 files changed

+1059
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ node_modules/
4646
npm-debug.log
4747
yarn-debug.log
4848
yarn-error.log
49+
yarn.lock
4950

5051
# BUCK
5152
buck-out/

README.md

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
A Dropdown select component for React Native
44

5+
- [react-native-dropdown-select](#react-native-dropdown-select)
6+
- [Installation](#installation)
7+
- [Usage](#usage)
8+
- [When Status bar is hidden or translucent](#when-status-bar-is-hidden-or-translucent)
9+
- [Props](#props)
10+
- [Contributing](#contributing)
11+
- [License](#license)
12+
513
## Installation
614

715
```sh
@@ -11,13 +19,103 @@ npm install react-native-dropdown-select
1119
## Usage
1220

1321
```js
14-
import DropdownSelect from "react-native-dropdown-select";
22+
// ...
23+
import DropdownSelect from 'react-native-dropdown-select';
1524

1625
// ...
1726

18-
const result = await DropdownSelect.multiply(3, 7);
27+
const options = [
28+
{
29+
label: 'Javascript',
30+
value: 'js',
31+
},
32+
{
33+
label: 'Typescript',
34+
value: 'ts',
35+
},
36+
{
37+
label: 'Python',
38+
value: 'py',
39+
},
40+
];
41+
42+
const defaultValue = 'js';
43+
44+
function App() {
45+
const [value, setValue] = React.useState(defaultValue);
46+
return (
47+
<>
48+
<View style={styles.container}>
49+
<View>
50+
<DropdownSelect
51+
options={options}
52+
defaultValue={defaultValue}
53+
value={value}
54+
onSelectOption={(option) => {
55+
setValue(option.value);
56+
}}
57+
onHideDropdown={() => {
58+
console.log('hide');
59+
}}
60+
onShowDropdown={() => {
61+
console.log('show');
62+
}}
63+
/>
64+
</View>
65+
<Text>{value}</Text>
66+
<Button title="Default" onPress={() => setValue(defaultValue)} />
67+
</View>
68+
</>
69+
);
70+
}
71+
72+
const styles = StyleSheet.create({
73+
container: {
74+
flex: 1,
75+
alignItems: 'center',
76+
justifyContent: 'center',
77+
padding: 10,
78+
},
79+
});
1980
```
2081

82+
### When Status bar is hidden or translucent
83+
84+
```js
85+
<DropdownSelect options={options} withStatusBar={false} />;
86+
```
87+
88+
## Props
89+
| Name | Description | Type | Default | Required |
90+
| ------------------------ | --------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------- | -------- |
91+
| options | List of option for dropdown | `array` | | Yes |
92+
| defaultValue | Default value to display | `any` | | No |
93+
| value | Current value of dropdown select | `any` | | No |
94+
| position | Position of dropdown | `'top' | 'bottom'` | `'bottom'` | No |
95+
| placeholder | Placeholder of dropdown select to display when no option selected | `string` | `'Select an option...'` | No |
96+
| loading | Loading state of dropdown select | `boolean` | `false` | No |
97+
| withStatusBar | Default is `true`, change it to `false` if status bar is **hidden** or **translucent** | `boolean` | `true` | No |
98+
| component | Component to render dropdown button | `React.ComponentType | React.ReactNode` | | No |
99+
| render | Render dropdown button via render function | `(props) => React.ReactElement` | | No |
100+
| children | Loading state of dropdown select | `(props) => React.ReactElemnt | React.ReactNode` | | No |
101+
| loadingComponent | Loading component to render loading icon | `React.ComponentType | React.ReactNode` | | No |
102+
| renderLoading | Render loading icon via render function | `() => React.ReactElement` | | No |
103+
| optionComponent | Option component to render option item | `React.ComponentType | React.ReactNode` | | No |
104+
| renderOption | Render option item via render function | `(props) => React.ReactElement` | | No |
105+
| compareFunc | Compare function to compare two option, return `true` if equal otherwise return `false` | `(option1, option2) => boolean` | | No |
106+
| onShowDropdown | Callback function is called when dropdown will be shown | `() => void` | | No |
107+
| onHideDropdown | Callback function is called when dropdown will be hide | `() => void` | | No |
108+
| onSelectOption | Callback function is called when an option is selected | `(option1) => void` | | No |
109+
| buttonWrapperStyle | Additional styles for button's wrapper | `object` | | No |
110+
| buttonContainerStyle | Additional styles for button's container | `object` | | No |
111+
| buttonLabelStyle | Additional styles for button's label | `object` | | No |
112+
| buttonIconStyle | Additional styles for button's icon | `object` | | No |
113+
| dropdownStyle | Additional styles for dropdown's container | `object` | | No |
114+
| optionStyle | Additional styles for option's container | `object` | | No |
115+
| selectedOptionStyle | Additional styles for selected option's container | `object` | | No |
116+
| optionLabelStyle | Additional styles for option's label | `object` | | No |
117+
| selectedOptionLabelStyle | Additional styles for selected option's label | `object` | | No |
118+
21119
## Contributing
22120

23121
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.

example/android/app/src/main/java/com/example/reactnativedropdownselect/MainApplication.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import java.lang.reflect.InvocationTargetException;
1212
import java.util.List;
1313

14-
import com.reactnativedropdownselect.DropdownSelectPackage;
15-
1614
public class MainApplication extends Application implements ReactApplication {
1715

1816
private final ReactNativeHost mReactNativeHost =
@@ -28,7 +26,6 @@ protected List<ReactPackage> getPackages() {
2826
List<ReactPackage> packages = new PackageList(this).getPackages();
2927
// Packages that cannot be autolinked yet can be added manually here, for DropdownSelectExample:
3028
// packages.add(new MyReactNativePackage());
31-
packages.add(new DropdownSelectPackage());
3229

3330
return packages;
3431
}

example/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"scripts": {
77
"android": "react-native run-android",
88
"ios": "react-native run-ios",
9-
"start": "react-native start"
9+
"start": "react-native start",
10+
"reset-cache": "cd android & gradlew clean"
1011
},
1112
"dependencies": {
1213
"react": "16.11.0",
@@ -15,6 +16,8 @@
1516
"devDependencies": {
1617
"@babel/core": "^7.9.6",
1718
"@babel/runtime": "^7.9.6",
19+
"@types/react": "^16.9.55",
20+
"@types/react-native": "^0.63.32",
1821
"babel-plugin-module-resolver": "^4.0.0",
1922
"metro-react-native-babel-preset": "^0.59.0"
2023
}

example/src/App.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
11
import * as React from 'react';
2-
import { StyleSheet, View, Text } from 'react-native';
2+
import { Button, StyleSheet, Text, View } from 'react-native';
33
import DropdownSelect from 'react-native-dropdown-select';
4+
import { defaultValue, options } from './constants';
45

56
export default function App() {
6-
const [result, setResult] = React.useState<number | undefined>();
7-
8-
React.useEffect(() => {
9-
DropdownSelect.multiply(3, 7).then(setResult);
10-
}, []);
11-
7+
const [value, setValue] = React.useState(defaultValue);
128
return (
13-
<View style={styles.container}>
14-
<Text>Result: {result}</Text>
15-
</View>
9+
<>
10+
<View style={styles.container}>
11+
<View>
12+
<DropdownSelect
13+
options={options}
14+
defaultValue={defaultValue}
15+
value={value}
16+
onSelectOption={(option) => {
17+
setValue(option.value);
18+
}}
19+
onHideDropdown={() => {
20+
console.log('hide');
21+
}}
22+
onShowDropdown={() => {
23+
console.log('show');
24+
}}
25+
withStatusBar={true}
26+
/>
27+
</View>
28+
<Text>{value}</Text>
29+
<Button title="Default" onPress={() => setValue(defaultValue)} />
30+
</View>
31+
</>
1632
);
1733
}
1834

@@ -21,5 +37,6 @@ const styles = StyleSheet.create({
2137
flex: 1,
2238
alignItems: 'center',
2339
justifyContent: 'center',
40+
padding: 10,
2441
},
2542
});

example/src/constants.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export const options = [
2+
{
3+
label: 'Javascript',
4+
value: 'js',
5+
},
6+
{
7+
label: 'Typescript',
8+
value: 'ts',
9+
},
10+
{
11+
label: 'Python',
12+
value: 'py',
13+
},
14+
];
15+
16+
export const defaultValue = 'js';

package.json

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@
3232
"keywords": [
3333
"react-native",
3434
"ios",
35-
"android"
35+
"android",
36+
"dropdown-select",
37+
"selector",
38+
"dropdown-modal",
39+
"select",
40+
"picker",
41+
"dropdown-picker"
3642
],
3743
"repository": "https://github.com/niku98/react-native-dropdown-select",
3844
"author": "Niku <[email protected]> (https://github.com/niku98)",
@@ -41,6 +47,9 @@
4147
"url": "https://github.com/niku98/react-native-dropdown-select/issues"
4248
},
4349
"homepage": "https://github.com/niku98/react-native-dropdown-select#readme",
50+
"dependencies": {
51+
"react-native-status-bar-height": "^2.5.0"
52+
},
4453
"devDependencies": {
4554
"@commitlint/config-conventional": "^8.3.4",
4655
"@react-native-community/bob": "^0.16.2",
@@ -57,14 +66,14 @@
5766
"jest": "^26.0.1",
5867
"pod-install": "^0.1.0",
5968
"prettier": "^2.0.5",
60-
"react": "16.11.0",
61-
"react-native": "0.62.2",
6269
"release-it": "^13.5.8",
6370
"typescript": "^3.8.3"
6471
},
6572
"peerDependencies": {
66-
"react": "*",
67-
"react-native": "*"
73+
"@types/react": "*",
74+
"@types/react-native": "0.63.2",
75+
"react": "16.13.1",
76+
"react-native": "0.63.2"
6877
},
6978
"jest": {
7079
"preset": "react-native",
@@ -107,6 +116,9 @@
107116
"prettier"
108117
],
109118
"rules": {
119+
"react-hooks/exhaustive-deps": [
120+
0
121+
],
110122
"prettier/prettier": [
111123
"error",
112124
{
@@ -119,7 +131,10 @@
119131
]
120132
}
121133
},
122-
"eslintIgnore": ["node_modules/", "lib/"],
134+
"eslintIgnore": [
135+
"node_modules/",
136+
"lib/"
137+
],
123138
"prettier": {
124139
"quoteProps": "consistent",
125140
"singleQuote": true,
@@ -130,6 +145,10 @@
130145
"@react-native-community/bob": {
131146
"source": "src",
132147
"output": "lib",
133-
"targets": ["commonjs", "module", "typescript"]
148+
"targets": [
149+
"commonjs",
150+
"module",
151+
"typescript"
152+
]
134153
}
135154
}

src/DropdownButton/index.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { useMemo } from 'react';
2+
import { ActivityIndicator, Image, Text, View } from 'react-native';
3+
import { Images } from '../assets';
4+
import type { DropdownButtonProps } from '../types';
5+
import { styles } from './styles';
6+
7+
export const DropdownButton = ({
8+
selectedOption,
9+
show,
10+
position,
11+
placeholder,
12+
style,
13+
labelStyle,
14+
iconStyle,
15+
placeholderStyle,
16+
loading,
17+
}: DropdownButtonProps) => {
18+
const iconSource = useMemo(() => {
19+
if (position === 'top') {
20+
return show ? Images.chevronDown : Images.chevronUp;
21+
}
22+
return show ? Images.chevronUp : Images.chevronDown;
23+
}, [show, position]);
24+
25+
return (
26+
<View style={[styles.container, style]}>
27+
{selectedOption ? (
28+
<Text style={[styles.label, labelStyle]} numberOfLines={1}>
29+
{selectedOption.label}
30+
</Text>
31+
) : (
32+
<Text style={[styles.placeholder, placeholderStyle]} numberOfLines={1}>
33+
{placeholder}
34+
</Text>
35+
)}
36+
{loading ? (
37+
<ActivityIndicator color="black" size="small" />
38+
) : (
39+
<Image source={iconSource} style={[styles.icon, iconStyle]} />
40+
)}
41+
</View>
42+
);
43+
};

src/DropdownButton/styles.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { StyleSheet } from 'react-native';
2+
3+
export const styles = StyleSheet.create({
4+
container: {
5+
flexDirection: 'row',
6+
alignItems: 'center',
7+
justifyContent: 'space-between',
8+
padding: 7,
9+
borderRadius: 3,
10+
backgroundColor: 'white',
11+
borderWidth: 1,
12+
borderColor: '#f5f5f5',
13+
},
14+
label: {
15+
marginRight: 5,
16+
color: 'black',
17+
},
18+
placeholder: {
19+
color: '#999',
20+
marginRight: 5,
21+
},
22+
icon: {
23+
width: 20,
24+
height: 20,
25+
},
26+
});

src/DropdownLoading/index.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
import { ActivityIndicator, View } from 'react-native';
3+
import { styles } from './styles';
4+
5+
export const DropdownLoading = () => {
6+
return (
7+
<View style={styles.container}>
8+
<ActivityIndicator color="black" />
9+
</View>
10+
);
11+
};

0 commit comments

Comments
 (0)