From b09dd69a44d44a3f66ff8f1ea8124d41679b857f Mon Sep 17 00:00:00 2001 From: adamviktora <84135613+adamviktora@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:42:12 +0200 Subject: [PATCH] fix(CalendarMonth): does not skip a month on arrow click (#9722) * fix(CalendarMonth): correct setting of initialDate * now focusing date on month change * change month and change year refactoring * fix(CalendarMonth): keep the dates unfocused on month change * fix(CalendarMonth): unfocus date on year change * fix(CalendarMonth): undefined check * refactor(CalendarMonth): remove unnecessary undefined check --- .../CalendarMonth/CalendarMonth.tsx | 61 ++++++------------- .../react-core/src/helpers/datetimeUtils.ts | 2 +- 2 files changed, 19 insertions(+), 44 deletions(-) diff --git a/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx b/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx index de4cb47d7f4..583824c3a37 100644 --- a/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx +++ b/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx @@ -154,12 +154,13 @@ export const CalendarMonth = ({ const [isSelectOpen, setIsSelectOpen] = React.useState(false); const getInitialDate = () => { - const initDate = new Date(dateProp); - if (isValidDate(initDate)) { - return initDate; - } else { - return isValidDate(rangeStart) ? rangeStart : today; + if (isValidDate(dateProp)) { + return dateProp; } + if (isValidDate(rangeStart)) { + return rangeStart; + } + return today; }; const initialDate = getInitialDate(); const [focusedDate, setFocusedDate] = React.useState(initialDate); @@ -211,43 +212,25 @@ export const CalendarMonth = ({ } }; - const changeMonth = (month: number) => { - const newDate = new Date(focusedDate); - const desiredDay = newDate.getDate(); - const monthDays = new Date(newDate.getFullYear(), (month + 1) % 12, 0).getDate(); // Setting day 0 of the next month returns the last day of current month - - if (monthDays < desiredDay) { - newDate.setDate(monthDays); - } - - newDate.setMonth(month); - - if (initialDate.getDate() > desiredDay && monthDays > desiredDay) { - newDate.setDate(initialDate.getDate()); - } + const changeYear = (newYear: number) => changeMonth(focusedDate.getMonth(), newYear); - return newDate; - }; + const changeMonth = (newMonth: number, newYear?: number) => + new Date(newYear ?? focusedDate.getFullYear(), newMonth, 1); const addMonth = (toAdd: -1 | 1) => { - let newMonth = new Date(focusedDate).getMonth() + toAdd; + let newMonth = focusedDate.getMonth() + toAdd; + let newYear = focusedDate.getFullYear(); + if (newMonth === -1) { newMonth = 11; + newYear--; } else if (newMonth === 12) { newMonth = 0; + newYear++; } - const newDate = changeMonth(newMonth); - if (toAdd === 1 && newMonth === 0) { - newDate.setFullYear(newDate.getFullYear() + 1); - } - if (toAdd === -1 && newMonth === 11) { - newDate.setFullYear(newDate.getFullYear() - 1); - } - return newDate; - }; - const yearHasFebruary29th = (year: number) => new Date(year, 1, 29).getMonth() === 1; - const dateIsFebruary29th = (date: Date) => date.getMonth() === 1 && date.getDate() === 29; + return changeMonth(newMonth, newYear); + }; const prevMonth = addMonth(-1); const nextMonth = addMonth(1); @@ -340,19 +323,11 @@ export const CalendarMonth = ({ type="number" value={yearFormatted} onChange={(ev: React.FormEvent, year: string) => { - const newDate = new Date(focusedDate); - if (dateIsFebruary29th(newDate) && !yearHasFebruary29th(+year)) { - newDate.setDate(28); - newDate.setMonth(1); - } - if (dateIsFebruary29th(initialDate) && yearHasFebruary29th(+year)) { - newDate.setFullYear(+year); - newDate.setDate(29); - } - newDate.setFullYear(+year); + const newDate = changeYear(Number(year)); setFocusedDate(newDate); setHoveredDate(newDate); setShouldFocus(false); + focusRef.current?.blur(); // will unfocus a date when changing year via up/down arrows onMonthChange(ev, newDate); }} /> diff --git a/packages/react-core/src/helpers/datetimeUtils.ts b/packages/react-core/src/helpers/datetimeUtils.ts index 708a9e73032..0a3abc28f1a 100644 --- a/packages/react-core/src/helpers/datetimeUtils.ts +++ b/packages/react-core/src/helpers/datetimeUtils.ts @@ -1,4 +1,4 @@ /** * @param {Date} date - A date to check the validity of */ -export const isValidDate = (date: Date) => Boolean(date && !isNaN(date as any)); +export const isValidDate = (date?: Date) => Boolean(date && !isNaN(date as any));