UNPKG

@lad-tech/mobydick-calendar

Version:

React Native components library focused on usability, accessibility and developer experience

256 lines (219 loc) 6.53 kB
import {DateData} from 'react-native-calendars'; import {MarkingProps} from 'react-native-calendars/src/calendar/day/marking'; import {px} from '@lad-tech/mobydick-core'; import {MarkedDates} from 'react-native-calendars/src/types'; import { colorElem, IColors, IDirection, IMarkedDates, IMarkedTypes, } from './types'; export const getDateForCalendar = (date: Date): string => { const yr = date.getFullYear(); const month = `${date.getMonth() + 1 < 10 ? 0 : ''}${date.getMonth() + 1}`; const d = `${date.getDate() < 10 ? 0 : ''}${date.getDate()}`; return `${yr}-${month}-${d}`; }; const getStyleToday = (colorToday: colorElem): MarkingProps => { return { startingDay: true, endingDay: true, color: colorToday.color, textColor: colorToday.textColor, customContainerStyle: { borderRadius: px(4), width: '100%', }, customTextStyle: { fontWeight: '600', fontFamily: 'Inter-SemiBold', }, }; }; export const getAllDatesBetween = ( fromDate: Date, toDate: Date, {colorPrime, colorSoft, colorToday}: IColors, isShowToday: boolean, ) => { let curDate = new Date(fromDate.getTime()); const datesForCalendar: IMarkedTypes = {}; let lengthDateRange = 1; if (isShowToday) { datesForCalendar[getDateForCalendar(new Date())] = getStyleToday(colorToday); } const today = new Date(); const todayTimeMidnight = today.getTime() - (today.getTime() % (1000 * 60 * 60 * 24)); // сбрасываем timestamp этого дня до 00:00:00 datesForCalendar[getDateForCalendar(fromDate)] = { startingDay: true, endingDay: true, color: colorPrime.color, textColor: colorPrime.textColor, customContainerStyle: { borderRadius: px(4), width: '100%', }, customTextStyle: isShowToday && fromDate.getTime() === todayTimeMidnight ? { fontWeight: '600', fontFamily: 'Inter-SemiBold', color: colorPrime.textColor, } : undefined, }; while (curDate < toDate) { lengthDateRange = lengthDateRange + 1; curDate = new Date(curDate.setDate(curDate.getDate() + 1)); datesForCalendar[getDateForCalendar(curDate)] = { color: colorSoft.color, textColor: colorSoft.textColor, }; if (isShowToday && curDate.getTime() === todayTimeMidnight) { datesForCalendar[getDateForCalendar(new Date())] = { color: colorSoft.color, customTextStyle: { fontWeight: '600', fontFamily: 'Inter-SemiBold', }, }; } } datesForCalendar[getDateForCalendar(toDate)] = { startingDay: true, endingDay: true, textColor: colorPrime.textColor, color: colorPrime.color, customContainerStyle: { borderRadius: px(4), width: '100%', }, customTextStyle: isShowToday && toDate.getTime() === todayTimeMidnight ? { fontWeight: '600', fontFamily: 'Inter-SemiBold', color: colorPrime.textColor, } : undefined, }; return {dates: datesForCalendar, fromDate, toDate, lengthDateRange}; }; export const getDottedDates = (dots: Date[], dotColor: string) => { const datesForCalendar: IMarkedTypes = {}; for (const dot of dots) { datesForCalendar[getDateForCalendar(dot)] = { marked: true, dotColor: dotColor, }; } return {dates: datesForCalendar}; }; export const getMarkedToday = ({colorToday}: IColors) => { const datesForCalendar: IMarkedTypes = {}; datesForCalendar[getDateForCalendar(new Date())] = getStyleToday(colorToday); return {dates: datesForCalendar, fromDate: null, toDate: null}; }; export const calculateBoundaries = ( day: DateData, markedDates: IMarkedDates | undefined, isPeriod: boolean, disabledDates?: MarkedDates, ) => { let toDate; let fromDate; if ( !markedDates || !isPeriod || !markedDates.fromDate || !markedDates.toDate ) { fromDate = day.timestamp; toDate = day.timestamp; } else { const {fromDate: minDate, toDate: maxDate} = markedDates; let hasBlockedDatesInPeriod = false; if ( day.timestamp !== minDate.getTime() && day.timestamp !== maxDate.getTime() ) { const startDate = new Date(Math.min(minDate.getTime(), day.timestamp)); const endDate = new Date(Math.max(maxDate.getTime(), day.timestamp)); const currentDate = new Date(startDate); while (currentDate <= endDate && !hasBlockedDatesInPeriod) { const dateKey = currentDate.toISOString().split('T')[0]; if (dateKey && disabledDates && disabledDates[dateKey]?.disabled) { hasBlockedDatesInPeriod = true; } currentDate.setDate(currentDate.getDate() + 1); } } if (hasBlockedDatesInPeriod) { fromDate = day.timestamp; toDate = day.timestamp; } else { if (day.timestamp < minDate.getTime()) { fromDate = day.timestamp; toDate = maxDate; } else if (day.timestamp > maxDate.getTime()) { toDate = day.timestamp; fromDate = minDate; } else if ( day.timestamp === minDate.getTime() || day.timestamp === maxDate.getTime() ) { fromDate = day.timestamp; toDate = day.timestamp; } else { fromDate = minDate; toDate = day.timestamp; } } } return {fromDate, toDate}; }; export const calculateYearRange = ( currentYear: number, direction?: IDirection, ) => { const yearRange = []; switch (direction) { case IDirection.left: { for (let i = 12; i > 0; i--) { yearRange.push(currentYear - i); } break; } case IDirection.right: { for (let i = 1; i <= 12; i++) { yearRange.push(currentYear + i); } break; } default: { for (let i = -4; i <= 7; i++) { yearRange.push(currentYear + i); } break; } } return yearRange; }; export const isValidDate = (date: string) => { return Boolean(Date.parse(date)); }; export const getMaxDate = (fromDate: Date, maxLengthDateRange: number) => { const date = new Date(fromDate); return getDateForCalendar( new Date(date?.setDate(fromDate.getDate() + maxLengthDateRange - 1)), ); }; export const getMinDate = (toDate: Date, maxLengthDateRange: number) => { const date = new Date(toDate); return getDateForCalendar( new Date(date?.setDate(toDate.getDate() - (maxLengthDateRange - 1))), ); };