@react-aria/interactions 3.20.1 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -69,6 +69,24 @@ export interface FocusVisibleResult {
69
69
  /** Whether keyboard focus is visible globally. */
70
70
  isFocusVisible: boolean;
71
71
  }
72
+ /**
73
+ * EXPERIMENTAL
74
+ * Adds a window (i.e. iframe) to the list of windows that are being tracked for focus visible.
75
+ *
76
+ * Sometimes apps render portions of their tree into an iframe. In this case, we cannot accurately track if the focus
77
+ * is visible because we cannot see interactions inside the iframe. If you have this in your application's architecture,
78
+ * then this function will attach event listeners inside the iframe. You should call `addWindowFocusTracking` with an
79
+ * element from inside the window you wish to add. We'll retrieve the relevant elements based on that.
80
+ * Note, you do not need to call this for the default window, as we call it for you.
81
+ *
82
+ * When you are ready to stop listening, but you do not wish to unmount the iframe, you may call the cleanup function
83
+ * returned by `addWindowFocusTracking`. Otherwise, when you unmount the iframe, all listeners and state will be cleaned
84
+ * up automatically for you.
85
+ *
86
+ * @param element @default document.body - The element provided will be used to get the window to add.
87
+ * @returns A function to remove the event listeners and cleanup the state.
88
+ */
89
+ export function addWindowFocusTracking(element?: HTMLElement | null): () => void;
72
90
  /**
73
91
  * If true, keyboard focus is visible.
74
92
  */
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/textSelection.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/context.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/usePress.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/Pressable.tsx","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/PressResponder.tsx","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/utils.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useFocus.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useFocusVisible.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useFocusWithin.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useHover.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useInteractOutside.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/createEventHandler.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useKeyboard.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useMove.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useScrollWheel.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useLongPress.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/index.ts","packages/@react-aria/interactions/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {Pressable} from './Pressable';\nexport {PressResponder, ClearPressResponder} from './PressResponder';\nexport {useFocus} from './useFocus';\nexport {\n isFocusVisible,\n getInteractionModality,\n setInteractionModality,\n useInteractionModality,\n useFocusVisible,\n useFocusVisibleListener\n} from './useFocusVisible';\nexport {useFocusWithin} from './useFocusWithin';\nexport {useHover} from './useHover';\nexport {useInteractOutside} from './useInteractOutside';\nexport {useKeyboard} from './useKeyboard';\nexport {useMove} from './useMove';\nexport {usePress} from './usePress';\nexport {useScrollWheel} from './useScrollWheel';\nexport {useLongPress} from './useLongPress';\n\nexport type {FocusProps, FocusResult} from './useFocus';\nexport type {FocusVisibleHandler, FocusVisibleProps, FocusVisibleResult, Modality} from './useFocusVisible';\nexport type {FocusWithinProps, FocusWithinResult} from './useFocusWithin';\nexport type {HoverProps, HoverResult} from './useHover';\nexport type {InteractOutsideProps} from './useInteractOutside';\nexport type {KeyboardProps, KeyboardResult} from './useKeyboard';\nexport type {PressProps, PressHookProps, PressResult} from './usePress';\nexport type {PressEvent, PressEvents, MoveStartEvent, MoveMoveEvent, MoveEndEvent, MoveEvents, HoverEvent, HoverEvents, FocusEvents, KeyboardEvents} from '@react-types/shared';\nexport type {MoveResult} from './useMove';\nexport type {LongPressProps, LongPressResult} from './useLongPress';\nexport type {ScrollWheelProps} from './useScrollWheel';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/textSelection.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/context.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/usePress.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/Pressable.tsx","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/PressResponder.tsx","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/utils.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useFocus.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useFocusVisible.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useFocusWithin.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useHover.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useInteractOutside.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/createEventHandler.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useKeyboard.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useMove.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useScrollWheel.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/useLongPress.ts","packages/@react-aria/interactions/src/packages/@react-aria/interactions/src/index.ts","packages/@react-aria/interactions/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {Pressable} from './Pressable';\nexport {PressResponder, ClearPressResponder} from './PressResponder';\nexport {useFocus} from './useFocus';\nexport {\n isFocusVisible,\n getInteractionModality,\n setInteractionModality,\n addWindowFocusTracking,\n useInteractionModality,\n useFocusVisible,\n useFocusVisibleListener\n} from './useFocusVisible';\nexport {useFocusWithin} from './useFocusWithin';\nexport {useHover} from './useHover';\nexport {useInteractOutside} from './useInteractOutside';\nexport {useKeyboard} from './useKeyboard';\nexport {useMove} from './useMove';\nexport {usePress} from './usePress';\nexport {useScrollWheel} from './useScrollWheel';\nexport {useLongPress} from './useLongPress';\n\nexport type {FocusProps, FocusResult} from './useFocus';\nexport type {FocusVisibleHandler, FocusVisibleProps, FocusVisibleResult, Modality} from './useFocusVisible';\nexport type {FocusWithinProps, FocusWithinResult} from './useFocusWithin';\nexport type {HoverProps, HoverResult} from './useHover';\nexport type {InteractOutsideProps} from './useInteractOutside';\nexport type {KeyboardProps, KeyboardResult} from './useKeyboard';\nexport type {PressProps, PressHookProps, PressResult} from './usePress';\nexport type {PressEvent, PressEvents, MoveStartEvent, MoveMoveEvent, MoveEndEvent, MoveEvents, HoverEvent, HoverEvents, FocusEvents, KeyboardEvents} from '@react-types/shared';\nexport type {MoveResult} from './useMove';\nexport type {LongPressProps, LongPressResult} from './useLongPress';\nexport type {ScrollWheelProps} from './useScrollWheel';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-aria/interactions",
3
- "version": "3.20.1",
3
+ "version": "3.21.0",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@react-aria/ssr": "^3.9.1",
26
- "@react-aria/utils": "^3.23.0",
26
+ "@react-aria/utils": "^3.23.1",
27
27
  "@react-types/shared": "^3.22.0",
