import { formatDate } from '@transferwise/formatting'; import { PureComponent } from 'react'; import { injectIntl, type WrappedComponentProps } from 'react-intl'; import { getDayNames, isWithinRange } from '../../../common/dateUtils'; import { getFocusableTime } from '../../getFocusableTime/getFocusableTime'; import { getStartOfDay } from '../../getStartOfDay'; import TableLink from '../../tableLink'; const SHORT_DAY_FORMAT: Intl.DateTimeFormatOptions = { day: 'numeric' }; interface DayCalendarTableProps extends WrappedComponentProps { selectedDate: Date | null; min: Date | null; max: Date | null; viewMonth: number; viewYear: number; onSelect: (date: Date) => void; } class DayCalendarTable extends PureComponent { getTableStructure = () => { const { viewMonth, viewYear } = this.props; let firstDayOfMonth = new Date(viewYear, viewMonth, 1).getDay(); // JS Sunday is 0, we're setting it last if (firstDayOfMonth === 0) { firstDayOfMonth = 7; } const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate(); let week: number[] = []; const weeks: number[][] = []; let i; // Pad first week for (i = 1; i < firstDayOfMonth; i += 1) { week.push(-1); } // Fill in days for (i = 1; i <= daysInMonth; i += 1) { week.push(i); if ((firstDayOfMonth + i - 1) % 7 === 0) { weeks.push(week); week = []; } } if (week.length > 0) { // Pad last week for (i = week.length; i < 7; i += 1) { week.push(-1); } weeks.push(week); } return weeks; }; days = getDayNames(this.props.intl.locale, 'short'); daysShort = getDayNames(this.props.intl.locale, 'narrow'); daysLong = getDayNames(this.props.intl.locale, 'long'); selectDay = (day: number) => { const { viewMonth, viewYear, onSelect } = this.props; onSelect(new Date(viewYear, viewMonth, day)); }; isDisabled = (day: number) => { if (day < 0) { return true; } const { min, max, viewMonth, viewYear } = this.props; const date = new Date(viewYear, viewMonth, day); return !isWithinRange(date, min, max); }; isActive = (day: number) => { const { selectedDate, viewMonth, viewYear } = this.props; return !!(selectedDate && Number(new Date(viewYear, viewMonth, day)) === Number(selectedDate)); }; isToday = (day: number) => { const { viewMonth, viewYear } = this.props; return Number(getStartOfDay(new Date())) === Number(new Date(viewYear, viewMonth, day)); }; getAutofocusDay = (weeks: number[][]) => { const days = weeks.flatMap((week) => week); return getFocusableTime({ isActive: this.isActive, isNow: this.isToday, isDisabled: this.isDisabled, timeSpan: days, }); }; render() { const { viewMonth, viewYear, intl } = this.props; const weeks = this.getTableStructure(); const autoFocusDay = this.getAutofocusDay(weeks); return ( {this.days.map((day, index) => ( ))} {/* eslint-disable react/no-array-index-key */} {weeks.map((week, weekIndex) => ( {week.map((day, dayIndex) => ( ))} ))} {/* eslint-enable react/no-array-index-key */}
4 ? 'text-xs-center np-text-body-default' : 'text-xs-center np-text-body-default-bold' } > {day.slice(0, 3)} {this.daysShort[index].slice(0, 2)}
4 ? 'weekend' : ''}> {day !== -1 && ( )}
); } } export default injectIntl(DayCalendarTable);