@@ -376,6 +376,7 @@ export default class DatePicker extends React.Component {
376376 // used to focus day in inline version after month has changed, but not on
377377 // initial render
378378 shouldFocusDayInline : false ,
379+ isRenderAriaLiveMessage : false ,
379380 } ;
380381 } ;
381382
@@ -527,6 +528,7 @@ export default class DatePicker extends React.Component {
527528 this . props . onChangeRaw ( event ) ;
528529 }
529530 this . setSelected ( date , event , false , monthSelectedIn ) ;
531+ this . setState ( { isRenderAriaLiveMessage : true } ) ;
530532 if ( ! this . props . shouldCloseOnSelect || this . props . showTimeSelect ) {
531533 this . setPreSelection ( date ) ;
532534 } else if ( ! this . props . inline ) {
@@ -670,6 +672,9 @@ export default class DatePicker extends React.Component {
670672 if ( this . props . showTimeInput ) {
671673 this . setOpen ( true ) ;
672674 }
675+ if ( this . props . showTimeSelectOnly || this . props . showTimeSelect ) {
676+ this . setState ( { isRenderAriaLiveMessage : true } ) ;
677+ }
673678 this . setState ( { inputValue : null } ) ;
674679 } ;
675680
@@ -1015,6 +1020,75 @@ export default class DatePicker extends React.Component {
10151020 ) ;
10161021 } ;
10171022
1023+ renderAriaLiveRegion = ( ) => {
1024+ const { dateFormat, locale } = this . props ;
1025+ const isContainsTime =
1026+ this . props . showTimeInput || this . props . showTimeSelect ;
1027+ const longDateFormat = isContainsTime ? "PPPPp" : "PPPP" ;
1028+ let ariaLiveMessage ;
1029+
1030+ if ( this . props . selectsRange ) {
1031+ ariaLiveMessage = `Selected start date: ${ safeDateFormat (
1032+ this . props . startDate ,
1033+ {
1034+ dateFormat : longDateFormat ,
1035+ locale,
1036+ }
1037+ ) } . ${
1038+ this . props . endDate
1039+ ? "End date: " +
1040+ safeDateFormat ( this . props . endDate , {
1041+ dateFormat : longDateFormat ,
1042+ locale,
1043+ } )
1044+ : ""
1045+ } `;
1046+ } else {
1047+ if ( this . props . showTimeSelectOnly ) {
1048+ ariaLiveMessage = `Selected time: ${ safeDateFormat (
1049+ this . props . selected ,
1050+ { dateFormat, locale }
1051+ ) } `;
1052+ } else if ( this . props . showYearPicker ) {
1053+ ariaLiveMessage = `Selected year: ${ safeDateFormat (
1054+ this . props . selected ,
1055+ { dateFormat : "yyyy" , locale }
1056+ ) } `;
1057+ } else if ( this . props . showMonthYearPicker ) {
1058+ ariaLiveMessage = `Selected month: ${ safeDateFormat (
1059+ this . props . selected ,
1060+ { dateFormat : "MMMM yyyy" , locale }
1061+ ) } `;
1062+ } else if ( this . props . showQuarterYearPicker ) {
1063+ ariaLiveMessage = `Selected quarter: ${ safeDateFormat (
1064+ this . props . selected ,
1065+ {
1066+ dateFormat : "yyyy, QQQ" ,
1067+ locale,
1068+ }
1069+ ) } `;
1070+ } else {
1071+ ariaLiveMessage = `Selected date: ${ safeDateFormat (
1072+ this . props . selected ,
1073+ {
1074+ dateFormat : longDateFormat ,
1075+ locale,
1076+ }
1077+ ) } `;
1078+ }
1079+ }
1080+
1081+ return (
1082+ < span
1083+ role = "alert"
1084+ aria-live = "polite"
1085+ className = "react-datepicker__aria-live"
1086+ >
1087+ { this . state . isRenderAriaLiveMessage && ariaLiveMessage }
1088+ </ span >
1089+ ) ;
1090+ } ;
1091+
10181092 renderDateInput = ( ) => {
10191093 const className = classnames ( this . props . className , {
10201094 [ outsideClickIgnoreClass ] : this . state . open ,
@@ -1096,6 +1170,7 @@ export default class DatePicker extends React.Component {
10961170 renderInputContainer ( ) {
10971171 return (
10981172 < div className = "react-datepicker__input-container" >
1173+ { this . renderAriaLiveRegion ( ) }
10991174 { this . renderDateInput ( ) }
11001175 { this . renderClearButton ( ) }
11011176 </ div >
0 commit comments