UNPKG

@navikt/ds-react

Version:

React components from the Norwegian Labour and Welfare Administration.

294 lines (278 loc) 6.75 kB
import { setYear } from "date-fns"; import { Matcher } from "../Date.typeutils"; import { isMatch } from "../date-utils"; export const nextEnabled = ( months: Date[], key: string, disabled: Matcher[], currentMonth: Date, setYearState: (date: Date) => void, yearState: Date, dropdownCaption: boolean, fromDate?: Date, toDate?: Date, ): Date => { const currentIndex = currentMonth.getMonth(); if (key === "Home") { const nextDate = nextOnRow( currentIndex, months, yearState, disabled, "home", ); if (nextDate) { return nextDate; } } if (key === "End") { const nextDate = nextOnRow( currentIndex, months, yearState, disabled, "end", ); if (nextDate) { return nextDate; } } if (key === "PageUp") { if ( !dropdownCaption || (fromDate && yearState.getFullYear() - 1 >= fromDate?.getFullYear()) ) { setYearState(setYear(yearState, Number(yearState.getFullYear() - 1))); } } if (key === "PageDown") { if ( !dropdownCaption || (toDate && yearState.getFullYear() + 1 <= toDate?.getFullYear()) ) { setYearState(setYear(yearState, Number(yearState.getFullYear() + 1))); } } if (key === "ArrowRight") { const nextMonth = loopForward( currentIndex, months, yearState, setYearState, disabled, false, dropdownCaption, fromDate, toDate, ); if (nextMonth) { return setYear(months[nextMonth.index], nextMonth.year); } } if (key === "ArrowLeft") { const prevMonth = loopBack( currentIndex - 1, months, disabled, yearState, setYearState, false, dropdownCaption, fromDate, toDate, ); if (prevMonth) { return setYear(months[prevMonth.index], prevMonth.year); } } if (key === "ArrowDown") { if ( months[currentIndex + 4] && !isMatch( setYear(months[currentIndex + 4], yearState.getFullYear()), disabled, ) ) { return setYear(months[currentIndex + 4], yearState.getFullYear()); } const fallbackNext = loopForward( currentIndex, months, yearState, setYearState, disabled, true, dropdownCaption, fromDate, toDate, ); if ( fallbackNext && getRow(fallbackNext.index) !== getRow(currentIndex + 8) ) { return setYear(months[fallbackNext.index], fallbackNext.year); } } if (key === "ArrowUp") { if ( months[currentIndex - 4] && !isMatch( setYear(months[currentIndex - 4], Number(yearState.getFullYear())), disabled, ) ) return setYear(months[currentIndex - 4], Number(yearState.getFullYear())); const fallbackPrev = loopBack( currentIndex, months, disabled, yearState, setYearState, true, dropdownCaption, fromDate, toDate, ); if (fallbackPrev) return setYear(months[fallbackPrev.index], fallbackPrev.year); } return currentMonth; }; const loopBack = ( currentIndex: number, months: Date[], disabled: Matcher[], yearState: Date, setYearState: (date: Date) => void, rowCheck: boolean, dropdownCaption: boolean, fromDate?: Date, toDate?: Date, ): { index: number; year: number } | undefined => { let currentYear = setYear(yearState, Number(yearState.getFullYear())); for (let i = currentIndex; i >= -1; i--) { if (i === -1) { if ( isOutOfRange( dropdownCaption, setYear(currentYear, Number(currentYear.getFullYear() - 1)), fromDate, toDate, ) ) return; currentYear = setYear(currentYear, Number(currentYear.getFullYear() - 1)); setYearState(currentYear); i = 11; } const month = months[i]; const isDisabled = !isMatch( setYear(month, Number(currentYear.getFullYear())), disabled, ); if (rowCheck) { if (isDisabled && getRow(i) !== getRow(currentIndex)) { return { index: i, year: Number(currentYear.getFullYear()) }; } } else { if (isDisabled) { return { index: i, year: Number(currentYear.getFullYear()) }; } } } }; const loopForward = ( currentIndex: number, months: Date[], yearState: Date, setYearState: (date: Date) => void, disabled: Matcher[], rowCheck: boolean, dropdownCaption: boolean, fromDate?: Date, toDate?: Date, ): { index: number; year: number } | undefined => { let currentYear = setYear(yearState, Number(yearState.getFullYear())); for (let i = currentIndex + 1; i < months.length + 1; i++) { if (i === 12) { if ( isOutOfRange( dropdownCaption, setYear(currentYear, Number(currentYear.getFullYear() + 1)), fromDate, toDate, ) ) return; currentYear = setYear(currentYear, Number(currentYear.getFullYear() + 1)); setYearState(currentYear); i = 0; } const month = months[i]; const isDisabled = !isMatch( setYear(month, Number(currentYear.getFullYear())), disabled, ); if (rowCheck) { if (isDisabled && getRow(i) !== getRow(currentIndex)) { return { index: i, year: Number(currentYear.getFullYear()) }; } } else { if (isDisabled) { return { index: i, year: Number(currentYear.getFullYear()) }; } } } }; const getRow = (index: number): number => { if (index >= 0 && index <= 3) return 1; if (index >= 4 && index <= 7) return 2; return 3; }; const isOutOfRange = ( dropdownCaption: boolean, year: Date, fromDate?: Date, toDate?: Date, ): boolean => { if ( dropdownCaption && fromDate && toDate && (year.getFullYear() < fromDate?.getFullYear() || year.getFullYear() > toDate?.getFullYear()) ) { return true; } return false; }; const nextOnRow = ( currentIndex: number, months: Date[], yearState: Date, disabled: Matcher[], mode: "home" | "end", ) => { const row = getRow(currentIndex); let monthsOfRow: Date[] = []; switch (row) { case 1: monthsOfRow = months.slice(0, 4); break; case 2: monthsOfRow = months.slice(4, 8); break; case 3: monthsOfRow = months.slice(8, 12); break; default: break; } if (mode === "end") monthsOfRow = monthsOfRow.reverse(); for (let i = 0; i < monthsOfRow.length; i++) { const month = monthsOfRow[i]; if (!isMatch(setYear(month, Number(yearState.getFullYear())), disabled)) { return setYear(month, Number(yearState.getFullYear())); } } };