diff --git a/DatePickerAndroid.js b/DatePickerAndroid.js new file mode 100644 index 0000000..69507fd --- /dev/null +++ b/DatePickerAndroid.js @@ -0,0 +1,48 @@ +import { + Platform, + NativeModules, + NativeAppEventEmitter, + Text, + requireNativeComponent, + ViewPropTypes, + StyleSheet, + DatePickerIOS, +} from 'react-native'; +import React, { Component } from 'react' +import PropTypes from 'prop-types'; +import { DatePicker } from 'react-native-date-picker-x'; + +const NativeDatePicker = requireNativeComponent(`DatePickerManager`, DatePickerAndroid, { nativeOnly: { onChange: true } }); + +class DatePickerAndroid extends React.Component { + + static defaultProps = { + mode: 'datetime', + minuteInterval: 1, + }; + + _onChange = e => this.props.onDateChange(new Date(parseInt(e.nativeEvent.date))); + _maximumDate = () => this.props.maximumDate && this.props.maximumDate.getTime(); + _minimumDate = () => this.props.minimumDate && this.props.minimumDate.getTime(); + render = () => ( + + ) +} + +const styles = StyleSheet.create({ + picker: { + width: 310, + height: 180, + } +}) + +DatePickerAndroid.propTypes = DatePickerIOS.propTypes; + +export default DatePickerAndroid; diff --git a/DatePickerIOS.js b/DatePickerIOS.js new file mode 100644 index 0000000..a76e86b --- /dev/null +++ b/DatePickerIOS.js @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * + * This is a controlled component version of RCTDatePickerIOS + * + * @format + * @flow + */ + +'use strict'; + +import React from 'react'; +import { StyleSheet, View, requireNativeComponent } from 'react-native'; +const invariant = require('fbjs/lib/invariant'); + +import type {ViewProps} from 'ViewPropTypes'; + +const RCTDatePickerIOS = requireNativeComponent('DatePickerX'); + +type Event = Object; + +type Props = $ReadOnly<{| + ...ViewProps, + + /** + * The currently selected date. + */ + date?: ?Date, + + /** + * Provides an initial value that will change when the user starts selecting + * a date. It is useful for simple use-cases where you do not want to deal + * with listening to events and updating the date prop to keep the + * controlled state in sync. The controlled state has known bugs which + * causes it to go out of sync with native. The initialDate prop is intended + * to allow you to have native be source of truth. + */ + initialDate?: ?Date, + + /** + * The date picker locale. + */ + locale?: ?string, + + /** + * Maximum date. + * + * Restricts the range of possible date/time values. + */ + maximumDate?: ?Date, + + /** + * Minimum date. + * + * Restricts the range of possible date/time values. + */ + minimumDate?: ?Date, + + /** + * The interval at which minutes can be selected. + */ + minuteInterval?: ?(1 | 2 | 3 | 4 | 5 | 6 | 10 | 12 | 15 | 20 | 30), + + /** + * The date picker mode. + */ + mode?: ?('date' | 'time' | 'datetime'), + + /** + * Date change handler. + * + * This is called when the user changes the date or time in the UI. + * The first and only argument is an Event. For getting the date the picker + * was changed to, use onDateChange instead. + */ + onChange?: ?(event: Event) => void, + + /** + * 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: (date: Date) => void, + + /** + * 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?: ?number, +|}>; + +/** + * 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. + */ +export default class DatePickerIOS extends React.Component { + static DefaultProps = { + mode: 'datetime', + }; + + // $FlowFixMe How to type a native component to be able to call setNativeProps + _picker: ?React.ElementRef = null; + + componentDidUpdate() { + if (this.props.date) { + const propsTimeStamp = this.props.date.getTime(); + if (this._picker) { + this._picker.setNativeProps({ + date: propsTimeStamp, + }); + } + } + } + + _onChange = (event: Event) => { + const nativeTimeStamp = event.nativeEvent.timestamp; + this.props.onDateChange && + this.props.onDateChange(new Date(nativeTimeStamp)); + this.props.onChange && this.props.onChange(event); + }; + + render() { + const props = this.props; + invariant( + props.date || props.initialDate, + 'A selected date or initial date should be specified.', + ); + return ( + + { + this._picker = picker; + }} + style={styles.datePickerIOS} + date={ + props.date + ? props.date.getTime() + : props.initialDate + ? props.initialDate.getTime() + : undefined + } + 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} + textColor={props.textColor} + /> + + ); + } +} + +const styles = StyleSheet.create({ + datePickerIOS: { + height: 216, + width: 310, + }, +}); diff --git a/README.md b/README.md index ec4c0c5..ae0b946 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ export default class App extends Component { minuteInterval={5} minimumDate={today} maximumDate={tomorrow} + textColor={'#ffffff'} + fadeToColor={'#000000'} /> } @@ -63,7 +65,7 @@ The goal with React Native Date Picker is to make a cross platform variant of [D -## TODO +## Roadmap - [x] Mode: datetime - [x] Locale support. (AM/PM, 12h/24h toggled and strings translated) - [x] Replace todays date with the string "Today" (considering locale) @@ -72,8 +74,9 @@ The goal with React Native Date Picker is to make a cross platform variant of [D - [x] Support maximumDate/minimumDate. - [x] Minute interval prop. - [x] Mode: time +- [x] Colored background support. +- [x] Colored text support. - [ ] Mode: date -- [ ] Colored background support. - [ ] Align text to right.