Skip to content

Commit fb5f6e2

Browse files
committed
refactor(datepicker): refactor datepicker with official ES6 Classes pattern
xgfe#23
1 parent 1430f06 commit fb5f6e2

File tree

5 files changed

+137
-80
lines changed

5 files changed

+137
-80
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Check [index.js](https://github.com/xgfe/react-native-datepicker/blob/master/exa
2020
style={{width: 200}}
2121
date={this.state.date}
2222
mode="date"
23+
placeholder="select date"
2324
format="YYYY-MM-DD"
2425
minDate="2016-05-01"
2526
maxDate="2016-06-01"
@@ -59,6 +60,7 @@ You can check [index.js](https://github.com/xgfe/react-native-datepicker/blob/ma
5960
| duration | 300 | `number` | Specify the animation duration of datepicker.|
6061
| customStyles | - | `number` | The hook of customize datepicker style, same as the native style. `dateTouchBody`, `dateInput`...|
6162
| showIcon | true | `boolean` | Controller whether or not show the icon |
63+
| placeholder | '' | `string` | The placeholder show when this.props.date is falsy |
6264

6365
## Methods
6466

example/index.android.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class example extends Component {
1818
super(props);
1919

2020
this.state = {
21-
date: '2016-05-11',
21+
date: '',
2222
time: '20:00',
2323
datetime: '2016-05-05 20:00',
2424
datetime1: '2016-05-05 20:00'
@@ -35,6 +35,7 @@ class example extends Component {
3535
style={{width: 200}}
3636
date={this.state.date}
3737
mode="date"
38+
placeholder="placeholder"
3839
format="YYYY-MM-DD"
3940
minDate="2016-05-01"
4041
maxDate="2016-06-01"

index.js

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,7 @@ class DatePicker extends Component {
2424
constructor(props) {
2525
super(props);
2626

27-
this.mode = this.props.mode || 'date';
28-
29-
this.format = this.props.format || FORMATS[this.mode];
30-
// component height: 216(DatePickerIOS) + 1(borderTop) + 42(marginTop), IOS only
31-
this.height = 259;
32-
// slide animation duration time, default to 300ms, IOS only
33-
this.duration = this.props.duration || 300;
34-
35-
this.confirmBtnText = this.props.confirmBtnText || '确定';
36-
this.cancelBtnText = this.props.cancelBtnText || '取消';
37-
38-
this.iconSource = this.props.iconSource || require('./date_icon.png');
39-
this.customStyles = this.props.customStyles || {};
40-
41-
// whether or not show the icon
42-
if (typeof this.props.showIcon === 'boolean') {
43-
this.showIcon = this.props.showIcon;
44-
} else {
45-
this.showIcon = true;
46-
}
27+
this.format = this.props.format || FORMATS[this.props.mode];
4728

4829
this.state = {
4930
date: this.getDate(),
@@ -79,8 +60,8 @@ class DatePicker extends Component {
7960
Animated.timing(
8061
this.state.animatedHeight,
8162
{
82-
toValue: this.height,
83-
duration: this.duration
63+
toValue: this.props.height,
64+
duration: this.props.duration
8465
}
8566
).start();
8667
} else {
@@ -120,15 +101,15 @@ class DatePicker extends Component {
120101
this.props.onDateChange(this.getDateStr(this.state.date), this.state.date);
121102
}
122103
}
123-
104+
124105
getTitleElement() {
125106
const {date, placeholder} = this.props;
126107
if (!date && placeholder) {
127-
return (<Text style={[Style.placeholderText, this.customStyles.placeholderText]}>{placeholder}</Text>);
108+
return (<Text style={[Style.placeholderText, this.props.customStyles.placeholderText]}>{placeholder}</Text>);
128109
}
129-
return (<Text style={[Style.dateText, this.customStyles.dateText]}>{this.getDateStr()}</Text>);
110+
return (<Text style={[Style.dateText, this.props.customStyles.dateText]}>{this.getDateStr()}</Text>);
130111
}
131-
112+
132113
onDatePicked({action, year, month, day}) {
133114
if (action !== DatePickerAndroid.dismissedAction) {
134115
this.setState({
@@ -183,13 +164,13 @@ class DatePicker extends Component {
183164
} else {
184165

185166
// 选日期
186-
if (this.mode === 'date') {
167+
if (this.props.mode === 'date') {
187168
DatePickerAndroid.open({
188169
date: this.state.date,
189170
minDate: this.props.minDate && this.getDate(this.props.minDate),
190171
maxDate: this.props.maxDate && this.getDate(this.props.maxDate)
191172
}).then(this.onDatePicked);
192-
} else if (this.mode === 'time') {
173+
} else if (this.props.mode === 'time') {
193174
// 选时间
194175

195176
let timeMoment = Moment(this.state.date);
@@ -199,7 +180,7 @@ class DatePicker extends Component {
199180
minute: timeMoment.minutes(),
200181
is24Hour: !this.format.match(/h|a/)
201182
}).then(this.onTimePicked);
202-
} else if (this.mode === 'datetime') {
183+
} else if (this.props.mode === 'datetime') {
203184
// 选日期和时间
204185

205186
DatePickerAndroid.open({
@@ -214,20 +195,22 @@ class DatePicker extends Component {
214195
}
215196

216197
render() {
198+
let customStyles = this.props.customStyles;
199+
this.format = this.props.format || FORMATS[this.props.mode];
217200

218201
return (
219202
<TouchableHighlight
220203
style={[Style.dateTouch, this.props.style]}
221204
underlayColor={'transparent'}
222205
onPress={this.onPressDate}
223206
>
224-
<View style={[Style.dateTouchBody, this.customStyles.dateTouchBody]}>
225-
<View style={[Style.dateInput, this.customStyles.dateInput, this.state.disabled && Style.disabled]}>
207+
<View style={[Style.dateTouchBody, customStyles.dateTouchBody]}>
208+
<View style={[Style.dateInput, customStyles.dateInput, this.state.disabled && Style.disabled]}>
226209
{this.getTitleElement()}
227210
</View>
228-
{this.showIcon && <Image
229-
style={[Style.dateIcon, this.customStyles.dateIcon]}
230-
source={this.iconSource}
211+
{this.props.showIcon && <Image
212+
style={[Style.dateIcon, customStyles.dateIcon]}
213+
source={this.props.iconSource}
231214
/>}
232215
{Platform.OS === 'ios' && <Modal
233216
transparent={true}
@@ -245,33 +228,33 @@ class DatePicker extends Component {
245228
style={{flex: 1}}
246229
>
247230
<Animated.View
248-
style={[Style.datePickerCon, {height: this.state.animatedHeight}, this.customStyles.datePickerCon]}
231+
style={[Style.datePickerCon, {height: this.state.animatedHeight}, customStyles.datePickerCon]}
249232
>
250233
<DatePickerIOS
251234
date={this.state.date}
252-
mode={this.mode}
235+
mode={this.props.mode}
253236
minimumDate={this.props.minDate && this.getDate(this.props.minDate)}
254237
maximumDate={this.props.maxDate && this.getDate(this.props.maxDate)}
255238
onDateChange={(date) => this.setState({date: date})}
256-
style={[Style.datePicker, this.customStyles.datePicker]}
239+
style={[Style.datePicker, customStyles.datePicker]}
257240
/>
258241
<TouchableHighlight
259242
underlayColor={'transparent'}
260243
onPress={this.onPressCancel}
261-
style={[Style.btnText, Style.btnCancel, this.customStyles.btnCancel]}
244+
style={[Style.btnText, Style.btnCancel, customStyles.btnCancel]}
262245
>
263246
<Text
264-
style={[Style.btnTextText, Style.btnTextCancel, this.customStyles.btnTextCancel]}
247+
style={[Style.btnTextText, Style.btnTextCancel, customStyles.btnTextCancel]}
265248
>
266-
{this.cancelBtnText}
249+
{this.props.cancelBtnText}
267250
</Text>
268251
</TouchableHighlight>
269252
<TouchableHighlight
270253
underlayColor={'transparent'}
271254
onPress={this.onPressConfirm}
272-
style={[Style.btnText, Style.btnConfirm, this.customStyles.btnConfirm]}
255+
style={[Style.btnText, Style.btnConfirm, customStyles.btnConfirm]}
273256
>
274-
<Text style={[Style.btnTextText, this.customStyles.btnTextConfirm]}>{this.confirmBtnText}</Text>
257+
<Text style={[Style.btnTextText, customStyles.btnTextConfirm]}>{this.props.confirmBtnText}</Text>
275258
</TouchableHighlight>
276259
</Animated.View>
277260
</TouchableHighlight>
@@ -283,4 +266,42 @@ class DatePicker extends Component {
283266
}
284267
}
285268

269+
DatePicker.defaultProps = {
270+
mode: 'date',
271+
date: '',
272+
// component height: 216(DatePickerIOS) + 1(borderTop) + 42(marginTop), IOS only
273+
height: 259,
274+
275+
// slide animation duration time, default to 300ms, IOS only
276+
duration: 300,
277+
confirmBtnText: '确定',
278+
cancelBtnText: '取消',
279+
iconSource: require('./date_icon.png'),
280+
customStyles: {},
281+
282+
// whether or not show the icon
283+
showIcon: true,
284+
disabled: false,
285+
placeholder: ''
286+
};
287+
288+
DatePicker.propTypes = {
289+
mode: React.PropTypes.oneOf(['date', 'datetime', 'time']),
290+
date: React.PropTypes.oneOfType([React.PropTypes.string, function(props, propName) {
291+
if (!(props[propName] instanceof Date)) {
292+
return new Error('Should be string or Date');
293+
}
294+
}]),
295+
height: React.PropTypes.number,
296+
duration: React.PropTypes.number,
297+
confirmBtnText: React.PropTypes.string,
298+
cancelBtnText: React.PropTypes.string,
299+
iconSource: React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.object]),
300+
customStyles: React.PropTypes.object,
301+
showIcon: React.PropTypes.bool,
302+
disabled: React.PropTypes.bool,
303+
onDateChange: React.PropTypes.func,
304+
placeholder: React.PropTypes.string
305+
};
306+
286307
export default DatePicker;

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-datepicker",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"description": "react native datePicker component for both Android and IOS, useing DatePikcerAndroid, TimePickerAndroid and DatePickerIOS",
55
"main": "index.js",
66
"scripts": {
@@ -33,14 +33,15 @@
3333
"chai": "^3.5.0",
3434
"coveralls": "^2.11.9",
3535
"cz-conventional-changelog": "^1.1.6",
36-
"enzyme": "^2.3.0",
36+
"enzyme": "^2.4.0",
3737
"istanbul": "^1.0.0-alpha.2",
38+
"jsdom": "^9.4.1",
3839
"mocha": "^2.5.2",
3940
"pre-commit": "^1.1.3",
40-
"react": "15.0.2",
41-
"react-addons-test-utils": "15.0.2",
42-
"react-dom": "15.0.2",
43-
"react-native": "^0.26.0",
41+
"react": "^15.1.0",
42+
"react-addons-test-utils": "^15.1.0",
43+
"react-dom": "^15.1.0",
44+
"react-native": "^0.28.0",
4445
"react-native-mock": "^0.2.3",
4546
"sinon": "^1.17.4"
4647
},

0 commit comments

Comments
 (0)