DatePickerIOS.ios.js
4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule DatePickerIOS
* @flow
*
* This is a controlled component version of RCTDatePickerIOS
*/
'use strict';
const NativeMethodsMixin = require('NativeMethodsMixin');
const React = require('React');
const PropTypes = require('prop-types');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
const createReactClass = require('create-react-class');
const requireNativeComponent = require('requireNativeComponent');
type DefaultProps = {
mode: 'date' | 'time' | 'datetime',
};
type Event = Object;
/**
* Use `DatePickerIOS` to render a date/time picker (selector) on iOS. This is
* a controlled component, so you must hook in to the `onDateChange` callback
* and update the `date` prop in order for the component to update, otherwise
* the user's change will be reverted immediately to reflect `props.date` as the
* source of truth.
*/
const DatePickerIOS = createReactClass({
displayName: 'DatePickerIOS',
// TOOD: Put a better type for _picker
_picker: (undefined: ?$FlowFixMe),
mixins: [NativeMethodsMixin],
propTypes: {
...ViewPropTypes,
/**
* The currently selected date.
*/
date: PropTypes.instanceOf(Date).isRequired,
/**
* Date change handler.
*
* This is called when the user changes the date or time in the UI.
* The first and only argument is a Date object representing the new
* date and time.
*/
onDateChange: PropTypes.func.isRequired,
/**
* Maximum date.
*
* Restricts the range of possible date/time values.
*/
maximumDate: PropTypes.instanceOf(Date),
/**
* Minimum date.
*
* Restricts the range of possible date/time values.
*/
minimumDate: PropTypes.instanceOf(Date),
/**
* The date picker mode.
*/
mode: PropTypes.oneOf(['date', 'time', 'datetime']),
/**
* The date picker locale.
*/
locale: PropTypes.string,
/**
* The interval at which minutes can be selected.
*/
minuteInterval: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]),
/**
* Timezone offset in minutes.
*
* By default, the date picker will use the device's timezone. With this
* parameter, it is possible to force a certain timezone offset. For
* instance, to show times in Pacific Standard Time, pass -7 * 60.
*/
timeZoneOffsetInMinutes: PropTypes.number,
},
getDefaultProps: function(): DefaultProps {
return {
mode: 'datetime',
};
},
_onChange: function(event: Event) {
const nativeTimeStamp = event.nativeEvent.timestamp;
this.props.onDateChange && this.props.onDateChange(
new Date(nativeTimeStamp)
);
// $FlowFixMe(>=0.41.0)
this.props.onChange && this.props.onChange(event);
// We expect the onChange* handlers to be in charge of updating our `date`
// prop. That way they can also disallow/undo/mutate the selection of
// certain values. In other words, the embedder of this component should
// be the source of truth, not the native component.
const propsTimeStamp = this.props.date.getTime();
if (this._picker && nativeTimeStamp !== propsTimeStamp) {
this._picker.setNativeProps({
date: propsTimeStamp,
});
}
},
render: function() {
const props = this.props;
return (
<View style={props.style}>
<RCTDatePickerIOS
ref={ picker => { this._picker = picker; } }
style={styles.datePickerIOS}
date={props.date.getTime()}
locale={props.locale ? props.locale : undefined}
maximumDate={
props.maximumDate ? props.maximumDate.getTime() : undefined
}
minimumDate={
props.minimumDate ? props.minimumDate.getTime() : undefined
}
mode={props.mode}
minuteInterval={props.minuteInterval}
timeZoneOffsetInMinutes={props.timeZoneOffsetInMinutes}
onChange={this._onChange}
onStartShouldSetResponder={() => true}
onResponderTerminationRequest={() => false}
/>
</View>
);
}
});
const styles = StyleSheet.create({
datePickerIOS: {
height: 216,
},
});
const RCTDatePickerIOS = requireNativeComponent('RCTDatePicker', {
propTypes: {
...DatePickerIOS.propTypes,
date: PropTypes.number,
locale: PropTypes.string,
minimumDate: PropTypes.number,
maximumDate: PropTypes.number,
onDateChange: () => null,
onChange: PropTypes.func,
}
});
module.exports = DatePickerIOS;