Smooth and fast cross platform Material Design date picker and time picker for (react-native-paper)
Tested on Android, iOS and the web
Uses the native Date.Intl API's which work out of the box on the web / iOS an on Android with Hermes from RN version 0.66 (automatic day name, month translations without bundle size increase)
Ideally you do this somewhere in your index.js before react-native-paper-dates is used.
Currently we have en/nl/de/pl/pt translations but it's really easy to add one extra since it are only some labels and error messages.
// e.g in your index.jsimport{// en,// nl,// de,// pl,// pt,enGB,registerTranslation,}from'react-native-paper-dates'// registerTranslation('en', en)// registerTranslation('nl', nl)// registerTranslation('pl', pl)// registerTranslation('pt', pt)// registerTranslation('de', de)registerTranslation('en-GB',enGB)
or register your own
Please send a PR with your language to make sure all locales are there next time
import{registerTranslation,}from'react-native-paper-dates'registerTranslation("pl",{save: 'Save',selectSingle: 'Select date',selectMultiple: 'Select dates',selectRange: 'Select period',notAccordingToDateFormat: (inputFormat)=>`Date format must be ${inputFormat}`,mustBeHigherThan: (date)=>`Must be later then ${date}`,mustBeLowerThan: (date)=>`Must be earlier then ${date}`,mustBeBetween: (startDate,endDate)=>`Must be between ${startDate} - ${endDate}`,dateIsDisabled: 'Day is not allowed',previous: 'Previous',next: 'Next',typeInDate: 'Type in date',pickDateFromCalendar: 'Pick date from calendar',close: 'Close',})
Usage
Single date Picker (modal)
import*asReactfrom'react';import{Button}from'react-native-paper';import{DatePickerModal}from'react-native-paper-dates';exportdefaultfunctionReadMeExampleSingle(){const[date,setDate]=React.useState<Date|undefined>(undefined);const[open,setOpen]=React.useState(false);constonDismissSingle=React.useCallback(()=>{setOpen(false);},[setOpen]);constonConfirmSingle=React.useCallback((params)=>{setOpen(false);setDate(params.date);},[setOpen,setDate]);return(<><ButtononPress={()=>setOpen(true)}uppercase={false}mode="outlined">
Pick single date
</Button><DatePickerModallocale="en"mode="single"visible={open}onDismiss={onDismissSingle}date={date}onConfirm={onConfirmSingle}// validRange={{// startDate: new Date(2021, 1, 2), // optional// endDate: new Date(), // optional// disabledDates: [new Date()] // optional// }}// onChange={} // same props as onConfirm but triggered without confirmed by user// saveLabel="Save" // optional// uppercase={false} // optional, default is true// label="Select date" // optional// animationType="slide" // optional, default is 'slide' on ios/android and 'none' on web/></>);}
Range picker (modal)
import*asReactfrom'react';import{Button}from'react-native-paper';import{DatePickerModal}from'react-native-paper-dates';exportdefaultfunctionReadMeExampleRange(){const[range,setRange]=React.useState<{startDate: Date|undefined;endDate: Date|undefined;}>({startDate: undefined,endDate: undefined});const[open,setOpen]=React.useState(false);constonDismiss=React.useCallback(()=>{setOpen(false);},[setOpen]);constonConfirm=React.useCallback(({ startDate, endDate })=>{setOpen(false);setRange({ startDate, endDate });},[setOpen,setRange]);return(<><ButtononPress={()=>setOpen(true)}uppercase={false}mode="outlined">
Pick range
</Button><DatePickerModallocale="en"mode="range"visible={open}onDismiss={onDismiss}startDate={range.startDate}endDate={range.endDate}onConfirm={onConfirm}// validRange={{// startDate: new Date(2021, 1, 2), // optional// endDate: new Date(), // optional// disabledDates: [new Date()] // optional// }}// onChange={} // same props as onConfirm but triggered without confirmed by user// saveLabel="Save" // optional// uppercase={false} // optional, default is true// label="Select period" // optional// startLabel="From" // optional// endLabel="To" // optional// animationType="slide" // optional, default is slide on ios/android and none on web/></>);}
Multiple dates picker
import*asReactfrom'react';import{Button}from'react-native-paper';import{DatePickerModal}from'react-native-paper-dates';exportdefaultfunctionReadMeExampleMultiple(){const[dates,setDates]=React.useState<Date[]|undefined>();const[open,setOpen]=React.useState(false);constonDismiss=React.useCallback(()=>{setOpen(false);},[setOpen]);constonConfirm=React.useCallback((params)=>{setOpen(false);setDates(params.dates);console.log('[on-change-multi]',params);},[]);return(<><ButtononPress={()=>setOpen(true)}uppercase={false}mode="outlined">
Pick multiple dates
</Button><DatePickerModallocale="en"mode="multiple"visible={open}onDismiss={onDismiss}dates={dates}onConfirm={onConfirm}// moreLabel="More"// validRange={{// startDate: new Date(2021, 1, 2), // optional// endDate: new Date(), // optional// disabledDates: [new Date()] // optional// }}// saveLabel="Save" // optional// uppercase={false} // optional, default is true// label="Select period" // optional// startLabel="From" // optional// endLabel="To" // optional// animationType="slide" // optional, default is slide on ios/android and none on web/></>);}
Input date with modal button
exportdefaultfunctionReadMeExampleDatePickerInput(){const[inputDate,setInputDate]=React.useState<Date|undefined>(undefined)return(<><DatePickerInputlocale="en"label="Birthdate"value={inputDate}onChange={(d)=>setInputDate(d)}inputMode="start"// mode="outlined" (see react-native-paper docs)// other react native TextInput props/></>)}
Time picker
import*asReactfrom'react'import{Button}from'react-native-paper'import{TimePickerModal}from'react-native-paper-dates'exportdefaultfunctionTimePickerPage(){const[visible,setVisible]=React.useState(false)constonDismiss=React.useCallback(()=>{setVisible(false)},[setVisible])constonConfirm=React.useCallback(({ hours, minutes })=>{setVisible(false);console.log({ hours, minutes });},[setVisible]);return(<><TimePickerModalvisible={visible}onDismiss={onDismiss}onConfirm={onConfirm}hours={12}// default: current hoursminutes={14}// default: current minuteslabel="Select time"// optional, default 'Select time'uppercase={false}// optional, default is truecancelLabel="Cancel"// optional, default: 'Cancel'confirmLabel="Ok"// optional, default: 'Ok'animationType="fade"// optional, default is 'none'locale="en"// optional, default is automically detected by your system/><ButtononPress={()=>setVisible(true)}>
Pick time
</Button></>)}
This is to prevent the need to press 2 times before save or close button in modal works (1 press for closing keyboard, 1 press for confirm/close)
React Native Issue: #10138
Android Caveats
We recommend Hermes with React Native >= 0.66 you won't need these polyfills at all!
Below React Native 0.66
You will need to add a polyfill for the Intl API on Android if:
You have Hermes enabled and are below React Native 0.66
You have Hermes disabled and you want to support locales outside of en-US and you don't have the org.webkit:android-jsc-intl:+ variant enabled in your app/build.gradle
If using Expo, omit react-native-localize and use expo install expo-localization instead. Read more here.
In your app starting entrypoint e.g. ./index.js or even better use a index.android.js to prevent importing on iOS/web put the following code. (don't forget to import the languages you want to support, in the example only english language is supported)
请发表评论