3
3
Dispatch ,
4
4
FC ,
5
5
FocusEvent ,
6
+ KeyboardEvent ,
6
7
MouseEvent ,
7
8
MutableRefObject ,
8
9
ReactNode ,
@@ -41,7 +42,9 @@ interface InputSelectProps {
41
42
42
43
const InputSelect : FC < InputSelectProps > = ( props : InputSelectProps ) => {
43
44
const triggerRef : MutableRefObject < any > = useRef ( undefined )
45
+ const buttonRef : MutableRefObject < HTMLButtonElement | null > = useRef ( null )
44
46
const [ menuIsVisible , setMenuIsVisible ] : [ boolean , Dispatch < SetStateAction < boolean > > ] = useState ( false )
47
+ const [ isFocus , setIsFocus ] : [ boolean , Dispatch < SetStateAction < boolean > > ] = useState ( false )
45
48
46
49
const selectedOption : InputSelectOption | undefined = props . options . find ( option => option . value === props . value )
47
50
@@ -60,10 +63,17 @@ const InputSelect: FC<InputSelectProps> = (props: InputSelectProps) => {
60
63
props . onChange ( {
61
64
target : { value : option . value } ,
62
65
} as unknown as ChangeEvent < HTMLInputElement > )
63
- toggleMenu ( )
66
+ buttonRef . current ?. focus ( ) // this will close the dropdown menu
64
67
}
65
68
66
- function toggleIfNotDisabled ( ) : void {
69
+ function toggleIfNotDisabled ( event :
70
+ MouseEvent < HTMLButtonElement >
71
+ | FocusEvent < HTMLButtonElement >
72
+ | KeyboardEvent < HTMLButtonElement >
73
+ | undefined )
74
+ : void {
75
+ event ?. stopPropagation ( )
76
+ event ?. preventDefault ( )
67
77
if ( props . disabled ) {
68
78
return
69
79
}
@@ -73,6 +83,12 @@ const InputSelect: FC<InputSelectProps> = (props: InputSelectProps) => {
73
83
74
84
useClickOutside ( triggerRef . current , ( ) => setMenuIsVisible ( false ) )
75
85
86
+ function handleKeyDown ( event : KeyboardEvent < HTMLButtonElement > | undefined ) : void {
87
+ if ( event ?. key === 'Enter' ) {
88
+ toggleIfNotDisabled ( event )
89
+ }
90
+ }
91
+
76
92
return (
77
93
< InputWrapper
78
94
{ ...props }
@@ -84,19 +100,23 @@ const InputSelect: FC<InputSelectProps> = (props: InputSelectProps) => {
84
100
className = { styles [ 'select-input-wrapper' ] }
85
101
hideInlineErrors = { props . hideInlineErrors }
86
102
ref = { triggerRef }
87
- forceFocusStyle = { menuIsVisible }
103
+ forceFocusStyle = { menuIsVisible || isFocus }
88
104
>
89
105
< button
90
106
tabIndex = { props . tabIndex }
91
107
className = { styles . selected }
92
- onClick = { toggleIfNotDisabled }
108
+ onMouseDown = { toggleIfNotDisabled }
109
+ onKeyDown = { handleKeyDown }
93
110
type = 'button'
94
111
disabled = { ! ! props . disabled }
95
112
onFocus = { function onFocus ( event : FocusEvent < HTMLButtonElement > | undefined ) {
96
- event ?. stopPropagation ( )
97
- event ?. preventDefault ( )
98
- setMenuIsVisible ( true )
113
+ setIsFocus ( true )
114
+ toggleIfNotDisabled ( event )
115
+ } }
116
+ onBlur = { function onBlur ( ) {
117
+ setIsFocus ( false )
99
118
} }
119
+ ref = { buttonRef }
100
120
>
101
121
< span className = 'body-small' > { selectedOption ? label ( selectedOption ) : '' } </ span >
102
122
< span className = 'body-small' > { ! selectedOption && ! ! props . placeholder ? props . placeholder : '' } </ span >
0 commit comments