@@ -80,6 +80,7 @@ interface FocusableComponent {
8080 onEnterPress : ( details ?: KeyPressDetails ) => void ;
8181 onEnterRelease : ( ) => void ;
8282 onArrowPress : ( direction : string , details : KeyPressDetails ) => boolean ;
83+ onArrowRelease : ( direction : string ) => void ;
8384 onFocus : ( layout : FocusableComponentLayout , details : FocusDetails ) => void ;
8485 onBlur : ( layout : FocusableComponentLayout , details : FocusDetails ) => void ;
8586 onUpdateFocus : ( focused : boolean ) => void ;
@@ -106,6 +107,7 @@ interface FocusableComponentUpdatePayload {
106107 onEnterPress : ( details ?: KeyPressDetails ) => void ;
107108 onEnterRelease : ( ) => void ;
108109 onArrowPress : ( direction : string , details : KeyPressDetails ) => boolean ;
110+ onArrowRelease : ( direction : string ) => void ;
109111 onFocus : ( layout : FocusableComponentLayout , details : FocusDetails ) => void ;
110112 onBlur : ( layout : FocusableComponentLayout , details : FocusDetails ) => void ;
111113}
@@ -830,6 +832,14 @@ class SpatialNavigationService {
830832 if ( eventType === KEY_ENTER && this . focusKey ) {
831833 this . onEnterRelease ( ) ;
832834 }
835+
836+ if ( this . focusKey && (
837+ eventType === DIRECTION_LEFT ||
838+ eventType === DIRECTION_RIGHT ||
839+ eventType === DIRECTION_UP ||
840+ eventType === DIRECTION_DOWN ) ) {
841+ this . onArrowRelease ( eventType )
842+ }
833843 } ;
834844
835845 window . addEventListener ( 'keyup' , this . keyUpEventListener ) ;
@@ -921,6 +931,28 @@ class SpatialNavigationService {
921931 ) ;
922932 }
923933
934+ onArrowRelease ( direction : string ) {
935+ const component = this . focusableComponents [ this . focusKey ] ;
936+
937+ /* Guard against last-focused component being unmounted at time of onArrowRelease (e.g due to UI fading out) */
938+ if ( ! component ) {
939+ this . log ( 'onArrowRelease' , 'noComponent' ) ;
940+
941+ return ;
942+ }
943+
944+ /* Suppress onArrowRelease if the last-focused item happens to lose its 'focused' status. */
945+ if ( ! component . focusable ) {
946+ this . log ( 'onArrowRelease' , 'componentNotFocusable' ) ;
947+
948+ return ;
949+ }
950+
951+ if ( component . onArrowRelease ) {
952+ component . onArrowRelease ( direction ) ;
953+ }
954+ }
955+
924956 /**
925957 * Move focus by direction, if you can't use buttons or focusing by key.
926958 *
@@ -1275,6 +1307,7 @@ class SpatialNavigationService {
12751307 onEnterPress,
12761308 onEnterRelease,
12771309 onArrowPress,
1310+ onArrowRelease,
12781311 onFocus,
12791312 onBlur,
12801313 saveLastFocusedChild,
@@ -1295,6 +1328,7 @@ class SpatialNavigationService {
12951328 onEnterPress,
12961329 onEnterRelease,
12971330 onArrowPress,
1331+ onArrowRelease,
12981332 onFocus,
12991333 onBlur,
13001334 onUpdateFocus,
0 commit comments