UNPKG

react-native-tx-modern-datetimepicker

Version:

Fix bugs and improve for lib: HosseinShabani/react-native-modern-datepicker. A customizable calendar, time & month picker for React Native

191 lines (177 loc) 4.97 kB
import React, { createContext, useReducer, useContext, useState } from 'react' import { View, StyleSheet } from 'react-native' import PropTypes from 'prop-types' import { Calendar, SelectMonth, SelectTime } from './components' import { utils } from '../utils' const options = { backgroundColor: '#fff', textHeaderColor: '#222', textDefaultColor: '#222', selectedTextColor: '#fff', mainColor: '#0277BD', textSecondaryColor: '#223344', borderColor: 'rgba(122, 146, 165, 0.1)', headerBorderWidth: 1, defaultFont: 'System', headerFont: 'System', textFontSize: 14, textHeaderFontSize: 16, headerAnimationDistance: 100, daysAnimationDistance: 200, textHeaderStyle: {}, textDayNamesStyle: {}, textDayStyle: {}, textDaySelectedStyle: {}, textTodayStyle: {}, textMonthStyle: {}, textActionTimeStyle: {}, viewDaysNameStyle: {}, viewDaysContainerStyle: {}, viewDayItemStyle: {}, viewDayItemSelectedStyle: {}, viewHeaderItemStyle: {}, viewHeaderContainerStyle: {}, viewButtonActionSelectTimeStyle: {}, viewButtonActionCancelTimeStyle: {}, viewButtonsActionTimeStyle: {}, viewMonthItemSelectedStyle: {}, viewMonthItemStyle: {}, imageArrow: {}, inputYearStyle: {}, } const reducer = (state, action) => { switch (action.type) { case 'set': return { ...state, ...action } case 'toggleMonth': return { ...state, monthOpen: !state.monthOpen } case 'toggleTime': return { ...state, timeOpen: !state.timeOpen } default: throw new Error('Unexpected action') } } const CalendarContext = createContext() const useCalendar = () => { const contextValue = useContext(CalendarContext) return contextValue } const DatePicker = (props) => { const calendarUtils = new utils(props) const contextValue = { ...props, reverse: props.reverse === 'unset' ? false : props.reverse, options: { ...options, ...props.options }, utils: calendarUtils, state: useReducer(reducer, { activeDate: props.current || calendarUtils.getToday(), selectedDate: props.selected ? calendarUtils.getFormated(calendarUtils.getDate(props.selected)) : '', monthOpen: props.mode === 'monthYear', timeOpen: props.mode === 'time', }), } const [minHeight, setMinHeight] = useState(300) const style = styles(contextValue.options) const renderBody = () => { switch (contextValue.mode) { default: case 'dateTimePicker': return ( <React.Fragment> <Calendar /> <SelectMonth /> <SelectTime /> </React.Fragment> ) case 'calendar': return ( <React.Fragment> <Calendar /> <SelectMonth /> </React.Fragment> ) case 'monthYear': return <SelectMonth /> case 'time': return <SelectTime /> } } return ( <CalendarContext.Provider value={contextValue}> <View style={[style.container, { minHeight }, props.style]} onLayout={({ nativeEvent }) => setMinHeight(nativeEvent.layout.width * 0.9 + 55)} > {renderBody()} </View> </CalendarContext.Provider> ) } const styles = (theme) => StyleSheet.create({ container: { backgroundColor: theme.backgroundColor, position: 'relative', width: '100%', overflow: 'hidden', }, }) const optionsShape = { backgroundColor: PropTypes.string, textHeaderColor: PropTypes.string, textDefaultColor: PropTypes.string, selectedTextColor: PropTypes.string, mainColor: PropTypes.string, textSecondaryColor: PropTypes.string, borderColor: PropTypes.string, headerBorderWidth: PropTypes.number, defaultFont: PropTypes.string, headerFont: PropTypes.string, textFontSize: PropTypes.number, textHeaderFontSize: PropTypes.number, headerAnimationDistance: PropTypes.number, daysAnimationDistance: PropTypes.number, } const modeArray = ['dateTimePicker', 'calendar', 'monthYear', 'time'] const minuteIntervalArray = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60] DatePicker.defaultProps = { onSelectedChange: () => null, onMonthYearChange: () => null, onTimeChange: () => null, onDateChange: () => null, current: '', selected: '', minimumDate: '', maximumDate: '', selectorStartingYear: 0, selectorEndingYear: 3000, disableDateChange: false, configs: {}, reverse: 'unset', options: {}, mode: 'dateTimePicker', minuteInterval: 5, style: {}, } DatePicker.propTypes = { onSelectedChange: PropTypes.func, onMonthYearChange: PropTypes.func, onTimeChange: PropTypes.func, onDateChange: PropTypes.func, current: PropTypes.string, selected: PropTypes.string, minimumDate: PropTypes.string, maximumDate: PropTypes.string, selectorStartingYear: PropTypes.number, selectorEndingYear: PropTypes.number, disableDateChange: PropTypes.bool, configs: PropTypes.object, reverse: PropTypes.oneOf([true, false, 'unset']), options: PropTypes.shape(optionsShape), mode: PropTypes.oneOf(modeArray), minuteInterval: PropTypes.oneOf(minuteIntervalArray), style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), } export { DatePicker, CalendarContext, useCalendar }