28
28
  "@swc/helpers": "^0.5.0"
29
29
  },
@@ -33,5 +33,5 @@
33
33
  "publishConfig": {
34
34
  "access": "public"
35
35
  },
36
- "gitHead": "86b38c87868ce7f262e0df905e5ac4eb2653791d"
36
+ "gitHead": "f040ff62678e6a31375b96c05396df0bae660350"
37
37
  }
@@ -20,7 +20,7 @@ interface DOMPropsResponderProps extends DOMAttributes {
20
20
 
21
21
  interface IDOMPropsResponderContext extends DOMAttributes {
22
22
  register(): void,
23
- ref?: MutableRefObject<Element>
23
+ ref?: MutableRefObject<Element | null>
24
24
  }
25
25
 
26
26
  export const DOMPropsResponderContext = React.createContext<IDOMPropsResponderContext | null>(null);
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ export {
17
17
  isFocusVisible,
18
18
  getInteractionModality,
19
19
  setInteractionModality,
20
+ addWindowFocusTracking,
20
21
  useInteractionModality,
21
22
  useFocusVisible,
22
23
  useFocusVisibleListener
@@ -15,7 +15,7 @@
15
15
  // NOTICE file in the root directory of this source tree.
16
16
  // See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
17
17
 
18
- import {isMac, isVirtualClick} from '@react-aria/utils';
18
+ import {getOwnerDocument, getOwnerWindow, isMac, isVirtualClick} from '@react-aria/utils';
19
19
  import {useEffect, useState} from 'react';
20
20
  import {useIsSSR} from '@react-aria/ssr';
21
21
 
@@ -37,7 +37,10 @@ export interface FocusVisibleResult {
37
37
 
38
38
  let currentModality: null | Modality = null;
39
39
  let changeHandlers = new Set<Handler>();
40
- let hasSetupGlobalListeners = false;
40
+ interface GlobalListenerData {
41
+ focus: () => void
42
+ }
43
+ export let hasSetupGlobalListeners = new Map<Window, GlobalListenerData>(); // We use a map here to support setting event listeners across multiple document objects.
41
44
  let hasEventBeforeFocus = false;
42
45
  let hasBlurredWindowRecently = false;
43
46
 
@@ -114,49 +117,117 @@ function handleWindowBlur() {
114
117
  /**
115
118
  * Setup global event listeners to control when keyboard focus style should be visible.
116
119
  */
117
- function setupGlobalFocusEvents() {
118
- if (typeof window === 'undefined' || hasSetupGlobalListeners) {
120
+ function setupGlobalFocusEvents(element?: HTMLElement | null) {
121
+ if (typeof window === 'undefined' || hasSetupGlobalListeners.get(getOwnerWindow(element))) {
119
122
  return;
120
123
  }
121
124
 
125
+ const windowObject = getOwnerWindow(element);
126
+ const documentObject = getOwnerDocument(element);
127
+
122
128
  // Programmatic focus() calls shouldn't affect the current input modality.
123
129
  // However, we need to detect other cases when a focus event occurs without
124
130
  // a preceding user event (e.g. screen reader focus). Overriding the focus
125
131
  // method on HTMLElement.prototype is a bit hacky, but works.
126
- let focus = HTMLElement.prototype.focus;
127
- HTMLElement.prototype.focus = function () {
132
+ let focus = windowObject.HTMLElement.prototype.focus;
133
+ windowObject.HTMLElement.prototype.focus = function () {
128
134
  hasEventBeforeFocus = true;
129
135
  focus.apply(this, arguments as unknown as [options?: FocusOptions | undefined]);
130
136
  };
131
137
 
132
- document.addEventListener('keydown', handleKeyboardEvent, true);
133
- document.addEventListener('keyup', handleKeyboardEvent, true);
134
- document.addEventListener('click', handleClickEvent, true);
138
+ documentObject.addEventListener('keydown', handleKeyboardEvent, true);
139
+ documentObject.addEventListener('keyup', handleKeyboardEvent, true);
140
+ documentObject.addEventListener('click', handleClickEvent, true);
135
141
 
136
142
  // Register focus events on the window so they are sure to happen
137
143
  // before React's event listeners (registered on the document).
138
- window.addEventListener('focus', handleFocusEvent, true);
139
- window.addEventListener('blur', handleWindowBlur, false);
144
+ windowObject.addEventListener('focus', handleFocusEvent, true);
145
+ windowObject.addEventListener('blur', handleWindowBlur, false);
140
146
 
141
147
  if (typeof PointerEvent !== 'undefined') {
142
- document.addEventListener('pointerdown', handlePointerEvent, true);
143
- document.addEventListener('pointermove', handlePointerEvent, true);
144
- document.addEventListener('pointerup', handlePointerEvent, true);
148
+ documentObject.addEventListener('pointerdown', handlePointerEvent, true);
149
+ documentObject.addEventListener('pointermove', handlePointerEvent, true);
150
+ documentObject.addEventListener('pointerup', handlePointerEvent, true);
145
151
  } else {
146
- document.addEventListener('mousedown', handlePointerEvent, true);
147
- document.addEventListener('mousemove', handlePointerEvent, true);
148
- document.addEventListener('mouseup', handlePointerEvent, true);
152
+ documentObject.addEventListener('mousedown', handlePointerEvent, true);
153
+ documentObject.addEventListener('mousemove', handlePointerEvent, true);
154
+ documentObject.addEventListener('mouseup', handlePointerEvent, true);
149
155
  }
150
156
 
151
- hasSetupGlobalListeners = true;
157
+ // Add unmount handler
158
+ windowObject.addEventListener('beforeunload', () => {
159
+ tearDownWindowFocusTracking(element);
160
+ }, {once: true});
161
+
162
+ hasSetupGlobalListeners.set(windowObject, {focus});
152
163
  }
153
164
 
154
- if (typeof document !== 'undefined') {
155
- if (document.readyState !== 'loading') {
156
- setupGlobalFocusEvents();
165
+ const tearDownWindowFocusTracking = (element, loadListener?: () => void) => {
166
+ const windowObject = getOwnerWindow(element);
167
+ const documentObject = getOwnerDocument(element);
168
+ if (loadListener) {
169
+ documentObject.removeEventListener('DOMContentLoaded', loadListener);
170
+ }
171
+ if (!hasSetupGlobalListeners.has(windowObject)) {
172
+ return;
173
+ }
174
+ windowObject.HTMLElement.prototype.focus = hasSetupGlobalListeners.get(windowObject)!.focus;
175
+
176
+ documentObject.removeEventListener('keydown', handleKeyboardEvent, true);
177
+ documentObject.removeEventListener('keyup', handleKeyboardEvent, true);
178
+ documentObject.removeEventListener('click', handleClickEvent, true);
179
+ windowObject.removeEventListener('focus', handleFocusEvent, true);
180
+ windowObject.removeEventListener('blur', handleWindowBlur, false);
181
+
182
+ if (typeof PointerEvent !== 'undefined') {
183
+ documentObject.removeEventListener('pointerdown', handlePointerEvent, true);
184
+ documentObject.removeEventListener('pointermove', handlePointerEvent, true);
185
+ documentObject.removeEventListener('pointerup', handlePointerEvent, true);
157
186
  } else {
158
- document.addEventListener('DOMContentLoaded', setupGlobalFocusEvents);
187
+ documentObject.removeEventListener('mousedown', handlePointerEvent, true);
188
+ documentObject.removeEventListener('mousemove', handlePointerEvent, true);
189
+ documentObject.removeEventListener('mouseup', handlePointerEvent, true);
159
190
  }
191
+
192
+ hasSetupGlobalListeners.delete(windowObject);
193
+ };
194
+
195
+ /**
196
+ * EXPERIMENTAL
197
+ * Adds a window (i.e. iframe) to the list of windows that are being tracked for focus visible.
198
+ *
199
+ * Sometimes apps render portions of their tree into an iframe. In this case, we cannot accurately track if the focus
200
+ * is visible because we cannot see interactions inside the iframe. If you have this in your application's architecture,
201
+ * then this function will attach event listeners inside the iframe. You should call `addWindowFocusTracking` with an
202
+ * element from inside the window you wish to add. We'll retrieve the relevant elements based on that.
203
+ * Note, you do not need to call this for the default window, as we call it for you.
204
+ *
205
+ * When you are ready to stop listening, but you do not wish to unmount the iframe, you may call the cleanup function
206
+ * returned by `addWindowFocusTracking`. Otherwise, when you unmount the iframe, all listeners and state will be cleaned
207
+ * up automatically for you.
208
+ *
209
+ * @param element @default document.body - The element provided will be used to get the window to add.
210
+ * @returns A function to remove the event listeners and cleanup the state.
211
+ */
212
+ export function addWindowFocusTracking(element?: HTMLElement | null): () => void {
213
+ const documentObject = getOwnerDocument(element);
214
+ let loadListener;
215
+ if (documentObject.readyState !== 'loading') {
216
+ setupGlobalFocusEvents(element);
217
+ } else {
218
+ loadListener = () => {
219
+ setupGlobalFocusEvents(element);
220
+ };
221
+ documentObject.addEventListener('DOMContentLoaded', loadListener);
222
+ }
223
+
224
+ return () => tearDownWindowFocusTracking(element, loadListener);
225
+ }
226
+
227
+ // Server-side rendering does not have the document object defined
228
+ // eslint-disable-next-line no-restricted-globals
229
+ if (typeof document !== 'undefined') {
230
+ addWindowFocusTracking();
160
231
  }
161
232
 
162
233
  /**
@@ -213,11 +284,16 @@ const nonTextInputTypes = new Set([
213
284
  * focus visible style can be properly set.
214
285
  */
215
286
  function isKeyboardFocusEvent(isTextInput: boolean, modality: Modality, e: HandlerEvent) {
216
- isTextInput = isTextInput ||
217
- (e?.target instanceof HTMLInputElement && !nonTextInputTypes.has(e?.target?.type)) ||
218
- e?.target instanceof HTMLTextAreaElement ||
219
- (e?.target instanceof HTMLElement && e?.target.isContentEditable);
220
- return !(isTextInput && modality === 'keyboard' && e instanceof KeyboardEvent && !FOCUS_VISIBLE_INPUT_KEYS[e.key]);
287
+ const IHTMLInputElement = typeof window !== 'undefined' ? getOwnerWindow(e?.target as Element).HTMLInputElement : HTMLInputElement;
288
+ const IHTMLTextAreaElement = typeof window !== 'undefined' ? getOwnerWindow(e?.target as Element).HTMLTextAreaElement : HTMLTextAreaElement;
289
+ const IHTMLElement = typeof window !== 'undefined' ? getOwnerWindow(e?.target as Element).HTMLElement : HTMLElement;
290
+ const IKeyboardEvent = typeof window !== 'undefined' ? getOwnerWindow(e?.target as Element).KeyboardEvent : KeyboardEvent;
291
+
292
+ isTextInput = isTextInput ||
293
+ (e?.target instanceof IHTMLInputElement && !nonTextInputTypes.has(e?.target?.type)) ||
294
+ e?.target instanceof IHTMLTextAreaElement ||
295
+ (e?.target instanceof IHTMLElement && e?.target.isContentEditable);
296
+ return !(isTextInput && modality === 'keyboard' && e instanceof IKeyboardEvent && !FOCUS_VISIBLE_INPUT_KEYS[e.key]);
221
297
  }
222
298
 
223
299
  /**
package/src/usePress.ts CHANGED
@@ -15,9 +15,9 @@
15
15
  // NOTICE file in the root directory of this source tree.
16
16
  // See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
17
17
 
18
+ import {chain, focusWithoutScrolling, getOwnerDocument, getOwnerWindow, isMac, isVirtualClick, isVirtualPointerEvent, mergeProps, openLink, useEffectEvent, useGlobalListeners, useSyncRef} from '@react-aria/utils';
18
19
  import {disableTextSelection, restoreTextSelection} from './textSelection';
19
20
  import {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';
21
21
  import {PressResponderContext} from './context';
22
22
  import {RefObject, useContext, useEffect, useMemo, useRef, useState} from 'react';
23
23
 
@@ -270,8 +270,16 @@ export function usePress(props: PressHookProps): PressResult {
270
270
  shouldStopPropagation = triggerPressStart(e, 'keyboard');
271
271
 
272
272
  // 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);
275
283
  }
276
284
 
277
285
  if (shouldStopPropagation) {
@@ -292,11 +300,6 @@ export function usePress(props: PressHookProps): PressResult {
292
300
  state.metaKeyEvents = new Map();
293
301
  }
294
302
  },
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
- },
300
303
  onClick(e) {
301
304
  if (e && !e.currentTarget.contains(e.target as Element)) {
302
305
  return;
@@ -338,13 +341,9 @@ export function usePress(props: PressHookProps): PressResult {
338
341
  }
339
342
 
340
343
  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));
342
345
  removeAllGlobalListeners();
343
346
 
344
- if (shouldStopPropagation) {
345
- e.stopPropagation();
346
- }
347
-
348
347
  // If a link was triggered with a key other than Enter, open the URL ourselves.
349
348
  // This means the link has a role override, and the default browser behavior
350
349
  // only applies when using the Enter key.