UNPKG

react-native-nepali-picker

Version:

Minimalist and modern Nepali-date picker with customization.🌟

426 lines (422 loc) • 14 kB
"use strict"; import { useEffect, useState } from 'react'; import { Modal, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import DateSyncLogo from "./assets/DateSync.js"; import { ChevronIcon } from "./assets/Icons.js"; import Triangle from "./assets/Triangle.js"; import { bs, daysInEnglish, daysInNepali, getNepaliNumber, monthsInEnglish, monthsInNepali } from "./calendar/config.js"; import { NepaliToday, validateDate } from "./calendar/functions.js"; import { calcFirstDay, isToday } from "./calendar/settings.js"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const CalendarPicker = ({ visible, onClose, theme = 'light', onDateSelect, language = 'np', initialDate = NepaliToday(), brandColor = '#2081b9', titleTextStyle = { fontSize: 20, fontWeight: 'bold' }, weekTextStyle = { fontSize: 15, fontWeight: 'bold' }, dayTextStyle = { fontSize: 15, fontWeight: '600' } }) => { const value = validateDate(initialDate); console.log('the initial date is ', initialDate); const [TodayNepaliDate, setTodayNepaliDate] = useState(initialDate); const cYear = parseInt(TodayNepaliDate.split('-')[0], 10); const cMonth = parseInt(TodayNepaliDate.split('-')[1], 10); const cDay = parseInt(TodayNepaliDate.split('-')[2], 10); const [firstDayOfMonth, setFirstDayOfMonth] = useState(0); const [month, setMonth] = useState(cMonth); const [year, setYear] = useState(cYear); const [calendarDate, setCalendarDate] = useState([]); const [yearModal, setYearModal] = useState(false); const syncToday = () => { setMonth(cMonth); setYear(cYear); }; const handleDateClick = day => { const date = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; setTodayNepaliDate(date); onDateSelect(date); onClose(); }; useEffect(() => { setTodayNepaliDate(initialDate); }, [initialDate]); //Handle Next Month Click const handleNextClick = () => { if (month === 12) { if (year < 2099) { setYear(prev => prev + 1); setMonth(1); } } else { setMonth(prev => prev + 1); } }; //Handle Previous Month Click const handlePreviousClick = () => { if (month === 1) { if (year > 2000) { setYear(prev => prev - 1); setMonth(12); } } else { setMonth(prev => prev - 1); } }; const openYearView = () => { setYearModal(true); }; const closeYearView = () => { setYearModal(false); }; useEffect(() => { // calculate First Day Of Month (FDOM) and Days In Month(DIM) const FDOM = calcFirstDay(year, month); const DIM = bs[year][month]; setFirstDayOfMonth(FDOM); // array which contain 42 cells and it only fill the date with number if the date is present otherwise it fill cells with null. const calendarCells = Array.from({ length: 42 }, (_, index) => { const dayNumber = index - FDOM + 1; if (dayNumber > 0 && dayNumber <= DIM) { return dayNumber; } else { return null; } }); setCalendarDate(calendarCells); }, [year, month, initialDate]); const handleYearClick = y => { setYear(y); closeYearView(); }; const dark = theme === 'dark'; const weekDays = language === 'en' ? daysInEnglish : daysInNepali; if (value !== true) { return /*#__PURE__*/_jsx(Modal, { visible: visible, onRequestClose: onClose, transparent: true, children: /*#__PURE__*/_jsx(Pressable, { style: styles.outerPressable, onPress: onClose, children: /*#__PURE__*/_jsx(Pressable, { onPress: () => {}, style: styles.innerPressable, children: /*#__PURE__*/_jsxs(View, { style: { ...styles.innerView, minHeight: '40%', minWidth: '90%', justifyContent: 'center', alignItems: 'center', backgroundColor: dark ? '#383838' : '#ffffff' }, children: [/*#__PURE__*/_jsx(Text, { style: { color: dark ? 'white' : 'black', fontWeight: '600', paddingHorizontal: 10, paddingVertical: 10 }, children: "Unsupported date range on initialDate" }), /*#__PURE__*/_jsx(Text, { style: { color: dark ? 'white' : 'black', paddingHorizontal: 10 }, children: value })] }) }) }) }); } return /*#__PURE__*/_jsxs(Modal, { visible: visible, onRequestClose: onClose, transparent: true, children: [/*#__PURE__*/_jsx(Pressable, { style: styles.outerPressable, onPress: onClose, children: /*#__PURE__*/_jsx(Pressable, { onPress: () => {}, style: styles.innerPressable, children: /*#__PURE__*/_jsxs(View, { style: { ...styles.innerView, backgroundColor: dark ? '#383838' : '#ffffff' }, children: [/*#__PURE__*/_jsx(Text, { style: { color: dark ? 'white' : 'black', paddingHorizontal: 10 }, children: language === 'np' ? 'आजको मिति ' : "Today's Date" }), /*#__PURE__*/_jsxs(View, { style: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 10, marginBottom: 20, alignItems: 'center' }, children: [/*#__PURE__*/_jsx(View, { children: /*#__PURE__*/_jsx(TouchableOpacity, { onPress: syncToday, children: language == 'np' ? /*#__PURE__*/_jsxs(Text, { style: { ...titleTextStyle, color: dark ? '#fff' : '#000' }, children: [getNepaliNumber(cYear), " ", monthsInNepali[cMonth - 1], ' ', " ", getNepaliNumber(cDay)] }) : /*#__PURE__*/_jsxs(Text, { style: { ...titleTextStyle, color: dark ? '#fff' : '#000' }, children: [cYear, " ", monthsInEnglish[cMonth - 1], ' ', " ", cDay] }) }) }), /*#__PURE__*/_jsx(TouchableOpacity, { onPress: syncToday, children: /*#__PURE__*/_jsx(DateSyncLogo, { day: cDay, color: dark ? '#ffff' : '#000' }) })] }), /*#__PURE__*/_jsxs(View, { style: styles.ButtonContainer, children: [/*#__PURE__*/_jsx(TouchableOpacity, { style: styles.CButton, onPress: handlePreviousClick, children: /*#__PURE__*/_jsx(ChevronIcon, { direction: "right", color: dark ? 'white' : 'black' }) }), /*#__PURE__*/_jsxs(TouchableOpacity, { style: { flexDirection: 'row', alignItems: 'center' }, onPress: openYearView, children: [/*#__PURE__*/_jsx(Text, { style: { ...titleTextStyle, marginRight: 6, color: dark ? 'white' : 'black' }, children: language === 'np' ? monthsInNepali[month - 1] : monthsInEnglish[month - 1] }), /*#__PURE__*/_jsx(Text, { style: { ...titleTextStyle, marginRight: 10, color: dark ? 'white' : 'black' }, children: language === 'np' ? getNepaliNumber(year) : year }), /*#__PURE__*/_jsx(Triangle, { height: 10, width: 13, color: dark ? 'white' : 'black' })] }), /*#__PURE__*/_jsx(TouchableOpacity, { style: styles.CButton, onPress: handleNextClick, children: /*#__PURE__*/_jsx(ChevronIcon, { direction: "left", color: dark ? 'white' : 'black' }) })] }), /*#__PURE__*/_jsxs(View, { style: styles.outerDateConainer, children: [/*#__PURE__*/_jsx(View, { style: styles.weekContainer, children: weekDays.map((item, index) => { return /*#__PURE__*/_jsx(View, { style: styles.WeekItem, children: /*#__PURE__*/_jsx(Text, { style: { ...weekTextStyle, color: dark ? 'white' : 'black' }, children: item }) }, index); }) }), /*#__PURE__*/_jsx(View, { style: styles.datesContainer, children: calendarDate.map((dayItem, index) => { return /*#__PURE__*/_jsx(TouchableOpacity, { style: styles.dateItem, onPress: //execute on day item press, Only execute when dayItem is not null dayItem ? () => handleDateClick(dayItem) : () => {}, children: dayItem ? /*#__PURE__*/_jsx(View, { style: { paddingHorizontal: 6, paddingVertical: 3, borderRadius: 999, //check if the date is today or not and apply conditional styling. backgroundColor: isToday(TodayNepaliDate, index, year, month, firstDayOfMonth) ? brandColor : dark ? '#383838' : '#fff' }, children: /*#__PURE__*/_jsx(Text, { style: { ...dayTextStyle, color: isToday(TodayNepaliDate, index, year, month, firstDayOfMonth) ? '#fff' : dark ? 'white' : 'black' }, children: language === 'np' ? getNepaliNumber(dayItem) : dayItem }) }) : null }, index); }) })] })] }) }) }), /*#__PURE__*/_jsx(Modal, { visible: yearModal, onRequestClose: closeYearView, transparent: true, children: /*#__PURE__*/_jsx(Pressable, { style: styles.outerPressable, onPress: () => closeYearView(), children: /*#__PURE__*/_jsx(Pressable, { style: styles.YearInnerPressable, onPress: () => {}, children: /*#__PURE__*/_jsx(View, { style: { ...styles.InnerYearView, backgroundColor: dark ? '#383838' : '#f2f2f2' }, children: /*#__PURE__*/_jsx(ScrollView, { showsVerticalScrollIndicator: false, contentContainerStyle: { display: 'flex', paddingVertical: 10, flexDirection: 'row', justifyContent: 'center', flexWrap: 'wrap' }, children: Array(100).fill(0).map((_, index) => { return /*#__PURE__*/_jsx(TouchableOpacity, { onPress: () => handleYearClick(index + 2000), style: { paddingHorizontal: 20, paddingVertical: 6, marginHorizontal: 4, marginVertical: 4, borderColor: dark ? 'white' : 'black', borderRadius: 20, backgroundColor: index + 2000 === year ? brandColor : '', borderWidth: 0.4 }, children: /*#__PURE__*/_jsx(Text, { style: { fontWeight: '500', color: index + 2000 === year ? 'white' : dark ? 'white' : 'black' }, children: language === 'np' ? getNepaliNumber(index + 2000) : index + 2000 }) }, index); }) }) }) }) }) })] }); }; const styles = 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 }, //WeekText: { // fontWeight: 'bold', // fontSize: 14, // color: 'black', //}, datesContainer: { flexDirection: 'row', flexWrap: 'wrap' }, dateItem: { overflow: 'hidden', width: '14.28%', justifyContent: 'center', alignItems: 'center', paddingVertical: 10 }, //DayText: { // fontSize: 14, // fontWeight: '600', //}, CButton: { paddingHorizontal: 20, paddingVertical: 10 }, ButtonContainer: { alignItems: 'center', flexDirection: 'row', marginBottom: 10, justifyContent: 'space-between' }, outerDateConainer: { paddingHorizontal: 3 }, //TitleText: { // fontSize: 20, // fontWeight: 'bold', //}, // for year view modal YearInnerPressable: { justifyContent: 'center', maxWidth: 500, maxHeight: '70%', marginHorizontal: 30 }, InnerYearView: { borderRadius: 20, backgroundColor: '#f2f2f2', minHeight: 50, maxHeight: '100%' } }); export default CalendarPicker; //# sourceMappingURL=CalendarPicker.js.map