@@ -464,6 +464,37 @@ const isDatesYearOutsideMinOrMax = (date, minDate, maxDate) =>
464464 lastDayOfMonth ( setMonth ( date , 11 ) ) < minDate ||
465465 ( maxDate && startOfMonth ( setMonth ( date , 0 ) ) > maxDate ) ;
466466
467+ /**
468+ * @typedef {Object } DateRangeContext
469+ * @property {Date } rangeStartDate
470+ * @property {Date } rangeEndDate
471+ * @property {Date } withinRangeStartDate
472+ * @property {Date } withinRangeEndDate
473+ */
474+
475+ /**
476+ * Set the start, end, and within range values for date range variants.
477+
478+ * @param {Date } date - Date that concludes the date range.
479+ * @param {Date } rangeDate - Range date data attribute value of the date picker component.
480+ * @returns {DateRangeContext } - Dates for range selection.
481+ */
482+ const setRangeDates = ( date , rangeDate ) => {
483+ const rangeConclusionDate = date ;
484+ const rangeStartDate = rangeDate && min ( rangeConclusionDate , rangeDate ) ;
485+ const rangeEndDate = rangeDate && max ( rangeConclusionDate , rangeDate ) ;
486+
487+ const withinRangeStartDate = rangeDate && addDays ( rangeStartDate , 1 ) ;
488+ const withinRangeEndDate = rangeDate && subDays ( rangeEndDate , 1 ) ;
489+
490+ return {
491+ rangeStartDate,
492+ rangeEndDate,
493+ withinRangeStartDate,
494+ withinRangeEndDate,
495+ } ;
496+ } ;
497+
467498/**
468499 * Parse a date with format M-D-YY
469500 *
@@ -951,12 +982,12 @@ const renderCalendar = (el, _dateToDisplay) => {
951982 const prevButtonsDisabled = isSameMonth ( dateToDisplay , minDate ) ;
952983 const nextButtonsDisabled = isSameMonth ( dateToDisplay , maxDate ) ;
953984
954- const rangeConclusionDate = selectedDate || dateToDisplay ;
955- const rangeStartDate = rangeDate && min ( rangeConclusionDate , rangeDate ) ;
956- const rangeEndDate = rangeDate && max ( rangeConclusionDate , rangeDate ) ;
957-
958- const withinRangeStartDate = rangeDate && addDays ( rangeStartDate , 1 ) ;
959- const withinRangeEndDate = rangeDate && subDays ( rangeEndDate , 1 ) ;
985+ const {
986+ rangeStartDate ,
987+ rangeEndDate ,
988+ withinRangeStartDate ,
989+ withinRangeEndDate ,
990+ } = setRangeDates ( selectedDate || dateToDisplay , rangeDate ) ;
960991
961992 const monthLabel = MONTH_LABELS [ focusedMonth ] ;
962993
@@ -1785,24 +1816,43 @@ const handleShiftPageDownFromDate = adjustCalendar((date) => addYears(date, 1));
17851816const handleShiftPageUpFromDate = adjustCalendar ( ( date ) => subYears ( date , 1 ) ) ;
17861817
17871818/**
1788- * display the calendar for the mouseover date.
1819+ * Set range date classes without re-rendering the calendar. Called when date button is hovered.
1820+ * Returns early if the date hovered is disabled or if there is already a selected date.
17891821 *
1790- * @param {MouseEvent } event The mouseover event
1791- * @param {HTMLButtonElement } dateEl A date element within the date picker component
1822+ * @param {HTMLElement } dateEl - Calendar date button within the date picker component.
17921823 */
1824+
17931825const handleMouseoverFromDate = ( dateEl ) => {
17941826 if ( dateEl . disabled ) return ;
17951827
1796- const calendarEl = dateEl . closest ( DATE_PICKER_CALENDAR ) ;
1828+ const hoverDate = parseDateString ( dateEl . dataset . value ) ;
1829+ const { calendarEl, selectedDate, rangeDate } = getDatePickerContext ( dateEl ) ;
17971830
1798- const currentCalendarDate = calendarEl . dataset . value ;
1799- const hoverDate = dateEl . dataset . value ;
1831+ if ( selectedDate ) return ;
18001832
1801- if ( hoverDate === currentCalendarDate ) return ;
1833+ const { withinRangeStartDate, withinRangeEndDate } = setRangeDates (
1834+ hoverDate ,
1835+ rangeDate ,
1836+ ) ;
18021837
1803- const dateToDisplay = parseDateString ( hoverDate ) ;
1804- const newCalendar = renderCalendar ( calendarEl , dateToDisplay ) ;
1805- newCalendar . querySelector ( CALENDAR_DATE_FOCUSED ) . focus ( ) ;
1838+ const dateButtons = calendarEl . querySelectorAll (
1839+ `.${ CALENDAR_DATE_CURRENT_MONTH_CLASS } ` ,
1840+ ) ;
1841+
1842+ dateButtons . forEach ( ( button ) => {
1843+ const buttonDate = parseDateString ( button . dataset . value ) ;
1844+ if (
1845+ isDateWithinMinAndMax (
1846+ buttonDate ,
1847+ withinRangeStartDate ,
1848+ withinRangeEndDate ,
1849+ )
1850+ ) {
1851+ button . classList . add ( CALENDAR_DATE_WITHIN_RANGE_CLASS ) ;
1852+ } else {
1853+ button . classList . remove ( CALENDAR_DATE_WITHIN_RANGE_CLASS ) ;
1854+ }
1855+ } ) ;
18061856} ;
18071857
18081858// #endregion Calendar Date Event Handling
@@ -1896,22 +1946,6 @@ const handlePageDownFromMonth = adjustMonthSelectionScreen(() => 11);
18961946 */
18971947const handlePageUpFromMonth = adjustMonthSelectionScreen ( ( ) => 0 ) ;
18981948
1899- /**
1900- * update the focus on a month when the mouse moves.
1901- *
1902- * @param {MouseEvent } event The mouseover event
1903- * @param {HTMLButtonElement } monthEl A month element within the date picker component
1904- */
1905- const handleMouseoverFromMonth = ( monthEl ) => {
1906- if ( monthEl . disabled ) return ;
1907- if ( monthEl . classList . contains ( CALENDAR_MONTH_FOCUSED_CLASS ) ) return ;
1908-
1909- const focusMonth = parseInt ( monthEl . dataset . value , 10 ) ;
1910-
1911- const newCalendar = displayMonthSelection ( monthEl , focusMonth ) ;
1912- newCalendar . querySelector ( CALENDAR_MONTH_FOCUSED ) . focus ( ) ;
1913- } ;
1914-
19151949// #endregion Calendar Month Event Handling
19161950
19171951// #region Calendar Year Event Handling
@@ -2007,22 +2041,6 @@ const handlePageDownFromYear = adjustYearSelectionScreen(
20072041 ( year ) => year + YEAR_CHUNK ,
20082042) ;
20092043
2010- /**
2011- * update the focus on a year when the mouse moves.
2012- *
2013- * @param {MouseEvent } event The mouseover event
2014- * @param {HTMLButtonElement } dateEl A year element within the date picker component
2015- */
2016- const handleMouseoverFromYear = ( yearEl ) => {
2017- if ( yearEl . disabled ) return ;
2018- if ( yearEl . classList . contains ( CALENDAR_YEAR_FOCUSED_CLASS ) ) return ;
2019-
2020- const focusYear = parseInt ( yearEl . dataset . value , 10 ) ;
2021-
2022- const newCalendar = displayYearSelection ( yearEl , focusYear ) ;
2023- newCalendar . querySelector ( CALENDAR_YEAR_FOCUSED ) . focus ( ) ;
2024- } ;
2025-
20262044// #endregion Calendar Year Event Handling
20272045
20282046// #region Focus Handling Event Handling
@@ -2230,12 +2248,6 @@ if (!isIosDevice()) {
22302248 [ CALENDAR_DATE_CURRENT_MONTH ] ( ) {
22312249 handleMouseoverFromDate ( this ) ;
22322250 } ,
2233- [ CALENDAR_MONTH ] ( ) {
2234- handleMouseoverFromMonth ( this ) ;
2235- } ,
2236- [ CALENDAR_YEAR ] ( ) {
2237- handleMouseoverFromYear ( this ) ;
2238- } ,
22392251 } ;
22402252}
22412253
0 commit comments