@@ -144,17 +144,30 @@ export function connect<T extends PropTypes>(
144144
145145 const decadeYears = getDecadeRange ( startValue . year , { strict : true } )
146146 const isOutsideVisibleRange = ! decadeYears . includes ( value )
147- const isOutsideRange = isValueWithinRange ( value , min ?. year , max ?. year )
147+ const isWithinMinMax = isValueWithinRange ( value , min ?. year , max ?. year )
148+
149+ const isInSelectedRange = isRangePicker && isDateWithinRange ( dateValue , selectedValue )
150+ const isFirstInSelectedRange = isRangePicker && selectedValue [ 0 ] && isEqualYear ( dateValue , selectedValue [ 0 ] )
151+ const isLastInSelectedRange = isRangePicker && selectedValue [ 1 ] && isEqualYear ( dateValue , selectedValue [ 1 ] )
152+
153+ const hasHoveredRange = isRangePicker && hoveredRangeValue . length > 0
154+ const isInHoveredRange = hasHoveredRange && isDateWithinRange ( dateValue , hoveredRangeValue )
155+ const isFirstInHoveredRange =
156+ hasHoveredRange && hoveredRangeValue [ 0 ] && isEqualYear ( dateValue , hoveredRangeValue [ 0 ] )
157+ const isLastInHoveredRange = hasHoveredRange && hoveredRangeValue [ 1 ] && isEqualYear ( dateValue , hoveredRangeValue [ 1 ] )
148158
149159 const cellState = {
150160 focused : focusedValue . year === props . value ,
151- selectable : isOutsideVisibleRange || isOutsideRange ,
161+ selectable : ! isOutsideVisibleRange && isWithinMinMax ,
152162 outsideRange : isOutsideVisibleRange ,
153163 selected : ! ! selectedValue . find ( ( date ) => date && date . year === value ) ,
154164 valueText : value . toString ( ) ,
155- inRange :
156- isRangePicker &&
157- ( isDateWithinRange ( dateValue , selectedValue ) || isDateWithinRange ( dateValue , hoveredRangeValue ) ) ,
165+ inRange : isInSelectedRange || isInHoveredRange ,
166+ firstInRange : ! ! isFirstInSelectedRange ,
167+ lastInRange : ! ! isLastInSelectedRange ,
168+ inHoveredRange : ! ! isInHoveredRange ,
169+ firstInHoveredRange : ! ! isFirstInHoveredRange ,
170+ lastInHoveredRange : ! ! isLastInHoveredRange ,
158171 value : dateValue ,
159172 get disabled ( ) {
160173 return disabled || ! cellState . selectable
@@ -167,14 +180,30 @@ export function connect<T extends PropTypes>(
167180 const { value, disabled } = props
168181 const dateValue = focusedValue . set ( { month : value } )
169182 const formatter = getMonthFormatter ( locale , timeZone , focusedValue )
183+
184+ const isInSelectedRange = isRangePicker && isDateWithinRange ( dateValue , selectedValue )
185+ const isFirstInSelectedRange = isRangePicker && selectedValue [ 0 ] && isEqualMonth ( dateValue , selectedValue [ 0 ] )
186+ const isLastInSelectedRange = isRangePicker && selectedValue [ 1 ] && isEqualMonth ( dateValue , selectedValue [ 1 ] )
187+
188+ const hasHoveredRange = isRangePicker && hoveredRangeValue . length > 0
189+ const isInHoveredRange = hasHoveredRange && isDateWithinRange ( dateValue , hoveredRangeValue )
190+ const isFirstInHoveredRange =
191+ hasHoveredRange && hoveredRangeValue [ 0 ] && isEqualMonth ( dateValue , hoveredRangeValue [ 0 ] )
192+ const isLastInHoveredRange =
193+ hasHoveredRange && hoveredRangeValue [ 1 ] && isEqualMonth ( dateValue , hoveredRangeValue [ 1 ] )
194+
170195 const cellState = {
171196 focused : focusedValue . month === props . value ,
172197 selectable : ! isDateOutsideRange ( dateValue , min , max ) ,
173198 selected : ! ! selectedValue . find ( ( date ) => date && date . month === value && date . year === focusedValue . year ) ,
174199 valueText : formatter . format ( dateValue . toDate ( timeZone ) ) ,
175- inRange :
176- isRangePicker &&
177- ( isDateWithinRange ( dateValue , selectedValue ) || isDateWithinRange ( dateValue , hoveredRangeValue ) ) ,
200+ inRange : isInSelectedRange || isInHoveredRange ,
201+ firstInRange : ! ! isFirstInSelectedRange ,
202+ lastInRange : ! ! isLastInSelectedRange ,
203+ inHoveredRange : ! ! isInHoveredRange ,
204+ firstInHoveredRange : ! ! isFirstInHoveredRange ,
205+ lastInHoveredRange : ! ! isLastInHoveredRange ,
206+ outsideRange : false ,
178207 value : dateValue ,
179208 get disabled ( ) {
180209 return disabled || ! cellState . selectable
@@ -220,13 +249,11 @@ export function connect<T extends PropTypes>(
220249 outsideRange : isOutsideRange ,
221250 today : isToday ( value , timeZone ) ,
222251 weekend : isWeekend ( value , locale ) ,
223- formattedDate : formatter . format ( value . toDate ( timeZone ) ) ,
252+ value,
253+ valueText : formatter . format ( value . toDate ( timeZone ) ) ,
224254 get focused ( ) {
225255 return isDateEqual ( value , focusedValue ) && ( ! cellState . outsideRange || outsideDaySelectable )
226256 } ,
227- get ariaLabel ( ) : string {
228- return translations . dayCell ( cellState )
229- } ,
230257 get selectable ( ) {
231258 return ! cellState . disabled && ! cellState . unavailable
232259 } ,
@@ -611,7 +638,7 @@ export function connect<T extends PropTypes>(
611638 role : "button" ,
612639 dir : prop ( "dir" ) ,
613640 tabIndex : cellState . focused ? 0 : - 1 ,
614- "aria-label" : cellState . ariaLabel ,
641+ "aria-label" : translations . dayCell ( cellState ) ,
615642 "aria-disabled" : ariaAttr ( ! cellState . selectable ) ,
616643 "aria-invalid" : ariaAttr ( cellState . invalid ) ,
617644 "data-disabled" : dataAttr ( ! cellState . selectable ) ,
@@ -668,19 +695,24 @@ export function connect<T extends PropTypes>(
668695 const cellState = getMonthTableCellState ( props )
669696 return normalize . element ( {
670697 ...parts . tableCellTrigger . attrs ,
671- dir : prop ( "dir" ) ,
672- role : "button" ,
673698 id : dom . getCellTriggerId ( scope , value . toString ( ) ) ,
674- "data-selected" : dataAttr ( cellState . selected ) ,
699+ role : "button" ,
700+ dir : prop ( "dir" ) ,
701+ tabIndex : cellState . focused ? 0 : - 1 ,
702+ "aria-label" : cellState . valueText ,
675703 "aria-disabled" : ariaAttr ( ! cellState . selectable ) ,
676704 "data-disabled" : dataAttr ( ! cellState . selectable ) ,
705+ "data-selected" : dataAttr ( cellState . selected ) ,
706+ "data-value" : value ,
707+ "data-view" : "month" ,
677708 "data-focus" : dataAttr ( cellState . focused ) ,
678- "data-in-range" : dataAttr ( cellState . inRange ) ,
679709 "data-outside-range" : dataAttr ( cellState . outsideRange ) ,
680- "aria-label" : cellState . valueText ,
681- "data-view" : "month" ,
682- "data-value" : value ,
683- tabIndex : cellState . focused ? 0 : - 1 ,
710+ "data-range-start" : dataAttr ( cellState . firstInRange ) ,
711+ "data-range-end" : dataAttr ( cellState . lastInRange ) ,
712+ "data-in-range" : dataAttr ( cellState . inRange ) ,
713+ "data-in-hover-range" : dataAttr ( cellState . inHoveredRange ) ,
714+ "data-hover-range-start" : dataAttr ( cellState . firstInHoveredRange ) ,
715+ "data-hover-range-end" : dataAttr ( cellState . lastInHoveredRange ) ,
684716 onClick ( event ) {
685717 if ( event . defaultPrevented ) return
686718 if ( ! cellState . selectable ) return
@@ -708,7 +740,7 @@ export function connect<T extends PropTypes>(
708740 dir : prop ( "dir" ) ,
709741 colSpan : columns ,
710742 role : "gridcell" ,
711- "aria-selected" : ariaAttr ( cellState . selected ) ,
743+ "aria-selected" : ariaAttr ( cellState . selected || cellState . inRange ) ,
712744 "data-selected" : dataAttr ( cellState . selected ) ,
713745 "aria-disabled" : ariaAttr ( ! cellState . selectable ) ,
714746 "data-value" : value ,
@@ -720,19 +752,24 @@ export function connect<T extends PropTypes>(
720752 const cellState = getYearTableCellState ( props )
721753 return normalize . element ( {
722754 ...parts . tableCellTrigger . attrs ,
723- dir : prop ( "dir" ) ,
724- role : "button" ,
725755 id : dom . getCellTriggerId ( scope , value . toString ( ) ) ,
726- "data-selected" : dataAttr ( cellState . selected ) ,
727- "data-focus" : dataAttr ( cellState . focused ) ,
728- "data-in-range" : dataAttr ( cellState . inRange ) ,
756+ role : "button" ,
757+ dir : prop ( "dir" ) ,
758+ tabIndex : cellState . focused ? 0 : - 1 ,
759+ "aria-label" : cellState . valueText ,
729760 "aria-disabled" : ariaAttr ( ! cellState . selectable ) ,
730761 "data-disabled" : dataAttr ( ! cellState . selectable ) ,
731- "aria-label" : cellState . valueText ,
732- "data-outside-range" : dataAttr ( cellState . outsideRange ) ,
762+ "data-selected" : dataAttr ( cellState . selected ) ,
733763 "data-value" : value ,
734764 "data-view" : "year" ,
735- tabIndex : cellState . focused ? 0 : - 1 ,
765+ "data-focus" : dataAttr ( cellState . focused ) ,
766+ "data-outside-range" : dataAttr ( cellState . outsideRange ) ,
767+ "data-range-start" : dataAttr ( cellState . firstInRange ) ,
768+ "data-range-end" : dataAttr ( cellState . lastInRange ) ,
769+ "data-in-range" : dataAttr ( cellState . inRange ) ,
770+ "data-in-hover-range" : dataAttr ( cellState . inHoveredRange ) ,
771+ "data-hover-range-start" : dataAttr ( cellState . firstInHoveredRange ) ,
772+ "data-hover-range-end" : dataAttr ( cellState . lastInHoveredRange ) ,
736773 onClick ( event ) {
737774 if ( event . defaultPrevented ) return
738775 if ( ! cellState . selectable ) return
0 commit comments