@@ -17,6 +17,7 @@ import {
17
17
useMemo ,
18
18
useReducer ,
19
19
useRef ,
20
+ useState ,
20
21
} from 'react'
21
22
import { EMPTY_ARRAY , EMPTY_RECORD } from '../../constants'
22
23
import { _hasFocus , _raf , focusFirstDescendant } from '../../helpers'
@@ -184,21 +185,22 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
184
185
typeof filterOptionProp === 'function' ? filterOptionProp : DEFAULT_FILTER_OPTION
185
186
186
187
// Element refs
187
- const rootElementRef = useRef < HTMLDivElement | null > ( null )
188
- const resultsPopoverElementRef = useRef < HTMLDivElement | null > ( null )
189
- const inputElementRef = useRef < HTMLInputElement | null > ( null )
188
+ const [ rootElement , setRootElement ] = useState < HTMLDivElement | null > ( null )
189
+ const [ resultsPopoverElement , setResultsPopoverElement ] = useState < HTMLDivElement | null > ( null )
190
+ const [ inputElement , setInputElement ] = useState < HTMLInputElement | null > ( null )
190
191
const listBoxElementRef = useRef < HTMLDivElement | null > ( null )
191
192
192
193
// Value refs
193
194
const listFocusedRef = useRef ( false )
194
195
const valueRef = useRef ( value )
195
196
const valuePropRef = useRef ( valueProp )
196
- const popoverMouseWithinRef = useRef ( false )
197
+ const [ popoverMouseWithin , setPopoverMouseWithin ] = useState ( false )
197
198
198
199
// Forward ref to parent
199
200
useImperativeHandle < HTMLInputElement | null , HTMLInputElement | null > (
200
201
forwardedRef ,
201
- ( ) => inputElementRef . current ,
202
+ ( ) => inputElement ,
203
+ [ inputElement ] ,
202
204
)
203
205
204
206
const listBoxId = `${ id } -listbox`
@@ -222,13 +224,13 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
222
224
// NOTE: This is a workaround for a bug that may happen in Chrome (clicking the scrollbar
223
225
// closes the results in certain situations):
224
226
// - Do not handle blur if the mouse is within the popover
225
- if ( popoverMouseWithinRef . current ) {
227
+ if ( popoverMouseWithin ) {
226
228
return
227
229
}
228
230
229
231
const elements : HTMLElement [ ] = ( relatedElements || [ ] ) . concat (
230
- rootElementRef . current ? [ rootElementRef . current ] : [ ] ,
231
- resultsPopoverElementRef . current ? [ resultsPopoverElementRef . current ] : [ ] ,
232
+ rootElement ? [ rootElement ] : [ ] ,
233
+ resultsPopoverElement ? [ resultsPopoverElement ] : [ ] ,
232
234
)
233
235
234
236
let focusInside = false
@@ -244,13 +246,20 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
244
246
245
247
if ( focusInside === false ) {
246
248
dispatch ( { type : 'root/blur' } )
247
- popoverMouseWithinRef . current = false
249
+ setPopoverMouseWithin ( false )
248
250
if ( onQueryChange ) onQueryChange ( null )
249
251
if ( onBlur ) onBlur ( event )
250
252
}
251
253
} , 0 )
252
254
} ,
253
- [ onBlur , onQueryChange , relatedElements ] ,
255
+ [
256
+ onBlur ,
257
+ onQueryChange ,
258
+ popoverMouseWithin ,
259
+ relatedElements ,
260
+ resultsPopoverElement ,
261
+ rootElement ,
262
+ ] ,
254
263
)
255
264
256
265
const handleRootFocus = useCallback ( ( event : FocusEvent < HTMLDivElement > ) => {
@@ -269,7 +278,7 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
269
278
( v : string ) => {
270
279
dispatch ( { type : 'value/change' , value : v } )
271
280
272
- popoverMouseWithinRef . current = false
281
+ setPopoverMouseWithin ( false )
273
282
274
283
if ( onSelect ) onSelect ( v )
275
284
@@ -278,9 +287,9 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
278
287
if ( onChange ) onChange ( v )
279
288
if ( onQueryChange ) onQueryChange ( null )
280
289
281
- inputElementRef . current ?. focus ( )
290
+ inputElement ?. focus ( )
282
291
} ,
283
- [ onChange , onSelect , onQueryChange ] ,
292
+ [ onSelect , onChange , onQueryChange , inputElement ] ,
284
293
)
285
294
286
295
const handleRootKeyDown = useCallback (
@@ -324,9 +333,9 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
324
333
325
334
if ( event . key === 'Escape' ) {
326
335
dispatch ( { type : 'root/escape' } )
327
- popoverMouseWithinRef . current = false
336
+ setPopoverMouseWithin ( false )
328
337
if ( onQueryChange ) onQueryChange ( null )
329
- inputElementRef . current ?. focus ( )
338
+ inputElement ?. focus ( )
330
339
331
340
return
332
341
}
@@ -338,12 +347,12 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
338
347
( listEl === target || listEl ?. contains ( target ) ) &&
339
348
! AUTOCOMPLETE_LISTBOX_IGNORE_KEYS . includes ( event . key )
340
349
) {
341
- inputElementRef . current ?. focus ( )
350
+ inputElement ?. focus ( )
342
351
343
352
return
344
353
}
345
354
} ,
346
- [ activeValue , filteredOptions , filteredOptionsLen , onQueryChange ] ,
355
+ [ activeValue , filteredOptions , filteredOptionsLen , inputElement , onQueryChange ] ,
347
356
)
348
357
349
358
const handleInputChange = useCallback (
@@ -377,20 +386,20 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
377
386
)
378
387
379
388
const handlePopoverMouseEnter = useCallback ( ( ) => {
380
- popoverMouseWithinRef . current = true
389
+ setPopoverMouseWithin ( true )
381
390
} , [ ] )
382
391
383
392
const handlePopoverMouseLeave = useCallback ( ( ) => {
384
- popoverMouseWithinRef . current = false
393
+ setPopoverMouseWithin ( false )
385
394
} , [ ] )
386
395
387
396
const handleClearButtonClick = useCallback ( ( ) => {
388
397
dispatch ( { type : 'root/clear' } )
389
398
valueRef . current = ''
390
399
if ( onChange ) onChange ( '' )
391
400
if ( onQueryChange ) onQueryChange ( null )
392
- inputElementRef . current ?. focus ( )
393
- } , [ onChange , onQueryChange ] )
401
+ inputElement ?. focus ( )
402
+ } , [ inputElement , onChange , onQueryChange ] )
394
403
395
404
const handleClearButtonFocus = useCallback ( ( ) => {
396
405
dispatch ( { type : 'input/focus' } )
@@ -482,9 +491,9 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
482
491
483
492
if ( openButtonProps . onClick ) openButtonProps . onClick ( event )
484
493
485
- _raf ( ( ) => inputElementRef . current ?. focus ( ) )
494
+ _raf ( ( ) => inputElement ?. focus ( ) )
486
495
} ,
487
- [ openButtonProps , dispatchOpen ] ,
496
+ [ dispatchOpen , openButtonProps , inputElement ] ,
488
497
)
489
498
490
499
const openButtonNode = useMemo (
@@ -554,7 +563,7 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
554
563
prefix = { prefix }
555
564
radius = { radius }
556
565
readOnly = { readOnly }
557
- ref = { inputElementRef }
566
+ ref = { setInputElement }
558
567
role = "combobox"
559
568
spellCheck = { false }
560
569
suffix = { suffix || openButtonNode }
@@ -566,10 +575,10 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
566
575
( event : KeyboardEvent < HTMLDivElement > ) => {
567
576
// If the focus is currently in the list, move focus to the input element
568
577
if ( event . key === 'Tab' ) {
569
- if ( listFocused ) inputElementRef . current ?. focus ( )
578
+ if ( listFocused ) inputElement ?. focus ( )
570
579
}
571
580
} ,
572
- [ listFocused ] ,
581
+ [ inputElement , listFocused ] ,
573
582
)
574
583
575
584
const content = useMemo ( ( ) => {
@@ -635,11 +644,11 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
635
644
{
636
645
content,
637
646
hidden : ! expanded ,
638
- inputElement : inputElementRef . current ,
647
+ inputElement,
639
648
onMouseEnter : handlePopoverMouseEnter ,
640
649
onMouseLeave : handlePopoverMouseLeave ,
641
650
} ,
642
- resultsPopoverElementRef ,
651
+ { current : resultsPopoverElement } ,
643
652
)
644
653
}
645
654
@@ -661,8 +670,8 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
661
670
placement = { AUTOCOMPLETE_POPOVER_PLACEMENT }
662
671
portal
663
672
radius = { radius }
664
- ref = { resultsPopoverElementRef }
665
- referenceElement = { inputElementRef . current }
673
+ ref = { setResultsPopoverElement }
674
+ referenceElement = { inputElement }
666
675
{ ...popover }
667
676
/>
668
677
)
@@ -672,9 +681,11 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
672
681
filteredOptionsLen ,
673
682
handlePopoverMouseEnter ,
674
683
handlePopoverMouseLeave ,
684
+ inputElement ,
675
685
popover ,
676
686
radius ,
677
687
renderPopover ,
688
+ resultsPopoverElement ,
678
689
] )
679
690
680
691
return (
@@ -683,7 +694,7 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
683
694
onBlur = { handleRootBlur }
684
695
onFocus = { handleRootFocus }
685
696
onKeyDown = { handleRootKeyDown }
686
- ref = { rootElementRef }
697
+ ref = { setRootElement }
687
698
>
688
699
{ input }
689
700
{ results }
0 commit comments