1
1
/* eslint-disable react/jsx-no-bind */
2
- import { FC } from 'react'
2
+ import { FC , forwardRef , KeyboardEvent , useRef , useState } from 'react'
3
3
import { getMonth , getYear } from 'date-fns'
4
4
import { range } from 'lodash'
5
- import DatePicker from 'react-datepicker'
5
+ import DatePicker , { ReactDatePicker } from 'react-datepicker'
6
6
import classNames from 'classnames'
7
7
import 'react-datepicker/dist/react-datepicker.css'
8
8
@@ -22,10 +22,10 @@ interface InputDatePickerProps {
22
22
readonly hideInlineErrors ?: boolean
23
23
readonly hint ?: string
24
24
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
29
29
readonly placeholder ?: string
30
30
readonly showMonthPicker ?: boolean
31
31
readonly showYearPicker ?: boolean
@@ -48,7 +48,34 @@ const months: string[] = [
48
48
'December' ,
49
49
]
50
50
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
+
51
74
const InputDatePicker : FC < InputDatePickerProps > = ( props : InputDatePickerProps ) => {
75
+ const datePickerRef = useRef < ReactDatePicker < never , undefined > > ( null )
76
+
77
+ const [ stateHasFocus , setStateHasFocus ] = useState ( false )
78
+
52
79
function renderCustomHeader ( {
53
80
date,
54
81
changeYear,
@@ -112,15 +139,34 @@ const InputDatePicker: FC<InputDatePickerProps> = (props: InputDatePickerProps)
112
139
className = { classNames ( props . className , styles . container ) }
113
140
>
114
141
< DatePicker
142
+ ref = { datePickerRef }
143
+ customInput = { < CustomInput stateHasFocus = { stateHasFocus } datePickerRef = { datePickerRef } /> }
115
144
renderCustomHeader = { renderCustomHeader }
116
145
selected = { props . date }
146
+ disabled = { props . disabled }
117
147
onChange = { (
118
148
date : Date | null ,
119
149
event : React . SyntheticEvent < any > | undefined ,
120
150
) => {
121
151
event ?. stopPropagation ( )
122
152
event ?. preventDefault ( )
123
153
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
+ } )
124
170
} }
125
171
placeholderText = { props . placeholder || 'Select a date' }
126
172
className = { styles . datePickerWrapper }
@@ -132,6 +178,8 @@ const InputDatePicker: FC<InputDatePickerProps> = (props: InputDatePickerProps)
132
178
dateFormat = { props . dateFormat }
133
179
popperPlacement = 'bottom'
134
180
portalId = 'react-date-portal'
181
+ onFocus = { ( ) => setStateHasFocus ( true ) }
182
+ onBlur = { ( ) => setStateHasFocus ( false ) }
135
183
/>
136
184
</ InputWrapper >
137
185
)
0 commit comments