UNPKG

react-native-nepali-picker

Version:

Minimalist and modern Nepali-date picker with customization.🌟

440 lines (429 loc) • 16.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("react"); var _reactNative = require("react-native"); var _DateSync = _interopRequireDefault(require("./assets/DateSync.js")); var _Icons = require("./assets/Icons.js"); var _Triangle = _interopRequireDefault(require("./assets/Triangle.js")); var _config = require("./calendar/config.js"); var _functions = require("./calendar/functions.js"); var _settings = require("./calendar/settings.js"); var _DayCell = _interopRequireDefault(require("./DayCell.js")); var _validate = require("./calendar/validate.js"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const CalendarPicker = ({ visible, onClose, theme = 'light', onDateSelect, language = 'np', date = (0, _functions.NepaliToday)(), minDate = '2000-01-01', maxDate = '2099-12-30', brandColor = '#2081b9', titleTextStyle = { fontSize: 20, fontWeight: 'bold' }, weekTextStyle = { fontSize: 15, fontWeight: 'bold' }, dayTextStyle = { fontSize: 15, fontWeight: '600' } }) => { const yearModelScrollRef = (0, _react.useRef)(null); const value = (0, _validate.validateCalendarDates)(date, minDate, maxDate); const [userSelectedDate, setUserSelectedDate] = (0, _react.useState)(date); const cYear = parseInt(userSelectedDate.split('-')[0], 10); const cMonth = parseInt(userSelectedDate.split('-')[1], 10); const cDay = parseInt(userSelectedDate.split('-')[2], 10); const [month, setMonth] = (0, _react.useState)(cMonth); const [year, setYear] = (0, _react.useState)(cYear); const [yearModal, setYearModal] = (0, _react.useState)(false); const syncToday = () => { setMonth(cMonth); setYear(cYear); }; const handleDateClick = (0, _react.useCallback)(day => { const date = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; setUserSelectedDate(date); onDateSelect(date); onClose(); }, [year, month, onDateSelect, onClose]); //check weather the date is disabled or not?(with maximum and minimum date provided) const isDateDisabled = (0, _react.useCallback)(day => { const date = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; if (minDate && date < minDate) return true; if (maxDate && date > maxDate) return true; return false; }, [year, month, minDate, maxDate]); // Set the user selected date is as NepaliDate (initially it will be always // current Nepali Date) (0, _react.useEffect)(() => { setUserSelectedDate(date); }, [date]); // It will calculate the current date number const selectedDay = (0, _react.useMemo)(() => { const [y, m, d] = userSelectedDate.split('-').map(Number); return y === year && m === month ? d : null; }, [userSelectedDate, year, month]); //Handle Next Month button Click const handleNextClick = () => { if (month === 12) { if (year < _settings.NEPALI_MAX_YEAR) { setYear(prev => prev + 1); setMonth(1); } } else { setMonth(prev => prev + 1); } }; //Handle Previous Month button Click const handlePreviousClick = () => { if (month === 1) { if (year > _settings.NEPALI_MIN_YEAR) { setYear(prev => prev - 1); setMonth(12); } } else { setMonth(prev => prev - 1); } }; //open the model which shows the list of years(2000-2099)BS const openYearView = async () => { setYearModal(true); //wait for model to open completely before to scroll down await new Promise(resolve => setTimeout(resolve, 10)); // After model is opened, need ot scrolldown to that year // Here we need to calculate (roughly) how much to scroll to keep the seelcted year in // focus // - For that we take the height of the year button and one row contain around 3-5( // we will take 4) column of buttons so, // approx Height = (year number(82 for 2082) * button height)/cloumn number // NOTE: This is approx just to make the button visible when model is opened. const vHeight = (year - _settings.NEPALI_MIN_YEAR) * 36 / 4; yearModelScrollRef.current?.scrollTo({ y: vHeight, animated: true }); }; //close the year view model const closeYearView = () => { setYearModal(false); }; // Calculating the number of cells on that month and year(Max it can have 42 cells) // If the cells don't have the date, it will be null otherwise it will contain the actual // date number (1,2,3...upto 32) const calendarDate = (0, _react.useMemo)(() => { const FDOM = (0, _settings.calcFirstDay)(year, month); const DIM = _config.bs[year][month]; return Array.from({ length: 42 }, (_, index) => { const dayNum = index - FDOM + 1; return dayNum > 0 && dayNum <= DIM ? dayNum : null; }); }, [year, month]); const handleYearClick = y => { setYear(y); closeYearView(); }; const dark = theme === 'dark'; const weekDays = language === 'en' ? _config.daysInEnglish : _config.daysInNepali; // If the user prvided (initial value ) is not in correct format i.e (YYYY-MM-DD) if (value !== true) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, { visible: visible, onRequestClose: onClose, transparent: true, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { style: styles.outerPressable, onPress: onClose, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { onPress: () => {}, style: styles.innerPressable, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: { ...styles.innerView, minHeight: '40%', minWidth: '90%', justifyContent: 'center', alignItems: 'center', backgroundColor: dark ? '#383838' : '#ffffff' }, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { color: dark ? 'white' : 'black', fontWeight: '600', paddingHorizontal: 10, paddingVertical: 10 }, children: "Unsupported date range on Provided Date" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { color: dark ? 'white' : 'black', paddingHorizontal: 10 }, children: value })] }) }) }) }); } return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Modal, { visible: visible, onRequestClose: onClose, transparent: true, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { style: styles.outerPressable, onPress: onClose, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { onPress: () => {}, style: styles.innerPressable, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: { ...styles.innerView, backgroundColor: dark ? '#383838' : '#ffffff' }, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { color: dark ? 'white' : 'black', paddingHorizontal: 10 }, children: language === 'np' ? 'तपाईंको मिति ' : "Selected Date" }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 10, marginBottom: 20, alignItems: 'center' }, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { onPress: syncToday, children: language == 'np' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: { ...titleTextStyle, color: dark ? '#fff' : '#000' }, children: [(0, _config.getNepaliNumber)(cYear), " ", _config.monthsInNepali[cMonth - 1], ' ', " ", (0, _config.getNepaliNumber)(cDay)] }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: { ...titleTextStyle, color: dark ? '#fff' : '#000' }, children: [cYear, " ", _config.monthsInEnglish[cMonth - 1], ' ', " ", cDay] }) }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { onPress: syncToday, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DateSync.default, { day: cDay, color: dark ? '#ffff' : '#000' }) })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.ButtonContainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: styles.CButton, onPress: handlePreviousClick, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icons.ChevronIcon, { direction: "right", color: dark ? 'white' : 'black' }) }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: { flexDirection: 'row', alignItems: 'center' }, onPress: openYearView, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { ...titleTextStyle, marginRight: 6, color: dark ? 'white' : 'black' }, children: language === 'np' ? _config.monthsInNepali[month - 1] : _config.monthsInEnglish[month - 1] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { ...titleTextStyle, marginRight: 10, color: dark ? 'white' : 'black' }, children: language === 'np' ? (0, _config.getNepaliNumber)(year) : year }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Triangle.default, { height: 10, width: 13, color: dark ? 'white' : 'black' })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: styles.CButton, onPress: handleNextClick, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icons.ChevronIcon, { direction: "left", color: dark ? 'white' : 'black' }) })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.outerDateConainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.weekContainer, children: weekDays.map((item, index) => { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.WeekItem, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { ...weekTextStyle, color: dark ? 'white' : 'black' }, children: item }) }, index); }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.datesContainer, children: calendarDate.map((day, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_DayCell.default, { day: day, isSelectedDay: day !== null && day === selectedDay, disabled: day !== null && isDateDisabled(day), onPress: handleDateClick, dark: dark, brandColor: brandColor, language: language, dayTextStyle: dayTextStyle }, index)) })] })] }) }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, { visible: yearModal, onRequestClose: closeYearView, transparent: true, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { style: styles.outerPressable, onPress: () => closeYearView(), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { style: styles.YearInnerPressable, onPress: () => {}, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: { ...styles.InnerYearView, backgroundColor: dark ? '#383838' : '#f2f2f2' }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, { showsVerticalScrollIndicator: false, ref: yearModelScrollRef, contentContainerStyle: { display: 'flex', paddingVertical: 10, flexDirection: 'row', justifyContent: 'center', flexWrap: 'wrap' }, children: Array(100).fill(0).map((_, index) => { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { onPress: () => handleYearClick(index + _settings.NEPALI_MIN_YEAR), style: { paddingHorizontal: 20, paddingVertical: 6, marginHorizontal: 4, marginVertical: 4, borderColor: dark ? 'white' : 'black', borderRadius: 20, backgroundColor: index + _settings.NEPALI_MIN_YEAR === year ? brandColor : '', borderWidth: 0.4 }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: { fontWeight: '500', color: index + _settings.NEPALI_MIN_YEAR === year ? 'white' : dark ? 'white' : 'black' }, children: language === 'np' ? (0, _config.getNepaliNumber)(index + _settings.NEPALI_MIN_YEAR) : index + _settings.NEPALI_MIN_YEAR }) }, index); }) }) }) }) }) })] }); }; const styles = _reactNative.StyleSheet.create({ outerPressable: { height: '100%', justifyContent: 'center', width: '100%', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.54)' }, innerPressable: { minHeight: '20%', maxWidth: 500, marginHorizontal: 30 }, innerView: { borderRadius: 20, backgroundColor: '#f2f2f2', padding: 10 }, weekContainer: { flexDirection: 'row', width: '100%' }, WeekItem: { width: '14.28%', alignItems: 'center', paddingVertical: 18 }, datesContainer: { flexDirection: 'row', flexWrap: 'wrap' }, dateItem: { overflow: 'hidden', width: '14.28%', justifyContent: 'center', alignItems: 'center', paddingVertical: 10 }, CButton: { paddingHorizontal: 20, paddingVertical: 10 }, ButtonContainer: { alignItems: 'center', flexDirection: 'row', marginBottom: 10, justifyContent: 'space-between' }, outerDateConainer: { paddingHorizontal: 3 }, // for year view modal YearInnerPressable: { justifyContent: 'center', maxWidth: 500, maxHeight: '70%', marginHorizontal: 30 }, InnerYearView: { borderRadius: 20, backgroundColor: '#f2f2f2', minHeight: 50, maxHeight: '100%' } }); var _default = exports.default = CalendarPicker; //# sourceMappingURL=CalendarPicker.js.map