1515// NOTICE file in the root directory of this source tree.
1616// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
1717
18+ import { chain , focusWithoutScrolling , getOwnerDocument , getOwnerWindow , isMac , isVirtualClick , isVirtualPointerEvent , mergeProps , openLink , useEffectEvent , useGlobalListeners , useSyncRef } from '@react-aria/utils' ;
1819import { disableTextSelection , restoreTextSelection } from './textSelection' ;
1920import { DOMAttributes , FocusableElement , PressEvent as IPressEvent , PointerType , PressEvents } from '@react-types/shared' ;
20- import { focusWithoutScrolling , getOwnerDocument , getOwnerWindow , isMac , isVirtualClick , isVirtualPointerEvent , mergeProps , openLink , useEffectEvent , useGlobalListeners , useSyncRef } from '@react-aria/utils' ;
2121import { PressResponderContext } from './context' ;
2222import { RefObject , useContext , useEffect , useMemo , useRef , useState } from 'react' ;
2323
@@ -270,8 +270,16 @@ export function usePress(props: PressHookProps): PressResult {
270270 shouldStopPropagation = triggerPressStart ( e , 'keyboard' ) ;
271271
272272 // Focus may move before the key up event, so register the event on the document
273- // instead of the same element where the key down event occurred.
274- addGlobalListener ( getOwnerDocument ( e . currentTarget ) , 'keyup' , onKeyUp , false ) ;
273+ // instead of the same element where the key down event occurred. Make it capturing so that it will trigger
274+ // before stopPropagation from useKeyboard on a child element may happen and thus we can still call triggerPress for the parent element.
275+ let originalTarget = e . currentTarget ;
276+ let pressUp = ( e ) => {
277+ if ( isValidKeyboardEvent ( e , originalTarget ) && ! e . repeat && originalTarget . contains ( e . target as Element ) && state . target ) {
278+ triggerPressUp ( createEvent ( state . target , e ) , 'keyboard' ) ;
279+ }
280+ } ;
281+
282+ addGlobalListener ( getOwnerDocument ( e . currentTarget ) , 'keyup' , chain ( pressUp , onKeyUp ) , true ) ;
275283 }
276284
277285 if ( shouldStopPropagation ) {
@@ -292,11 +300,6 @@ export function usePress(props: PressHookProps): PressResult {
292300 state . metaKeyEvents = new Map ( ) ;
293301 }
294302 } ,
295- onKeyUp ( e ) {
296- if ( isValidKeyboardEvent ( e . nativeEvent , e . currentTarget ) && ! e . repeat && e . currentTarget . contains ( e . target as Element ) && state . target ) {
297- triggerPressUp ( createEvent ( state . target , e ) , 'keyboard' ) ;
298- }
299- } ,
300303 onClick ( e ) {
301304 if ( e && ! e . currentTarget . contains ( e . target as Element ) ) {
302305 return ;
@@ -338,13 +341,9 @@ export function usePress(props: PressHookProps): PressResult {
338341 }
339342
340343 let target = e . target as Element ;
341- let shouldStopPropagation = triggerPressEnd ( createEvent ( state . target , e ) , 'keyboard' , state . target . contains ( target ) ) ;
344+ triggerPressEnd ( createEvent ( state . target , e ) , 'keyboard' , state . target . contains ( target ) ) ;
342345 removeAllGlobalListeners ( ) ;
343346
344- if ( shouldStopPropagation ) {
345- e . stopPropagation ( ) ;
346- }
347-
348347 // If a link was triggered with a key other than Enter, open the URL ourselves.
349348 // This means the link has a role override, and the default browser behavior
350349 // only applies when using the Enter key.
0 commit comments