UNPKG

react-native-taqweem

Version:

**A dual calendar component (Hijri + Gregorian) for React Native** — minimal, customizable, and theme-ready. Perfect for apps needing culturally-aware calendars, Islamic date pickers, or just modern UX flexibility.

100 lines (88 loc) 3.14 kB
import { useMemo } from 'react'; import type { CalendarDay } from './types'; import { getCurrentMonth, getCurrentYear, getNextMonth, getNumberOfDaysInMonth, getPreviousMonth, setDayOfMonth } from './utils'; import moment from 'moment-hijri'; export const useCalendarInfo = (isHijri: boolean, dateObj: moment.Moment) => { const year = getCurrentYear(isHijri, dateObj); const month = getCurrentMonth(isHijri, dateObj); const daysInMonth = getNumberOfDaysInMonth(isHijri, dateObj); return { year, month, daysInMonth }; }; export const useCalendarDays = ( isHijri: boolean, year: number, month: number, daysInMonth: number, showAdjacentMonths: boolean, ): (CalendarDay | null)[] => { return useMemo(() => { const startOfCurrentMonth = isHijri ? moment(`${year}-${month + 1}-1`, 'iYYYY-iM-iD') : moment(`${year}-${month + 1}-1`, 'YYYY-M-D'); const firstDayWeekDayOfMonth = startOfCurrentMonth.day(); const currentMonthDates = Array.from({ length: daysInMonth }, (_, i) => { const day = i + 1; const date = startOfCurrentMonth.clone(); const dateObj = setDayOfMonth(date, day, isHijri); return { label: day.toString(), date: dateObj, isCurrentMonth: true, }; }); if (!showAdjacentMonths) { const totalCells = 42; const blanksBefore = Array(firstDayWeekDayOfMonth).fill(null); const blanksAfter = Array( totalCells - blanksBefore.length - currentMonthDates.length, ).fill(null); return [ ...blanksBefore.map(() => null), ...currentMonthDates, ...blanksAfter.map(() => null), ]; } const prevMonth = getPreviousMonth(isHijri, startOfCurrentMonth.clone()); const prevMonthDays = getNumberOfDaysInMonth(isHijri, prevMonth); const prevMonthDates = Array.from( { length: firstDayWeekDayOfMonth }, (_, i) => { const day = prevMonthDays - firstDayWeekDayOfMonth + i + 1; const date = prevMonth.clone(); const dateObj = setDayOfMonth(date, day, isHijri); return { label: day.toString(), date: dateObj, isCurrentMonth: false, }; }, ); const totalCells = 42; const nextDaysNeeded = totalCells - (prevMonthDates.length + currentMonthDates.length); const nextMonth = getNextMonth(isHijri, startOfCurrentMonth.clone()); const nextMonthDates = Array.from({ length: nextDaysNeeded }, (_, i) => { const day = i + 1; const date = nextMonth.clone(); const dateObj = setDayOfMonth(date, day, isHijri); return { label: day.toString(), date: dateObj, isCurrentMonth: false, }; }); return [...prevMonthDates, ...currentMonthDates, ...nextMonthDates]; }, [isHijri, year, month, daysInMonth, showAdjacentMonths]); }; export const useWeekdays = (lang = 'en'): string[] => { return useMemo(() => { const formatter = new Intl.DateTimeFormat(lang, { weekday: 'short' }); // Starting from Sunday (0) to Saturday (6) const baseDate = new Date(Date.UTC(2023, 9, 1)); // Any Sunday return Array.from({ length: 7 }, (_, i) => { const date = new Date(baseDate); date.setDate(baseDate.getDate() + i); // Increment day return formatter.format(date); }); }, [lang]); };