11/* eslint-disable react/jsx-no-bind */
2- import { FC } from 'react'
2+ import { FC , forwardRef , KeyboardEvent , useRef , useState } from 'react'
33import { getMonth , getYear } from 'date-fns'
44import { range } from 'lodash'
5- import DatePicker from 'react-datepicker'
5+ import DatePicker , { ReactDatePicker } from 'react-datepicker'
66import classNames from 'classnames'
77import 'react-datepicker/dist/react-datepicker.css'
88
@@ -22,10 +22,10 @@ interface InputDatePickerProps {
2222 readonly hideInlineErrors ?: boolean
2323 readonly hint ?: string
2424 readonly label : string | JSX . Element
25- readonly maxDate ?: Date | null | undefined ;
26- readonly maxTime ?: Date | undefined ;
27- readonly minDate ?: Date | null | undefined ;
28- readonly minTime ?: Date | undefined ;
25+ readonly maxDate ?: Date | null | undefined
26+ readonly maxTime ?: Date | undefined
27+ readonly minDate ?: Date | null | undefined
28+ readonly minTime ?: Date | undefined
2929 readonly placeholder ?: string
3030 readonly showMonthPicker ?: boolean
3131 readonly showYearPicker ?: boolean
@@ -48,7 +48,34 @@ const months: string[] = [
4848 'December' ,
4949]
5050
51+ const CustomInput = forwardRef ( ( props : any , ref ) => {
52+ const { stateHasFocus, datePickerRef, ...remaining } : any = props
53+
54+ function handleKeyDown ( event : KeyboardEvent < HTMLButtonElement > | undefined ) : void {
55+ if ( event ?. key === 'Enter' ) {
56+ event ?. stopPropagation ( )
57+ event ?. preventDefault ( )
58+ datePickerRef . current ?. setOpen ( ! datePickerRef . current ?. isCalendarOpen ( ) , true )
59+ }
60+ }
61+
62+ return (
63+ < input
64+ type = 'text'
65+ ref = { ref }
66+ { ...remaining }
67+ // eslint-disable-next-line jsx-a11y/no-autofocus
68+ autoFocus = { stateHasFocus }
69+ onKeyDown = { handleKeyDown }
70+ />
71+ )
72+ } )
73+
5174const InputDatePicker : FC < InputDatePickerProps > = ( props : InputDatePickerProps ) => {
75+ const datePickerRef = useRef < ReactDatePicker < never , undefined > > ( null )
76+
77+ const [ stateHasFocus , setStateHasFocus ] = useState ( false )
78+
5279 function renderCustomHeader ( {
5380 date,
5481 changeYear,
@@ -112,15 +139,34 @@ const InputDatePicker: FC<InputDatePickerProps> = (props: InputDatePickerProps)
112139 className = { classNames ( props . className , styles . container ) }
113140 >
114141 < DatePicker
142+ ref = { datePickerRef }
143+ customInput = { < CustomInput stateHasFocus = { stateHasFocus } datePickerRef = { datePickerRef } /> }
115144 renderCustomHeader = { renderCustomHeader }
116145 selected = { props . date }
146+ disabled = { props . disabled }
117147 onChange = { (
118148 date : Date | null ,
119149 event : React . SyntheticEvent < any > | undefined ,
120150 ) => {
121151 event ?. stopPropagation ( )
122152 event ?. preventDefault ( )
123153 props . onChange ?.( date )
154+
155+ // re-focus on date input field after select date
156+ const calendarPortal = document . getElementById ( 'react-date-portal' )
157+ if ( calendarPortal ) {
158+ calendarPortal . style . display = 'none'
159+ }
160+
161+ setTimeout ( ( ) => {
162+ datePickerRef . current ?. setFocus ( )
163+ setTimeout ( ( ) => {
164+ datePickerRef . current ?. setOpen ( false , true )
165+ if ( calendarPortal ) {
166+ calendarPortal . style . display = ''
167+ }
168+ } )
169+ } )
124170 } }
125171 placeholderText = { props . placeholder || 'Select a date' }
126172 className = { styles . datePickerWrapper }
@@ -132,6 +178,8 @@ const InputDatePicker: FC<InputDatePickerProps> = (props: InputDatePickerProps)
132178 dateFormat = { props . dateFormat }
133179 popperPlacement = 'bottom'
134180 portalId = 'react-date-portal'
181+ onFocus = { ( ) => setStateHasFocus ( true ) }
182+ onBlur = { ( ) => setStateHasFocus ( false ) }
135183 />
136184 </ InputWrapper >
137185 )
0 commit comments