@@ -37,47 +37,46 @@ const AccessibleList: React.FunctionComponent<AccessibleListProps> = (
3737 } , [ refArray , current , props . focusFirstItem ] ) ;
3838
3939 const handleKeyDown = ( e : KeyboardEvent ) => {
40- if (
41- e . key === KeyboardKeys . DownArrow &&
42- current === refArray . length - 1
43- ) {
44- e . preventDefault ( ) ;
45- setCurrent ( 0 ) ;
46- return ;
40+ switch ( e . key ) {
41+ case KeyboardKeys . UpArrow : {
42+ handleUpArrowPress ( e ) ;
43+ break ;
44+ }
45+ case KeyboardKeys . DownArrow : {
46+ handleDownArrowPress ( e ) ;
47+ break ;
48+ }
49+ case KeyboardKeys . Escape : {
50+ handleEscapePress ( e ) ;
51+ break ;
52+ }
53+ default : {
54+ return ;
55+ }
4756 }
57+ } ;
4858
49- if ( e . key === KeyboardKeys . UpArrow && current === 0 ) {
50- e . preventDefault ( ) ;
51- setCurrent ( refArray . length - 1 ) ;
52- return ;
53- }
59+ const handleDownArrowPress = ( e : KeyboardEvent ) => {
60+ const isLastElementFocused = current === refArray . length - 1 ;
61+ const indexToFocus = isLastElementFocused ? 0 : current + 1 ;
5462
55- if (
56- e . key === KeyboardKeys . DownArrow &&
57- current !== refArray . length - 1
58- ) {
59- e . preventDefault ( ) ;
63+ setCurrentAndPreventDefault ( e , indexToFocus ) ;
64+ } ;
6065
61- setCurrent ( current + 1 ) ;
62- return ;
63- }
64-
65- if ( e . key === KeyboardKeys . UpArrow && current !== 0 ) {
66- e . preventDefault ( ) ;
67-
68- setCurrent ( current - 1 ) ;
69- return ;
66+ const handleEscapePress = ( e : KeyboardEvent ) => {
67+ setCurrentAndPreventDefault ( e , 0 ) ;
68+ if ( props . onEsc != null ) {
69+ props . onEsc ( ) ;
7070 }
71+ } ;
7172
72- if ( e . key === KeyboardKeys . Escape ) {
73- e . preventDefault ( ) ;
74- setCurrent ( 0 ) ;
73+ const handleUpArrowPress = ( e : KeyboardEvent ) => {
74+ const isFirstElementFocused = current === 0 ;
75+ const indexToFocus = isFirstElementFocused
76+ ? refArray . length - 1
77+ : current - 1 ;
7578
76- if ( props . onEsc != null ) {
77- props . onEsc ( ) ;
78- }
79- return ;
80- }
79+ setCurrentAndPreventDefault ( e , indexToFocus ) ;
8180 } ;
8281
8382 const renderChildren = ( ) => {
@@ -87,19 +86,36 @@ const AccessibleList: React.FunctionComponent<AccessibleListProps> = (
8786 return child ;
8887 }
8988
90- return React . cloneElement ( child , {
91- ...child . props ,
92- onClick : ( ) => {
93- if ( child . props . onClick != null ) {
94- child . props . onClick ( ) ;
95- }
96- } ,
97- onKeyDown : handleKeyDown ,
98- ref : ( el : HTMLElement ) => ( refArray [ validElementIndex ++ ] = el ) ,
99- } ) ;
89+ const renderedChild = renderChild ( child , validElementIndex ) ;
90+ validElementIndex ++ ;
91+ return renderedChild ;
92+ } ) ;
93+ } ;
94+
95+ const renderChild = ( child : React . ReactElement , index : number ) => {
96+ return React . cloneElement ( child , {
97+ ...child . props ,
98+ onClick : ( ) => {
99+ if ( child . props . onClick != null ) {
100+ child . props . onClick ( ) ;
101+ }
102+ } ,
103+ onKeyDown : handleKeyDown ,
104+ ref : ( el : HTMLElement ) => ( refArray [ index ] = el ) ,
100105 } ) ;
101106 } ;
102107
108+ const setCurrentAndPreventDefault = (
109+ e : KeyboardEvent ,
110+ indexToFocus : number
111+ ) => {
112+ if ( indexToFocus < 0 ) {
113+ return ;
114+ }
115+ e . preventDefault ( ) ;
116+ setCurrent ( indexToFocus ) ;
117+ } ;
118+
103119 return < React . Fragment > { renderChildren ( ) } </ React . Fragment > ;
104120} ;
105121
0 commit comments