@tchesa/react-native-modern-datepicker
Version:
A customizable calendar, time & month picker for React Native (including Persian Jalaali calendar & locale)
183 lines • 6.4 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
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 defaultOptions = {
backgroundColor: '#fff',
textHeaderColor: '#212c35',
textDefaultColor: '#2d4150',
selectedTextColor: '#fff',
mainColor: '#61dafb',
textSecondaryColor: '#7a92a5',
borderColor: 'rgba(122, 146, 165, 0.1)',
defaultFont: 'System',
headerFont: 'System',
textFontSize: 15,
textHeaderFontSize: 17,
headerAnimationDistance: 100,
daysAnimationDistance: 200,
};
const reducer = (state, action) => {
switch (action.type) {
case 'set':
return Object.assign(Object.assign({}, state), action);
case 'toggleMonth':
return Object.assign(Object.assign({}, state), { monthOpen: !state.monthOpen });
case 'toggleTime':
return Object.assign(Object.assign({}, state), { timeOpen: !state.timeOpen });
default:
throw new Error('Unexpected action');
}
};
const CalendarContext = createContext({
mode: 'datepicker',
reverse: false,
options: defaultOptions,
utils: new Utils({
minimumDate: '',
maximumDate: '',
isGregorian: true,
configs: {},
reverse: false,
mode: 'datepicker',
}),
state: [
{
activeDate: '',
selectedDate: '',
monthOpen: false,
timeOpen: false,
},
() => null,
],
disableDateChange: false,
isGregorian: false,
minimumDate: '',
maximumDate: '',
selectorStartingYear: 0,
selectorEndingYear: 0,
minuteInterval: 5,
});
const useCalendar = () => {
const contextValue = useContext(CalendarContext);
return contextValue;
};
const DatePicker = ({ onSelectedChange, onMonthYearChange, onTimeChange, onDateChange, current = '', selected = '', minimumDate = '', maximumDate = '', selectorStartingYear = 0, selectorEndingYear = 3000, disableDateChange = false, isGregorian = true, configs, reverse = 'unset', options, mode = 'datepicker', minuteInterval = 5, style, }) => {
const calendarUtils = new Utils({
minimumDate,
maximumDate,
isGregorian,
configs,
reverse,
mode,
});
const contextValue = {
// ...props,
onSelectedChange,
onDateChange,
mode,
reverse: reverse === 'unset' ? !isGregorian : reverse,
options: Object.assign(Object.assign({}, defaultOptions), options),
utils: calendarUtils,
disableDateChange,
minimumDate,
maximumDate,
isGregorian,
selectorStartingYear,
selectorEndingYear,
onMonthYearChange,
minuteInterval,
onTimeChange,
state: useReducer(reducer, {
activeDate: current || calendarUtils.getToday(),
selectedDate: selected ? calendarUtils.getFormated(calendarUtils.getDate(selected)) : '',
monthOpen: mode === 'monthYear',
timeOpen: mode === 'time',
}),
};
const [minHeight, setMinHeight] = useState(300);
const themedStyles = styles(contextValue.options);
const renderBody = () => {
switch (contextValue.mode) {
default:
case 'datepicker':
return (_jsxs(React.Fragment, { children: [_jsx(Calendar, {}), _jsx(SelectMonth, {}), _jsx(SelectTime, {})] }));
case 'calendar':
return (_jsxs(React.Fragment, { children: [_jsx(Calendar, {}), _jsx(SelectMonth, {})] }));
case 'monthYear':
return _jsx(SelectMonth, {});
case 'time':
return _jsx(SelectTime, {});
}
};
return (_jsx(CalendarContext.Provider, { value: contextValue, children: _jsx(View, { style: [themedStyles.container, { minHeight }, style], onLayout: ({ nativeEvent }) => setMinHeight(nativeEvent.layout.width * 0.9 + 55), children: renderBody() }) }));
};
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,
defaultFont: PropTypes.string,
headerFont: PropTypes.string,
textFontSize: PropTypes.number,
textHeaderFontSize: PropTypes.number,
headerAnimationDistance: PropTypes.number,
daysAnimationDistance: PropTypes.number,
};
const modeArray = ['datepicker', '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,
isGregorian: true,
configs: {},
reverse: 'unset',
options: {},
mode: 'datepicker',
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,
isGregorian: 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 };
//# sourceMappingURL=DatePicker.js.map