diff --git a/README.md b/README.md
index 68a4a40f..6c68ff39 100644
--- a/README.md
+++ b/README.md
@@ -28,10 +28,9 @@ See this [issue](https://github.com/react-native-datetimepicker/datetimepicker/i
This repository was moved out of the react native community GH organization, in accordance to [this proposal](https://github.com/react-native-community/discussions-and-proposals/issues/176).
The module is still published on `npm` under the old namespace (as documented) but will be published under a new namespace at some point, with a major version bump.
-![CircleCI Status][circle-ci-status]
+[![npm downloads][npm-downloads-badge]][npm-downloads-link]
![Supports Android and iOS][support-badge]
![MIT License][license-badge]
-[![Lean Core Badge][lean-core-badge]][lean-core-issue]
React Native date & time picker component for iOS, Android and Windows (please note Windows is not actively maintained).
@@ -74,28 +73,30 @@ React Native date & time picker component for iOS, Android and Windows (please n
- [Expo users notice](#expo-users-notice)
- [Getting started](#getting-started)
- [Usage](#usage)
- - [React Native Support](#react-native-support)
- [Localization note](#localization-note)
- [Android imperative API](#android-imperative-api)
- [Android styling](#android-styling)
- [Props / params](#component-props--params-of-the-android-imperative-api)
- [`mode` (`optional`)](#mode-optional)
- [`display` (`optional`)](#display-optional)
- - [`design` (`optional`, `Android only`)](#design-optional)
+ - [`design` (`optional`, `Android only`)](#design-optional-android-only)
- [`initialInputMode` (`optional`, `Android only`)](#initialinputmode-optional-android-only)
- [`title` (`optional`, `Android only`)](#title-optional-android-only)
- [`fullscreen` (`optional`, `Android only`)](#fullscreen-optional-android-only)
- [`startOnYearSelection` (`optional`, `Android only`)](#startOnYearSelection-optional-android-only)
- - [`onChange` (`optional`)](#onchange-optional)
+ - [`onValueChange` (`optional`)](#onvaluechange-optional)
+ - [`onDismiss` (`optional`)](#ondismiss-optional)
+ - [`onNeutralButtonPress` (`optional`, `Android only`)](#onneutralbuttonpress-optional-android-only)
+ - [`onChange` (`optional`, `deprecated`)](#onchange-optional-deprecated)
- [`value` (`required`)](#value-required)
- [`maximumDate` (`optional`)](#maximumdate-optional)
- [`minimumDate` (`optional`)](#minimumdate-optional)
- [`timeZoneName` (`optional`, `iOS or Android only`)](#timeZoneName-optional-ios-and-android-only)
- [`timeZoneOffsetInMinutes` (`optional`, `iOS or Android only`)](#timezoneoffsetinminutes-optional-ios-and-android-only)
- - [`timeZoneOffsetInSeconds` (`optional`, `Windows only`)](#timezoneoffsetinsecond-optional-windows-only)
+ - [`timeZoneOffsetInSeconds` (`optional`, `Windows only`)](#timezoneoffsetinseconds-optional-windows-only)
- [`dayOfWeekFormat` (`optional`, `Windows only`)](#dayOfWeekFormat-optional-windows-only)
- [`dateFormat` (`optional`, `Windows only`)](#dateFormat-optional-windows-only)
- - [`firstDayOfWeek` (`optional`, `Windows only`)](#firstDayOfWeek-optional-windows-only)
+ - [`firstDayOfWeek` (`optional`, `Android and Windows only`)](#firstdayofweek-optional-android-and-windows-only)
- [`textColor` (`optional`, `iOS only`)](#textColor-optional-ios-only)
- [`accentColor` (`optional`, `iOS only`)](#accentColor-optional-ios-only)
- [`themeVariant` (`optional`, `iOS only`)](#themevariant-optional-ios-only)
@@ -117,15 +118,12 @@ React Native date & time picker component for iOS, Android and Windows (please n
## Requirements
-- Only Android API level >=21 (Android 5), iOS >= 11 are supported.
-- Tested with Xcode 14.0 and RN 0.72.7. Other configurations are very likely to work as well but have not been tested.
-
-The module supports the [new React Native architecture](https://reactnative.dev/docs/next/the-new-architecture/why) (Fabric rendering of iOS components, and turbomodules on Android). If you are using the new architecture, you will need to use React Native 0.71.4 or higher.
+The module supports the [new React Native architecture](https://reactnative.dev/docs/next/the-new-architecture/why) (Fabric rendering of iOS components, and turbomodules on Android).
## Expo users notice
-This module is part of Expo Managed Workflow - [see docs](https://docs.expo.io/versions/latest/sdk/date-time-picker/). However, Expo SDK in the Managed Workflow may not contain the latest version of the module and therefore, the newest features and bugfixes may not be available in Expo Managed Workflow.
-If you use the Managed Workflow, use the command `expo install @react-native-community/datetimepicker` (not `yarn` or `npm`) to install this module - Expo will automatically install the latest version compatible with your Expo SDK (which may _not_ be the latest version of the module available).
+This module is part of Expo Go - [see docs](https://docs.expo.io/versions/latest/sdk/date-time-picker/). However, Expo Go may not contain the latest version of the module and therefore, the newest features and bugfixes may not be available.
+If you use Expo Go, use the command `npx expo install @react-native-community/datetimepicker` (not `yarn` or `npm`) to install this module - Expo will automatically install the latest version compatible with your Expo SDK (which may _not_ be the latest version of the module available).
If you're using a [Dev Client](https://docs.expo.dev/development/create-development-builds/), rebuild the Dev Client after installing the dependencies.
@@ -145,20 +143,7 @@ yarn add @react-native-community/datetimepicker
Autolinking is not yet implemented on Windows, so [manual installation ](/docs/manual-installation.md) is needed.
-#### RN >= 0.60
-
-If you are using RN >= 0.60, only run `npx pod-install`. Then rebuild your project.
-
-## React Native Support
-
-Check the `react-native` version support table below to find the corresponding `datetimepicker` version to meet support requirements. Maintenance is only provided for last 3 stable react-native versions.
-
-| react-native version | version |
-| -------------------- | ------- |
-| 0.73.0+ | 7.6.3+ |
-| <=0.72.0 | <=7.6.2 |
-| 0.70.0+ | 7.0.1+ |
-| <0.70.0 | <=7.0.0 |
+On iOS, run `npx pod-install` after installing. Then rebuild your project.
## Usage
@@ -181,15 +166,10 @@ Read more about the motivation in [Android imperative API](#android-imperative-a
export const App = () => {
const [date, setDate] = useState(new Date(1598051730000));
- const onChange = (event, selectedDate) => {
- const currentDate = selectedDate;
- setDate(currentDate);
- };
-
const showMode = (currentMode) => {
DateTimePickerAndroid.open({
value: date,
- onChange,
+ onValueChange: (event, selectedDate) => setDate(selectedDate),
mode: currentMode,
is24Hour: true,
});
@@ -221,12 +201,6 @@ export const App = () => {
const [mode, setMode] = useState('date');
const [show, setShow] = useState(false);
- const onChange = (event, selectedDate) => {
- const currentDate = selectedDate;
- setShow(false);
- setDate(currentDate);
- };
-
const showMode = (currentMode) => {
setShow(true);
setMode(currentMode);
@@ -251,7 +225,8 @@ export const App = () => {
value={date}
mode={mode}
is24Hour={true}
- onChange={onChange}
+ onValueChange={(event, selectedDate) => setDate(selectedDate)}
+ onDismiss={() => setShow(false)}
/>
)}
@@ -358,7 +333,36 @@ List of possible values
```
-#### `onChange` (`optional`)
+#### `onValueChange` (`optional`)
+
+Called when the user selects a date or time. Receives an `event` with `nativeEvent: { timestamp, utcOffset }` and the selected `Date`.
+
+```js
+ setDate(date)} />
+```
+
+#### `onDismiss` (`optional`)
+
+Called when the picker is dismissed without selecting a value. Receives no arguments.
+
+```js
+ setShow(false)} />
+```
+
+#### `onNeutralButtonPress` (`optional`, `Android only`)
+
+Called when the neutral button is pressed. Receives no arguments. See [`neutralButton`](#neutralButton-optional-android-only).
+
+```js
+ clearDate()}
+/>
+```
+
+#### `onChange` (`optional`, `deprecated`)
+
+> **Deprecated:** Use `onValueChange`, `onDismiss`, and `onNeutralButtonPress` instead. If the new specific listeners are provided, they take precedence over `onChange` for their respective event types.
Date change handler.
@@ -554,7 +558,7 @@ Set the positive button label and text color.
#### `neutralButton` (`optional`, `Android only`)
Allows displaying neutral button on picker dialog.
-Pressing button can be observed in onChange handler as `event.type === 'neutralButtonPressed'`
+Pressing the button can be observed via the [`onNeutralButtonPress`](#onneutralbuttonpress-optional-android-only) callback.
```js
@@ -643,9 +647,7 @@ Please see [manual-installation.md](/docs/manual-installation.md)
This project is tested with BrowserStack.
-[circle-ci-badge]: https://img.shields.io/circleci/project/github/react-native-community/datetimepicker/master.svg?style=flat-square
-[circle-ci-status]: https://circleci.com/gh/react-native-datetimepicker/datetimepicker.svg?style=svg
+[npm-downloads-badge]: https://img.shields.io/npm/dm/@react-native-community/datetimepicker.svg?style=flat-square
+[npm-downloads-link]: https://www.npmjs.com/package/@react-native-community/datetimepicker
[support-badge]: https://img.shields.io/badge/platforms-android%20%7C%20ios%20%7C%20windows-lightgrey.svg?style=flat-square
-[license-badge]: https://img.shields.io/npm/l/@react-native-community/slider.svg?style=flat-square
-[lean-core-badge]: https://img.shields.io/badge/Lean%20Core-Extracted-brightgreen.svg?style=flat-square
-[lean-core-issue]: https://github.com/facebook/react-native/issues/23313
+[license-badge]: https://img.shields.io/npm/l/@react-native-community/datetimepicker.svg?style=flat-square
diff --git a/android/src/main/java/com/reactcommunity/rndatetimepicker/RNDateTimePickerPackage.java b/android/src/main/java/com/reactcommunity/rndatetimepicker/RNDateTimePickerPackage.java
index 7b9274b9..bfab8277 100644
--- a/android/src/main/java/com/reactcommunity/rndatetimepicker/RNDateTimePickerPackage.java
+++ b/android/src/main/java/com/reactcommunity/rndatetimepicker/RNDateTimePickerPackage.java
@@ -1,6 +1,7 @@
package com.reactcommunity.rndatetimepicker;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.react.BaseReactPackage;
@@ -15,7 +16,7 @@
public class RNDateTimePickerPackage extends BaseReactPackage {
@Nullable
@Override
- public NativeModule getModule(String name, ReactApplicationContext reactContext) {
+ public NativeModule getModule(String name, @NonNull ReactApplicationContext reactContext) {
if (name.equals(DatePickerModule.NAME)) {
return new DatePickerModule(reactContext);
} else if (name.equals(TimePickerModule.NAME)) {
@@ -29,6 +30,7 @@ public NativeModule getModule(String name, ReactApplicationContext reactContext)
}
}
+ @NonNull
@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
return () -> {
@@ -61,7 +63,6 @@ public ReactModuleInfoProvider getReactModuleInfoProvider() {
MaterialDatePickerModule.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
- false, // hasConstants
false, // isCxxModule
isTurboModule // isTurboModule
));
@@ -72,7 +73,6 @@ public ReactModuleInfoProvider getReactModuleInfoProvider() {
MaterialTimePickerModule.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
- false, // hasConstants
false, // isCxxModule
isTurboModule // isTurboModule
));
diff --git a/example/App.js b/example/App.js
index b6346e51..f984c6ed 100644
--- a/example/App.js
+++ b/example/App.js
@@ -138,29 +138,31 @@ export const App = () => {
setDate(undefined);
};
- const onChange = (event, selectedDate) => {
+ const onValueChange = (event, selectedDate) => {
if (Platform.OS === 'android') {
setShow(false);
}
- if (event.type === 'dismissed') {
- Alert.alert(
- 'picker was dismissed',
- undefined,
- [
- {
- text: 'great',
- },
- ],
- {cancelable: true},
- );
- return;
- }
+ setDate(selectedDate);
+ };
- if (event.type === 'neutralButtonPressed') {
- setDate(new Date(0));
- } else {
- setDate(selectedDate);
+ const onDismiss = () => {
+ if (Platform.OS === 'android') {
+ setShow(false);
}
+ Alert.alert(
+ 'picker was dismissed',
+ undefined,
+ [
+ {
+ text: 'great',
+ },
+ ],
+ {cancelable: true},
+ );
+ };
+
+ const onNeutralButtonPress = () => {
+ setDate(new Date(0));
};
const onTimeChange = (event: any, newTime?: Date) => {
@@ -523,7 +525,9 @@ export const App = () => {
is24Hour
locale="en-US"
display={display}
- onChange={onChange}
+ onValueChange={onValueChange}
+ onDismiss={onDismiss}
+ onNeutralButtonPress={onNeutralButtonPress}
textColor={textColor || undefined}
accentColor={accentColor || undefined}
neutralButton={{label: neutralButtonLabel}}
@@ -621,7 +625,7 @@ export const App = () => {
{
mode="time"
value={time}
style={{width: 300, opacity: 1, height: 30, marginTop: 50}}
- onChange={onTimeChange}
+ onValueChange={onTimeChange}
is24Hour={is24Hours}
minuteInterval={interval}
/>
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index b75436ef..68a3bb83 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -1810,7 +1810,7 @@ PODS:
- React-Core
- React-jsi
- ReactTestApp-Resources (1.0.0-dev)
- - RNDateTimePicker (8.6.0):
+ - RNDateTimePicker (9.0.0):
- hermes-engine
- RCTRequired
- RCTTypeSafety
@@ -2176,7 +2176,7 @@ SPEC CHECKSUMS:
ReactNativeHost: 147a222a7c577801639023140b694160987738ef
ReactTestApp-DevSupport: 0e7676c00b33b0545e72d89ea09f990d737db6d3
ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf
- RNDateTimePicker: 9c0a849bbe1c256f0854fea255734b715f5ea876
+ RNDateTimePicker: a8b45651bfa11872964f1439d1cae9a1712dc108
RNLocalize: 390c6e0c4061855a7bd7a91e21dd6a317b45c46c
Yoga: 1f66b0bb07f6c5f0199562b772bfb2ac54cad91a
diff --git a/src/DateTimePickerAndroid.android.js b/src/DateTimePickerAndroid.android.js
index 8ed335b8..6f5bb3d2 100644
--- a/src/DateTimePickerAndroid.android.js
+++ b/src/DateTimePickerAndroid.android.js
@@ -25,6 +25,7 @@ import {
createNeutralEvtParams,
} from './eventCreators';
import {processColor} from 'react-native';
+import {warnIfOnChangeIsUsed} from './utils';
function open(props: AndroidNativeProps) {
const {
@@ -38,6 +39,9 @@ function open(props: AndroidNativeProps) {
timeZoneOffsetInMinutes,
timeZoneName,
onChange,
+ onValueChange,
+ onDismiss,
+ onNeutralButtonPress,
onError,
positiveButton,
negativeButton,
@@ -51,6 +55,7 @@ function open(props: AndroidNativeProps) {
startOnYearSelection,
} = props;
validateAndroidProps(props);
+ warnIfOnChangeIsUsed(onChange);
invariant(originalValue, 'A date or time must be specified as `value` prop.');
const valueTimestamp = originalValue.getTime();
@@ -99,20 +104,32 @@ function open(props: AndroidNativeProps) {
case DATE_SET_ACTION:
case TIME_SET_ACTION: {
const date = new Date(timestamp);
- const [event] = createDateTimeSetEvtParams(date, utcOffset);
- onChange?.(event, date);
+ if (onValueChange) {
+ onValueChange({nativeEvent: {timestamp, utcOffset}}, date);
+ } else {
+ const [event] = createDateTimeSetEvtParams(date, utcOffset);
+ onChange?.(event, date);
+ }
break;
}
case NEUTRAL_BUTTON_ACTION: {
- const [event] = createNeutralEvtParams(originalValue, utcOffset);
- onChange?.(event, originalValue);
+ if (onNeutralButtonPress) {
+ onNeutralButtonPress();
+ } else {
+ const [event] = createNeutralEvtParams(originalValue, utcOffset);
+ onChange?.(event, originalValue);
+ }
break;
}
case DISMISS_ACTION:
default: {
- const [event] = createDismissEvtParams(originalValue, utcOffset);
- onChange?.(event, originalValue);
+ if (onDismiss) {
+ onDismiss();
+ } else {
+ const [event] = createDismissEvtParams(originalValue, utcOffset);
+ onChange?.(event, originalValue);
+ }
break;
}
}
diff --git a/src/datetimepicker.android.js b/src/datetimepicker.android.js
index 3bf75f0b..8bea7d26 100644
--- a/src/datetimepicker.android.js
+++ b/src/datetimepicker.android.js
@@ -18,10 +18,13 @@ export default function RNDateTimePickerAndroid(
display = ANDROID_DISPLAY.default,
value,
onChange,
+ onValueChange,
is24Hour,
minimumDate,
maximumDate,
minuteInterval,
+ onDismiss,
+ onNeutralButtonPress,
onError,
timeZoneOffsetInMinutes,
timeZoneName,
@@ -56,6 +59,9 @@ export default function RNDateTimePickerAndroid(
minuteInterval,
timeZoneOffsetInMinutes,
timeZoneName,
+ onValueChange,
+ onDismiss,
+ onNeutralButtonPress,
onError,
onChange,
positiveButton,
@@ -75,7 +81,14 @@ export default function RNDateTimePickerAndroid(
// as an alternative, use the DateTimePickerAndroid whose reason for existence is described in
// https://github.com/react-native-datetimepicker/datetimepicker/pull/327#issuecomment-723160992
// eslint-disable-next-line react-hooks/exhaustive-deps
- [onChange, valueTimestamp, mode],
+ [
+ onChange,
+ onValueChange,
+ onDismiss,
+ onNeutralButtonPress,
+ valueTimestamp,
+ mode,
+ ],
);
return null;
diff --git a/src/datetimepicker.ios.js b/src/datetimepicker.ios.js
index d8819f76..2925c161 100644
--- a/src/datetimepicker.ios.js
+++ b/src/datetimepicker.ios.js
@@ -10,7 +10,11 @@
* @flow strict-local
*/
import RNDateTimePicker from './picker';
-import {dateToMilliseconds, sharedPropsValidation} from './utils';
+import {
+ dateToMilliseconds,
+ sharedPropsValidation,
+ warnIfOnChangeIsUsed,
+} from './utils';
import {
IOS_DISPLAY,
EVENT_TYPE_SET,
@@ -55,41 +59,56 @@ export default function Picker({
accentColor,
themeVariant,
onChange,
+ onValueChange,
+ onDismiss: onDismissProp,
mode = IOS_MODE.date,
display: providedDisplay = IOS_DISPLAY.default,
// $FlowFixMe[incompatible-type]
disabled = false,
...other
}: IOSNativeProps): React.Node {
- sharedPropsValidation({value, timeZoneOffsetInMinutes, timeZoneName, minimumDate, maximumDate});
+ sharedPropsValidation({
+ value,
+ timeZoneOffsetInMinutes,
+ timeZoneName,
+ minimumDate,
+ maximumDate,
+ });
+ warnIfOnChangeIsUsed(onChange);
const display = getDisplaySafe(providedDisplay);
const _onChange = (event: NativeEventIOS) => {
const timestamp = event.nativeEvent.timestamp;
- const unifiedEvent: DateTimePickerEvent = {
- ...event,
- type: EVENT_TYPE_SET,
- };
-
const date = timestamp !== undefined ? new Date(timestamp) : undefined;
- onChange && onChange(unifiedEvent, date);
+ if (onValueChange && date) {
+ onValueChange(event, date);
+ } else if (onChange) {
+ const unifiedEvent: DateTimePickerEvent = {
+ ...event,
+ type: EVENT_TYPE_SET,
+ };
+ onChange(unifiedEvent, date);
+ }
};
const onDismiss = () => {
- // TODO introduce separate onDismissed event listener
- onChange &&
- onChange(
- {
- type: EVENT_TYPE_DISMISSED,
- nativeEvent: {
- timestamp: value.getTime(),
- utcOffset: 0, // TODO vonovak - the dismiss event should not carry any date information
+ if (onDismissProp) {
+ onDismissProp();
+ } else {
+ onChange &&
+ onChange(
+ {
+ type: EVENT_TYPE_DISMISSED,
+ nativeEvent: {
+ timestamp: value.getTime(),
+ utcOffset: 0,
+ },
},
- },
- value,
- );
+ value,
+ );
+ }
};
return (
diff --git a/src/datetimepicker.windows.js b/src/datetimepicker.windows.js
index 92b10ec1..ab14c93d 100644
--- a/src/datetimepicker.windows.js
+++ b/src/datetimepicker.windows.js
@@ -6,10 +6,7 @@
*/
'use strict';
-import {
- requireNativeComponent,
- StyleSheet,
-} from 'react-native';
+import {requireNativeComponent, StyleSheet} from 'react-native';
import type {
WindowsNativeProps,
WindowsDatePickerChangeEvent,
@@ -17,7 +14,7 @@ import type {
} from './types';
import * as React from 'react';
import {EVENT_TYPE_SET, WINDOWS_MODE} from './constants';
-import {sharedPropsValidation} from './utils';
+import {sharedPropsValidation, warnIfOnChangeIsUsed} from './utils';
const styles = StyleSheet.create({
rnDatePicker: {
@@ -38,6 +35,7 @@ export default function RNDateTimePickerQWE(
props: WindowsNativeProps,
): React.Node {
sharedPropsValidation({value: props?.value});
+ warnIfOnChangeIsUsed(props.onChange);
const localProps = {
accessibilityLabel: props.accessibilityLabel,
@@ -53,18 +51,23 @@ export default function RNDateTimePickerQWE(
};
const _onChange = (event: WindowsDatePickerChangeEvent) => {
- const {onChange} = props;
- const unifiedEvent: DateTimePickerEvent = {
- ...event,
- nativeEvent: {
- ...event.nativeEvent,
- timestamp: event.nativeEvent.newDate,
- utcOffset: 0,
- },
- type: EVENT_TYPE_SET,
- };
+ const {onChange, onValueChange} = props;
+ const date = new Date(event.nativeEvent.newDate);
- onChange && onChange(unifiedEvent, new Date(event.nativeEvent.newDate));
+ if (onValueChange) {
+ onValueChange({nativeEvent: {timestamp: event.nativeEvent.newDate, utcOffset: 0}}, date);
+ } else if (onChange) {
+ const unifiedEvent: DateTimePickerEvent = {
+ ...event,
+ nativeEvent: {
+ ...event.nativeEvent,
+ timestamp: event.nativeEvent.newDate,
+ utcOffset: 0,
+ },
+ type: EVENT_TYPE_SET,
+ };
+ onChange(unifiedEvent, date);
+ }
};
// $FlowFixMe[recursive-definition]
diff --git a/src/index.d.ts b/src/index.d.ts
index 451f3e63..423a7fab 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -26,6 +26,13 @@ export type DateTimePickerEvent = {
};
};
+export type DateTimePickerChangeEvent = {
+ nativeEvent: {
+ timestamp: number;
+ utcOffset: number;
+ };
+};
+
type BaseOptions = {
/**
* The currently selected date.
@@ -33,12 +40,28 @@ type BaseOptions = {
value: Date;
/**
- * Date change handler.
+ * @deprecated Use onValueChange, onDismiss, and onNeutralButtonPress instead.
*
- * This is called when the user changes the date or time in the UI.
- * The first argument is an Event, the second a selected Date.
+ * Called when the user changes the date/time, dismisses the picker,
+ * or presses the neutral button. The event type is encoded in event.type.
+ * If the new specific listeners are provided, they take precedence.
*/
onChange?: (event: DateTimePickerEvent, date?: Date) => void;
+
+ /**
+ * Called when the user selects a date or time.
+ */
+ onValueChange?: (event: DateTimePickerChangeEvent, date: Date) => void;
+
+ /**
+ * Called when the picker is dismissed without selecting a value.
+ */
+ onDismiss?: () => void;
+
+ /**
+ * Called when the neutral button is pressed (Android only).
+ */
+ onNeutralButtonPress?: () => void;
};
type DateOptions = BaseOptions & {
diff --git a/src/types.js b/src/types.js
index 94c9cb22..81847c04 100644
--- a/src/types.js
+++ b/src/types.js
@@ -43,6 +43,15 @@ export type DateTimePickerEvent = {
...
};
+export type DateTimePickerChangeEvent = {
+ nativeEvent: $ReadOnly<{
+ timestamp: number,
+ utcOffset: number,
+ ...
+ }>,
+ ...
+};
+
type BaseOptions = {|
/**
* The currently selected date.
@@ -50,13 +59,28 @@ type BaseOptions = {|
value: Date,
/**
- * change handler.
+ * @deprecated Use onValueChange, onDismiss, and onNeutralButtonPress instead.
*
- * This is called when the user changes the date or time in the UI.
- * Or when they clear / dismiss the dialog.
- * The first argument is an Event, the second a selected Date.
+ * Called when the user changes the date/time, dismisses the picker,
+ * or presses the neutral button. The event type is encoded in event.type.
+ * If the new specific listeners are provided, they take precedence.
*/
onChange?: ?(event: DateTimePickerEvent, date?: Date) => void,
+
+ /**
+ * Called when the user selects a date or time.
+ */
+ onValueChange?: ?(event: DateTimePickerChangeEvent, date: Date) => void,
+
+ /**
+ * Called when the picker is dismissed without selecting a value.
+ */
+ onDismiss?: ?() => void,
+
+ /**
+ * Called when the neutral button is pressed (Android only).
+ */
+ onNeutralButtonPress?: ?() => void,
|};
type DateOptions = {|
diff --git a/src/utils.js b/src/utils.js
index b7775256..96e4b21c 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -67,3 +67,13 @@ export function sharedPropsValidation({
);
}
}
+
+let hasWarnedOnChange = false;
+export function warnIfOnChangeIsUsed(onChange: ?Function) {
+ if (__DEV__ && onChange && !hasWarnedOnChange) {
+ hasWarnedOnChange = true;
+ console.warn(
+ 'DateTimePicker: `onChange` is deprecated. Use `onValueChange`, `onDismiss`, and `onNeutralButtonPress` instead.',
+ );
+ }
+}