diff --git a/packages/components/src/date-time/date.js b/packages/components/src/date-time/date.js index 0d5058789f17f..7361494a61e68 100644 --- a/packages/components/src/date-time/date.js +++ b/packages/components/src/date-time/date.js @@ -7,7 +7,7 @@ import { DayPickerSingleDateController } from 'react-dates'; /** * WordPress dependencies */ -import { Component } from '@wordpress/element'; +import { Component, createRef } from '@wordpress/element'; /** * Module Constants @@ -20,6 +20,30 @@ class DatePicker extends Component { super( ...arguments ); this.onChangeMoment = this.onChangeMoment.bind( this ); + this.nodeRef = createRef(); + this.keepFocusInside = this.keepFocusInside.bind( this ); + } + + /* + * Todo: We should remove this function ASAP. + * It is kept because focus is lost when we click on the previous and next month buttons. + * This focus loss closes the date picker popover. + * Ideally we should add an upstream commit on react-dates to fix this issue. + */ + keepFocusInside() { + if ( ! this.nodeRef.current ) { + return; + } + // If focus was lost. + if ( ! document.activeElement || ! this.nodeRef.current.contains( document.activeElement ) ) { + // Retrieve the focus region div. + const focusRegion = this.nodeRef.current.querySelector( '.DayPicker_focusRegion' ); + if ( ! focusRegion ) { + return; + } + // Keep the focus on focus region. + focusRegion.focus(); + } } onChangeMoment( newDate ) { @@ -56,7 +80,10 @@ class DatePicker extends Component { const momentDate = this.getMomentDate( currentDate ); return ( -
+
{ return isInvalidDate && isInvalidDate( date.toDate() ); } } + onPrevMonthClick={ this.keepFocusInside } + onNextMonthClick={ this.keepFocusInside } />
);