Skip to content

Commit 909bb9f

Browse files
committed
feat(direction + custom button): Added direction and custom select button
1 parent 55dd032 commit 909bb9f

File tree

2 files changed

+102
-59
lines changed

2 files changed

+102
-59
lines changed

Example/src/index.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,22 @@ export default class Example extends React.PureComponent {
1313
return (
1414
<View style={styles.container}>
1515
<Text style={styles.title}>
16-
React Native Chooser Example
16+
React Native Chooser
1717
</Text>
1818
<View style={styles.cooserContainer}>
1919
<Select
2020
onSelect = {this.onSelect}
21-
defaultText = "Select Me Please"
22-
style = {{borderWidth : 1, borderColor : "green"}}
21+
defaultText = "Choose a name"
22+
style = {{borderWidth : 1, borderColor : "#d3d5d6"}}
2323
textStyle = {{}}
2424
backdropStyle = {{backgroundColor : "#d3d5d6"}}
2525
optionListStyle = {{backgroundColor : "#F5FCFF"}}
26+
animationType={'fade'}
27+
transparent={false}
28+
direction={'fromLeft'}
29+
renderButton={ currentValue => <Text>{'Current Value: ' + currentValue}</Text> }
2630
>
31+
2732
<Option value = {{name : "azhar"}}>Azhar</Option>
2833
<Option value = "johnceena">Johnceena</Option>
2934
<Option value = "undertaker">Undertaker</Option>
@@ -39,6 +44,7 @@ export default class Example extends React.PureComponent {
3944
</View>
4045
);
4146
}
47+
4248
onSelect = e => {
4349
console.log(e)
4450
}

Example/src/react-native-chooser/Select.js

Lines changed: 93 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ import React, {Component} from "react"
22
import {
33
View,
44
Text,
5+
Modal,
6+
Animated,
7+
Dimensions,
58
StyleSheet,
69
TouchableWithoutFeedback,
7-
Modal,
8-
Dimensions
910
} from "react-native"
1011

1112
import OptionList from "./Optionlist"
1213
import Indicator from "./Indicator"
1314

14-
const window = Dimensions.get('window')
15-
15+
var deviceHeight = Dimensions.get('window').height
16+
var deviceWidth = Dimensions.get('window').width
1617

1718
export default class Select extends Component {
1819
static defaultProps = {
@@ -34,20 +35,23 @@ export default class Select extends Component {
3435
indicator : React.PropTypes.string,
3536
indicatorColor : React.PropTypes.string,
3637
indicatorSize : React.PropTypes.number,
37-
indicatorStyle : View.propTypes.style
38+
indicatorStyle : View.propTypes.style,
39+
direction:
3840
}
3941

42+
state={
43+
modalVisible : false,
44+
defaultText : this.props.defaultText,
45+
selected : this.props.selected,
46+
};
4047

41-
constructor(props) {
42-
super(props)
43-
this.selected = this.props.selected
44-
this.state = {
45-
modalVisible : false,
46-
defaultText : this.props.defaultText,
47-
selected : this.props.selected,
48-
}
49-
}
48+
selected = this.props.selected
49+
left = (this.props.direction == 'fromLeft')? new Animated.Value(-deviceWidth): null
50+
right = (this.props.direction == 'fromRight')? new Animated.Value(-deviceWidth): null
51+
top = (this.props.direction == 'fromTop')? new Animated.Value(-deviceHeight): null
52+
bottom = (this.props.direction == 'fromBottom')? new Animated.Value(-deviceHeight): null
5053

54+
5155
onSelect(label, value) {
5256
this.props.onSelect(value)
5357
this.setState({
@@ -56,10 +60,43 @@ export default class Select extends Component {
5660
})
5761
}
5862

59-
onClose() {
60-
this.setState({
61-
modalVisible: false
62-
})
63+
openModal = e => {
64+
this.setState({ modalVisible: true })
65+
switch(this.props.direction){
66+
case 'fromLeft':
67+
Animated.timing(this.left, {toValue: 0, duration: 200}).start()
68+
break
69+
case 'fromRight':
70+
Animated.timing(this.right, {toValue: 0}).start()
71+
break
72+
case 'fromTop':
73+
Animated.timing(this.top, {toValue: 0}).start()
74+
break
75+
case 'fromBottom':
76+
Animated.timing(this.bottom, {toValue: 0}).start()
77+
break
78+
}
79+
}
80+
81+
closeModal = e => {
82+
switch(this.props.direction){
83+
case 'fromLeft':
84+
Animated.timing(this.left, {toValue: -deviceWidth}).start()
85+
setTimeout( () => this.setState({ modalVisible: false }), 500)
86+
break
87+
case 'fromRight':
88+
Animated.timing(this.right, {toValue: -deviceWidth}).start()
89+
setTimeout( () => this.setState({ modalVisible: false }), 500)
90+
break
91+
case 'fromTop':
92+
Animated.timing(this.top, {toValue: -deviceHeight}).start()
93+
setTimeout( () => this.setState({ modalVisible: false }), 500)
94+
break
95+
case 'fromBottom':
96+
Animated.timing(this.bottom, {toValue: -deviceHeight}).start()
97+
setTimeout( () => this.setState({ modalVisible: false }), 500)
98+
break
99+
}
63100
}
64101

65102
render() {
@@ -70,56 +107,51 @@ export default class Select extends Component {
70107

71108
return (
72109
<View>
73-
<TouchableWithoutFeedback onPress = {this.onPress.bind(this)}>
110+
<TouchableWithoutFeedback onPress={this.openModal}>
111+
{
112+
(this.props.renderButton)?
113+
<View>
114+
{this.props.renderButton(this.state.defaultText)}
115+
</View>:
74116
<View style = {[styles.selectBox, style]}>
75117
<View style={styles.selectBoxContent}>
76118
<Text style = {textStyle}>{this.state.defaultText}</Text>
77119
<Indicator direction={indicator} color={indicatorColor} size={indicatorSize} style={indicatorStyle} />
78120
</View>
79121
</View>
122+
}
80123
</TouchableWithoutFeedback>
81124

82125
<Modal
83-
transparent={transparent}
84-
animationType={animationType}
85-
visible={this.state.modalVisible}
86-
onRequestClose={this.onClose.bind(this)}
87-
>
88-
<TouchableWithoutFeedback onPress ={this.onModalPress.bind(this)}>
89-
<View style={[styles.modalOverlay, backdropStyle]}>
90-
<OptionList
91-
onSelect = {this.onSelect.bind(this)}
92-
selectedStyle = {selectedStyle}
93-
selected = {selected}
94-
style = {[optionListStyle]}>
95-
{this.props.children}
96-
</OptionList>
97-
</View>
98-
</TouchableWithoutFeedback>
99-
126+
animationType={"none"}
127+
transparent={true}
128+
visible={this.state.modalVisible}
129+
onRequestClose={this.closeModal}
130+
>
131+
<Animated.View style={[styles.modal,{
132+
left: this.left,
133+
right: this.right,
134+
top: this.top,
135+
bottom: this.bottom,
136+
}]}>
137+
<TouchableWithoutFeedback onPress={this.closeModal}>
138+
<View style={[styles.modalOverlay, backdropStyle]}>
139+
<OptionList
140+
onSelect = {this.onSelect.bind(this)}
141+
selectedStyle = {selectedStyle}
142+
selected = {selected}
143+
style = {[optionListStyle]}
144+
>
145+
{this.props.children}
146+
</OptionList>
147+
</View>
148+
</TouchableWithoutFeedback>
149+
</Animated.View>
100150
</Modal>
151+
101152
</View>
102153
)
103154
}
104-
/*
105-
Fired when user clicks the button
106-
*/
107-
onPress() {
108-
this.setState({
109-
modalVisible : !this.state.modalVisible
110-
})
111-
}
112-
113-
/*
114-
Fires when user clicks on modal. primarily used to close
115-
the select box
116-
*/
117-
118-
onModalPress() {
119-
this.setState({
120-
modalVisible : false
121-
})
122-
}
123155

124156
setSelectedText(text){
125157
this.setState({
@@ -145,6 +177,11 @@ var styles = StyleSheet.create({
145177
justifyContent : "center",
146178
alignItems : "center",
147179
width: window.width,
148-
height: window.height
180+
height: window.height
181+
},
182+
modal:{
183+
position: 'absolute',
184+
height: deviceHeight,
185+
width: deviceWidth,
149186
}
150187
})

0 commit comments

Comments
 (0)