1
1
import React , { useRef , useEffect } from 'react' ;
2
2
import propTypes from 'prop-types' ;
3
- import {
4
- StyledOptionsList ,
5
- StyledOptionsListItemInnerButton ,
6
- StyledOptionsListItem
7
- } from './SelectBox.styles' ;
3
+ import { StyledOptionsList , StyledOptionsListItem } from './SelectBox.styles' ;
8
4
import { StyledCutout } from '../Cutout/Cutout' ;
9
5
10
6
const SelectBox = React . forwardRef ( function SelectBox ( props ) {
11
7
const { options, value, onSelect, width, height } = props ;
12
8
const selectedListItemRef = useRef ( null ) ;
13
9
const listRef = useRef ( null ) ;
14
10
15
- const handleKeyDown = ( { key } ) => {
16
- switch ( key ) {
11
+ const handleKeyDown = event => {
12
+ switch ( event . key ) {
17
13
case 'ArrowDown' :
18
- if ( value < options . length - 1 ) onSelect ( value + 1 ) ;
14
+ if ( value < options . length - 1 ) {
15
+ event . preventDefault ( ) ;
16
+ onSelect ( value + 1 ) ;
17
+ listRef . current . childNodes [ value + 1 ] . scrollIntoView ( {
18
+ block : 'end'
19
+ } ) ;
20
+ }
19
21
break ;
20
22
case 'ArrowUp' :
21
- if ( value > 0 ) onSelect ( value - 1 ) ;
23
+ if ( value > 0 ) {
24
+ event . preventDefault ( ) ;
25
+ onSelect ( value - 1 ) ;
26
+ listRef . current . childNodes [ value - 1 ] . scrollIntoView ( {
27
+ block : 'nearest'
28
+ } ) ;
29
+ }
30
+ break ;
31
+ case 'Home' :
32
+ onSelect ( 0 ) ;
33
+ listRef . current . childNodes [ 0 ] . scrollIntoView ( {
34
+ block : 'start'
35
+ } ) ;
36
+ break ;
37
+ case 'End' :
38
+ onSelect ( options . length - 1 ) ;
39
+ listRef . current . childNodes [ options . length - 1 ] . scrollIntoView ( {
40
+ block : 'end'
41
+ } ) ;
22
42
break ;
23
43
default :
24
44
break ;
@@ -27,29 +47,34 @@ const SelectBox = React.forwardRef(function SelectBox(props) {
27
47
28
48
useEffect ( ( ) => {
29
49
selectedListItemRef . current . scrollIntoView ( {
30
- behavior : 'smooth' ,
31
50
block : 'start'
32
51
} ) ;
33
52
} , [ selectedListItemRef ] ) ;
34
53
54
+ const handleClickOnItem = itemValue => {
55
+ onSelect ( itemValue ) ;
56
+ listRef . current . childNodes [ itemValue ] . scrollIntoView ( {
57
+ block : 'nearest'
58
+ } ) ;
59
+ } ;
60
+
35
61
return (
36
62
< StyledCutout >
37
63
< StyledOptionsList
38
64
style = { { width, height } }
39
65
ref = { listRef }
40
66
onKeyDown = { handleKeyDown }
67
+ tabIndex = { - 1 }
41
68
>
42
69
{ options . map ( option => (
43
- < StyledOptionsListItem key = { option . value . toString ( ) } >
44
- < StyledOptionsListItemInnerButton
45
- onClick = { ( ) => onSelect ( option . value ) }
46
- type = 'button'
47
- autoFocus = { option . value === value }
48
- isSelected = { option . value === value }
49
- ref = { option . value === value ? selectedListItemRef : null }
50
- >
51
- { option . label }
52
- </ StyledOptionsListItemInnerButton >
70
+ < StyledOptionsListItem
71
+ key = { option . value . toString ( ) }
72
+ onClick = { ( ) => handleClickOnItem ( option . value ) }
73
+ type = 'button'
74
+ isSelected = { option . value === value }
75
+ ref = { option . value === value ? selectedListItemRef : null }
76
+ >
77
+ { option . label }
53
78
</ StyledOptionsListItem >
54
79
) ) }
55
80
</ StyledOptionsList >
0 commit comments