1
- import React , { useState , useRef , useCallback , useEffect } from 'react' ;
1
+ import React , { useState , useRef , useCallback , useEffect , useMemo } from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
import { handleInputChange , normalizeOptions , normalizeDisabled } from './helpers/form-helpers' ;
4
4
import { Dropdown } from '../mixed/Dropdown' ;
@@ -37,17 +37,6 @@ export function FormAutocomplete({
37
37
38
38
const controlFeedback = getFormSubmitedAttempted ( ) ? ( isValid ( ) ? 'is-valid' : 'is-invalid' ) : '' ;
39
39
40
- useEffect ( ( ) => {
41
- searchInputRef . current . setCustomValidity ( controlFeedback === 'is-invalid' ? 'invalid' : '' ) ;
42
- } , [ controlFeedback ] ) ;
43
-
44
- useEffect ( ( ) => {
45
- if ( isEmpty ( value ) && ! isFocused ) {
46
- setSearchValue ( '' ) ;
47
- setSelectedItem ( null ) ;
48
- }
49
- } , [ isFocused , value ] ) ;
50
-
51
40
const onSearchInputType = useCallback (
52
41
( _ , nextSearchValue ) => {
53
42
setSearchValue ( nextSearchValue ) ;
@@ -61,6 +50,14 @@ export function FormAutocomplete({
61
50
[ onSearch , open , setValue , value ]
62
51
) ;
63
52
53
+ const inputHandleChange = useMemo (
54
+ ( ) =>
55
+ handleInputChange . bind ( null , {
56
+ update : onSearchInputType ,
57
+ } ) ,
58
+ [ onSearchInputType ]
59
+ ) ;
60
+
64
61
const onSearchInputFocus = useCallback ( ( ) => {
65
62
if ( openOnFocus ) {
66
63
setTimeout ( ( ) => {
@@ -70,13 +67,18 @@ export function FormAutocomplete({
70
67
} , [ open , openOnFocus ] ) ;
71
68
72
69
const onSearchInputBlur = useCallback ( ( ) => {
70
+ if ( isEmpty ( searchValue ) && value ) {
71
+ setValue ( '' ) ;
72
+ setSelectedItem ( null ) ;
73
+ }
74
+
73
75
if ( ignoreBlur ) {
74
76
searchInputRef . current . focus ( ) ;
75
77
} else {
76
78
close ( ) ;
77
79
setFocus ( false ) ;
78
80
}
79
- } , [ close , ignoreBlur ] ) ;
81
+ } , [ close , ignoreBlur , searchValue , setValue , value ] ) ;
80
82
81
83
const enableSearchInput = useCallback ( ( ) => {
82
84
if ( disabled ) {
@@ -103,16 +105,28 @@ export function FormAutocomplete({
103
105
[ close , setValue ]
104
106
) ;
105
107
108
+ const updateSearchInputValidation = useCallback ( ( ) => {
109
+ searchInputRef . current . setCustomValidity ( controlFeedback === 'is-invalid' ? 'invalid' : '' ) ;
110
+ } , [ controlFeedback ] ) ;
111
+
112
+ const clearSearchValue = useCallback ( ( ) => {
113
+ if ( isEmpty ( value ) && ! isFocused ) {
114
+ setSearchValue ( '' ) ;
115
+ setSelectedItem ( null ) ;
116
+ }
117
+ } , [ isFocused , value ] ) ;
118
+
119
+ useEffect ( updateSearchInputValidation , [ updateSearchInputValidation ] ) ;
120
+ useEffect ( clearSearchValue , [ clearSearchValue ] ) ;
121
+
106
122
return (
107
123
< >
108
124
< input
109
125
{ ...{ placeholder, disabled } }
110
- type = "text "
126
+ type = "search "
111
127
ref = { searchInputRef }
112
128
className = { formatClasses ( [ 'form-control form-autocomplete-search' , isFocused ? '' : 'd-none' , controlFeedback ] ) }
113
- onChange = { handleInputChange . bind ( null , {
114
- update : onSearchInputType ,
115
- } ) }
129
+ onChange = { inputHandleChange }
116
130
onFocus = { onSearchInputFocus }
117
131
onBlur = { onSearchInputBlur }
118
132
value = { searchValue }
@@ -134,12 +148,13 @@ export function FormAutocomplete({
134
148
135
149
< input
136
150
type = "text"
137
- className = { ` form-control d-none` }
151
+ className = { formatClasses ( [ ' form-control' , ' d-none' ] ) }
138
152
{ ...{ name, required, id } }
139
153
onChange = { ( ) => { } }
140
154
value = { getValue ( ) }
141
155
ref = { registerRef }
142
156
/>
157
+
143
158
< Dropdown
144
159
className = "form-autocomplete-dropdown"
145
160
isOpen = { isOpen ( ) }
0 commit comments