Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/react-aria/src/interactions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import {FocusableElement} from '@react-types/shared';
import {focusWithoutScrolling} from '../utils/focusWithoutScrolling';
import {getActiveElement, getEventTarget, nodeContains} from '../utils/shadowdom/DOMFunctions';
import {getOwnerWindow, isShadowRoot} from '../utils/domHelpers';
import {getOwnerWindow, isNode, isShadowRoot} from '../utils/domHelpers';
import {isFocusable} from '../utils/isFocusable';
import {FocusEvent as ReactFocusEvent, SyntheticEvent, useCallback, useRef} from 'react';
import {useLayoutEffect} from '../utils/useLayoutEffect';
Expand Down Expand Up @@ -138,12 +138,12 @@ export function preventFocus(target: FocusableElement | null): (() => void) | un
// Focus is "moving to target" when it moves to the button or to a descendant of the button
// (e.g. SVG icon)
let isFocusMovingToTarget = (focusTarget: Element | null) =>
focusTarget === target || (focusTarget != null && nodeContains(target, focusTarget));
focusTarget === target || (isNode(focusTarget) && nodeContains(target, focusTarget));
// Blur/focusout events have their target as the element losing focus. Stop propagation when
// that is the previously focused element (activeElement) or a descendant (e.g. in shadow DOM).
let isBlurFromActiveElement = (eventTarget: Element | null) =>
eventTarget === activeElement ||
(activeElement != null && eventTarget != null && nodeContains(activeElement, eventTarget));
(activeElement != null && isNode(eventTarget) && nodeContains(activeElement, eventTarget));

ignoreFocusEvent = true;
let isRefocusing = false;
Expand Down
19 changes: 19 additions & 0 deletions packages/react-aria/test/interactions/usePress.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,25 @@ describe('usePress', function () {
expect(document.activeElement).not.toBe(el);
});

it('should not throw if the window is focused or blurred during a press', function () {
let res = render(<Example preventFocusOnPress />);

let el = res.getByText('test');
fireEvent.mouseDown(el);

// preventFocus listens for focus and blur on the window. The browser fires
// those at the window itself when it gains or loses focus, e.g. returning
// from a native dialog, another tab, or an iframe. The target of those
// events is the Window, which is not a Node.
fireEvent(window, new FocusEvent('focus'));
fireEvent(window, new FocusEvent('blur'));

fireEvent.mouseUp(el);
fireEvent.click(el);

expect(document.activeElement).not.toBe(el);
});

it('should focus the element on click by default', function () {
let res = render(<Example />);

Expand Down