e.stopPropagation()} />
+
+ );
+
+ let el = res.getByTestId('inner');
+ fireEvent(el, pointerEvent('pointerover', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+
+ let shouldFireMouseEvents = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ expect(shouldFireMouseEvents).toBe(true);
+
+ let shouldFocus = fireEvent.mouseDown(el);
+ expect(shouldFocus).toBe(true);
+ act(() => el.focus());
+
+ fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ fireEvent.mouseUp(el);
+
+ let shouldClick = fireEvent.click(el);
+ expect(shouldClick).toBe(true);
+ fireEvent(el, pointerEvent('pointerout', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+
+ act(() => jest.advanceTimersByTime(10));
+
+ expect(events).toEqual([
+ {
+ type: 'pressstart',
+ target: el.parentElement,
+ pointerType: 'mouse',
+ ctrlKey: false,
+ metaKey: false,
+ shiftKey: false,
+ altKey: false,
+ x: 0,
+ y: 0
+ },
+ {
+ type: 'presschange',
+ pressed: true
+ },
+ {
+ type: 'pressup',
+ target: el.parentElement,
+ pointerType: 'mouse',
+ ctrlKey: false,
+ metaKey: false,
+ shiftKey: false,
+ altKey: false,
+ x: 0,
+ y: 0
+ },
+ {
+ type: 'pressend',
+ target: el.parentElement,
+ pointerType: 'mouse',
+ ctrlKey: false,
+ metaKey: false,
+ shiftKey: false,
+ altKey: false,
+ x: 0,
+ y: 0
+ },
+ {
+ type: 'presschange',
+ pressed: false
+ }
+ ]);
+ });
+
it('should fire press change events when moving pointer outside target', function () {
let events = [];
let addEvent = (e) => events.push(e);
@@ -191,6 +462,7 @@ describe('usePress', function () {
fireEvent(el, pointerEvent('pointermove', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerover', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ fireEvent.click(el);
expect(events).toEqual([
{
@@ -447,6 +719,7 @@ describe('usePress', function () {
let el = res.getByText('test');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', shiftKey: true, clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', ctrlKey: true, clientX: 0, clientY: 0}));
+ fireEvent.click(el, {ctrlKey: true});
// How else to get the DOM node it renders the hook to?
// let el = events[0].target;
@@ -521,6 +794,7 @@ describe('usePress', function () {
let el = res.getByText('test');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', button: 1}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', button: 1, clientX: 0, clientY: 0}));
+ fireEvent.click(el, {button: 1});
expect(events).toEqual([]);
});
@@ -535,58 +809,6 @@ describe('usePress', function () {
expect(document.activeElement).not.toBe(el);
});
- it('should focus the target on click by default', function () {
- let res = render(
-
- );
-
- let el = res.getByText('test');
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
- expect(document.activeElement).toBe(el);
- });
-
- it('should prevent default on pointerdown and mousedown by default', function () {
- let res = render(
-
- );
-
- let el = res.getByText('test');
- let allowDefault = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- expect(allowDefault).toBe(false);
-
- allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(false);
- });
-
- it('should still prevent default when pressing on a non draggable + pressable item in a draggable container', function () {
- let res = render(
-
-
-
- );
-
- let el = res.getByText('test');
- let allowDefault = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- expect(allowDefault).toBe(false);
-
- allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(false);
- });
-
- it('should not prevent default when pressing on a draggable item', function () {
- let res = render(
-
- );
-
- let el = res.getByText('test');
- let allowDefault = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- expect(allowDefault).toBe(true);
-
- allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(true);
- });
-
it('should ignore virtual pointer events', function () {
let events = [];
let addEvent = (e) => events.push(e);
@@ -669,6 +891,7 @@ describe('usePress', function () {
let el = res.getByText('test');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', width: 0, height: 0, clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', width: 0, height: 0, clientX: 0, clientY: 0}));
+ fireEvent.click(el);
expect(events).toEqual([
{
@@ -816,6 +1039,7 @@ describe('usePress', function () {
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0, width: 20, height: 20}));
fireEvent(el, pointerEvent('pointermove', {pointerId: 1, pointerType: 'mouse', clientX: 10, clientY: 10, width: 20, height: 20}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 10, clientY: 10, width: 20, height: 20}));
+ fireEvent.click(el);
expect(spy).toHaveBeenCalled();
});
@@ -829,63 +1053,9 @@ describe('usePress', function () {
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
expect(el).toHaveStyle('user-select: none');
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse'}));
+ fireEvent.click(el);
expect(el).not.toHaveStyle('user-select: none');
});
-
- it('should preventDefault on touchend to prevent click events on the wrong element', function () {
- let res = render(
);
-
- let el = res.getByText('test');
- el.ontouchend = () => {}; // So that 'ontouchend' in target works
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'touch'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'touch'}));
- let browserDefault = fireEvent.touchEnd(el);
- expect(browserDefault).toBe(false);
- });
-
- it('should not preventDefault on touchend when element is a submit button', function () {
- let res = render(
);
-
- let el = res.getByText('test');
- el.ontouchend = () => {}; // So that 'ontouchend' in target works
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'touch'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'touch'}));
- let browserDefault = fireEvent.touchEnd(el);
- expect(browserDefault).toBe(true);
- });
-
- it('should not preventDefault on touchend when element is an
', function () {
- let res = render(
);
-
- let el = res.getByRole('button');
- el.ontouchend = () => {}; // So that 'ontouchend' in target works
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'touch'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'touch'}));
- let browserDefault = fireEvent.touchEnd(el);
- expect(browserDefault).toBe(true);
- });
-
- it('should not preventDefault on touchend when element is an
', function () {
- let res = render(
);
-
- let el = res.getByRole('checkbox');
- el.ontouchend = () => {}; // So that 'ontouchend' in target works
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'touch'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'touch'}));
- let browserDefault = fireEvent.touchEnd(el);
- expect(browserDefault).toBe(true);
- });
-
- it('should not preventDefault on touchend when element is a link', function () {
- let res = render(
);
-
- let el = res.getByText('test');
- el.ontouchend = () => {}; // So that 'ontouchend' in target works
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'touch'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'touch'}));
- let browserDefault = fireEvent.touchEnd(el);
- expect(browserDefault).toBe(true);
- });
});
describe('mouse events', function () {
@@ -902,9 +1072,12 @@ describe('usePress', function () {
);
let el = res.getByText('test');
- fireEvent.mouseDown(el, {detail: 1});
+ let shouldFocus = fireEvent.mouseDown(el, {detail: 1});
+ expect(shouldFocus).toBe(true);
+ act(() => el.focus());
fireEvent.mouseUp(el, {detail: 1});
- fireEvent.click(el, {detail: 1});
+ let shouldClick = fireEvent.click(el, {detail: 1});
+ expect(shouldClick).toBe(true);
expect(events).toEqual([
{
@@ -1173,7 +1346,7 @@ describe('usePress', function () {
let el = res.getByText('test');
fireEvent.mouseDown(el, {detail: 1, metaKey: true});
fireEvent.mouseUp(el, {detail: 1, shiftKey: true});
- fireEvent.click(el, {detail: 1});
+ fireEvent.click(el, {detail: 1, shiftKey: true});
expect(events).toEqual([
{
@@ -1270,46 +1443,16 @@ describe('usePress', function () {
);
let el = res.getByText('test');
- fireEvent.mouseDown(el);
+ let shouldFocus = fireEvent.mouseDown(el);
+ if (shouldFocus) {
+ act(() => el.focus());
+ }
fireEvent.mouseUp(el);
fireEvent.click(el);
expect(document.activeElement).toBe(el);
});
- it('should prevent default on mousedown by default', function () {
- let res = render(
-
- );
-
- let el = res.getByText('test');
- let allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(false);
- });
-
- it('should still prevent default when pressing on a non draggable + pressable item in a draggable container', function () {
- let res = render(
-
-
-
- );
-
- let el = res.getByText('test');
- let allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(false);
- });
-
-
- it('should not prevent default when pressing on a draggable item', function () {
- let res = render(
-
- );
-
- let el = res.getByText('test');
- let allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(true);
- });
-
it('should cancel press on dragstart', function () {
let events = [];
let addEvent = (e) => events.push(e);
@@ -1986,8 +2129,11 @@ describe('usePress', function () {
);
let el = res.getByText('test');
- fireEvent.touchStart(el, {targetTouches: [{identifier: 1, clientX: 0, clientY: 0}]});
- fireEvent.touchEnd(el, {changedTouches: [{identifier: 1, clientX: 0, clientY: 0}]});
+ let shouldFocus = fireEvent.touchStart(el, {targetTouches: [{identifier: 1, clientX: 0, clientY: 0}]});
+ let shouldFocus2 = fireEvent.touchEnd(el, {changedTouches: [{identifier: 1, clientX: 0, clientY: 0}]});
+ if (shouldFocus && shouldFocus2) {
+ act(() => el.focus());
+ }
expect(document.activeElement).toBe(el);
});
@@ -2823,17 +2969,6 @@ describe('usePress', function () {
expect(document.activeElement).not.toBe(el);
});
- it('should focus the target on virtual click by default', function () {
- let {getByText} = render(
-
- );
-
- let el = getByText('test');
- fireEvent.click(el);
-
- expect(document.activeElement).toBe(el);
- });
-
describe('disable text-selection when pressed', function () {
let handler = jest.fn();
let mockUserSelect = 'contain';
@@ -3201,6 +3336,7 @@ describe('usePress', function () {
let el = res.getByTestId('test');
start(el);
end(el);
+ fireEvent.click(el);
expect(outerPressMock.mock.calls).toHaveLength(0);
expect(innerPressMock.mock.calls).toHaveLength(3);
});
@@ -3228,6 +3364,7 @@ describe('usePress', function () {
let el = res.getByTestId('test');
start(el);
end(el);
+ fireEvent.click(el);
expect(outerPressMock.mock.calls).toHaveLength(4);
expect(innerPressMock.mock.calls).toHaveLength(4);
});
@@ -3359,6 +3496,7 @@ describe('usePress', function () {
const el = document.querySelector('iframe').contentWindow.document.body.querySelector('div[data-testid="example"]');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ fireEvent.click(el);
expect(events).toEqual([
{
@@ -3672,12 +3810,13 @@ describe('usePress', function () {
}
beforeAll(() => {
+ user = userEvent.setup({delay: null, pointerMap});
jest.useFakeTimers();
});
afterEach(() => {
act(() => {jest.runAllTimers();});
- unmount();
+ unmount?.();
});
it('should fire press events based on pointer events', function () {
@@ -3686,6 +3825,7 @@ describe('usePress', function () {
const el = shadowRoot.getElementById('testElement');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ fireEvent.click(el);
expect(events).toEqual([
expect.objectContaining({
@@ -3742,12 +3882,12 @@ describe('usePress', function () {
const el = shadowRoot.getElementById('testElement');
el.releasePointerCapture = jest.fn();
-
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
+ fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
expect(el.releasePointerCapture).toHaveBeenCalled();
// react listens for pointerout and pointerover instead of pointerleave and pointerenter...
fireEvent(el, pointerEvent('pointerout', {pointerId: 1, pointerType: 'mouse', clientX: 100, clientY: 100}));
fireEvent(document, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 100, clientY: 100}));
+ fireEvent(el, pointerEvent('pointerover', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
expect(events).toEqual([
expect.objectContaining({
@@ -3781,11 +3921,14 @@ describe('usePress', function () {
]);
events = [];
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
+ fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ fireEvent(el, pointerEvent('pointermove', {pointerId: 1, pointerType: 'mouse', clientX: 100, clientY: 100}));
// react listens for pointerout and pointerover instead of pointerleave and pointerenter...
fireEvent(el, pointerEvent('pointerout', {pointerId: 1, pointerType: 'mouse', clientX: 100, clientY: 100}));
+ fireEvent(el, pointerEvent('pointermove', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerover', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
+ fireEvent.click(el);
expect(events).toEqual([
expect.objectContaining({
@@ -4058,8 +4201,9 @@ describe('usePress', function () {
const el = shadowRoot.getElementById('testElement');
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', shiftKey: true}));
+ fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', shiftKey: true, clientX: 0, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', ctrlKey: true, clientX: 0, clientY: 0}));
+ fireEvent.click(el, {ctrlKey: true});
expect(events).toEqual([
expect.objectContaining({
@@ -4121,60 +4265,6 @@ describe('usePress', function () {
expect(events).toEqual([]);
});
- it('should not focus the target on click if preventFocusOnPress is true', function () {
- const shadowRoot = setupShadowDOMTest({preventFocusOnPress: true});
- const el = shadowRoot.getElementById('testElement');
-
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
- const deepActiveElement = getActiveElement();
-
- expect(deepActiveElement).not.toBe(el);
- expect(deepActiveElement).not.toBe(shadowRoot);
- });
-
- it('should focus the target on click by default', function () {
- const shadowRoot = setupShadowDOMTest();
-
- const el = shadowRoot.getElementById('testElement');
- fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0}));
- expect(shadowRoot.activeElement).toBe(el);
- });
-
- it('should prevent default on pointerdown and mousedown by default', function () {
- const shadowRoot = setupShadowDOMTest();
-
- const el = shadowRoot.getElementById('testElement');
- let allowDefault = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- expect(allowDefault).toBe(false);
-
- allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(false);
- });
-
- it('should still prevent default when pressing on a non draggable + pressable item in a draggable container', function () {
- const shadowRoot = setupShadowDOMTest({}, true);
-
- const el = shadowRoot.getElementById('testElement');
- let allowDefault = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- expect(allowDefault).toBe(false);
-
- allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(false);
- });
-
- it('should not prevent default when pressing on a draggable item', function () {
- const shadowRoot = setupShadowDOMTest({draggable: true});
-
- const el = shadowRoot.getElementById('testElement');
- let allowDefault = fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
- expect(allowDefault).toBe(true);
-
- allowDefault = fireEvent.mouseDown(el);
- expect(allowDefault).toBe(true);
- });
-
it('should ignore virtual pointer events', function () {
const shadowRoot = setupShadowDOMTest({onPressChange: null});
@@ -4235,6 +4325,7 @@ describe('usePress', function () {
const el = shadowRoot.getElementById('testElement');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', width: 0, height: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', width: 0, height: 0, clientX: 0, clientY: 0}));
+ fireEvent.click(el);
expect(events).toEqual([
expect.objectContaining({
@@ -4352,6 +4443,7 @@ describe('usePress', function () {
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 0, clientY: 0, width: 20, height: 20}));
fireEvent(el, pointerEvent('pointermove', {pointerId: 1, pointerType: 'mouse', clientX: 10, clientY: 10, width: 20, height: 20}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 10, clientY: 10, width: 20, height: 20}));
+ fireEvent.click(el, {clientX: 10, clientY: 10});
expect(spy).toHaveBeenCalled();
});
@@ -4363,6 +4455,7 @@ describe('usePress', function () {
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse'}));
expect(el).toHaveStyle('user-select: none');
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse'}));
+ fireEvent.click(el);
expect(el).not.toHaveStyle('user-select: none');
});
});
@@ -4420,6 +4513,7 @@ describe('coordinates', () => {
let el = res.getByText('test');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'mouse', clientX: 25, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'mouse', clientX: 75, clientY: 75}));
+ fireEvent.click(el, {clientX: 75, clientY: 75});
// How else to get the DOM node it renders the hook to?
// let el = events[0].target;
@@ -4497,6 +4591,7 @@ describe('coordinates', () => {
let el = res.getByText('test');
fireEvent(el, pointerEvent('pointerdown', {pointerId: 1, pointerType: 'touch', clientX: 25, clientY: 0}));
fireEvent(el, pointerEvent('pointerup', {pointerId: 1, pointerType: 'touch', clientX: 75, clientY: 75}));
+ fireEvent.click(el, {clientX: 75, clientY: 75});
expect(events).toEqual([
{
diff --git a/packages/@react-aria/link/test/useLink.test.js b/packages/@react-aria/link/test/useLink.test.js
index 7af03681602..f2d2975c3aa 100644
--- a/packages/@react-aria/link/test/useLink.test.js
+++ b/packages/@react-aria/link/test/useLink.test.js
@@ -23,7 +23,7 @@ describe('useLink', function () {
it('handles defaults', function () {
let {linkProps} = renderLinkHook({children: 'Test Link'});
expect(linkProps.role).toBeUndefined();
- expect(linkProps.tabIndex).toBeUndefined();
+ expect(linkProps.tabIndex).toBe(0);
expect(typeof linkProps.onKeyDown).toBe('function');
});
diff --git a/packages/@react-aria/menu/src/useMenuTrigger.ts b/packages/@react-aria/menu/src/useMenuTrigger.ts
index 3e22777bb1d..44c50a03ecf 100644
--- a/packages/@react-aria/menu/src/useMenuTrigger.ts
+++ b/packages/@react-aria/menu/src/useMenuTrigger.ts
@@ -12,14 +12,14 @@
import {AriaButtonProps} from '@react-types/button';
import {AriaMenuOptions} from './useMenu';
+import {FocusableElement, RefObject} from '@react-types/shared';
+import {focusWithoutScrolling, useId} from '@react-aria/utils';
// @ts-ignore
import intlMessages from '../intl/*.json';
import {MenuTriggerState} from '@react-stately/menu';
import {MenuTriggerType} from '@react-types/menu';
-import {RefObject} from '@react-types/shared';
-import {useId} from '@react-aria/utils';
+import {PressProps, useLongPress} from '@react-aria/interactions';
import {useLocalizedStringFormatter} from '@react-aria/i18n';
-import {useLongPress} from '@react-aria/interactions';
import {useOverlayTrigger} from '@react-aria/overlays';
export interface AriaMenuTriggerProps {
@@ -108,10 +108,14 @@ export function useMenuTrigger
(props: AriaMenuTriggerProps, state: MenuTrigge
}
});
- let pressProps = {
+ let pressProps: PressProps = {
+ preventFocusOnPress: true,
onPressStart(e) {
// For consistency with native, open the menu on mouse/key down, but touch up.
if (e.pointerType !== 'touch' && e.pointerType !== 'keyboard' && !isDisabled) {
+ // Ensure trigger has focus before opening the menu so it can be restored by FocusScope on close.
+ focusWithoutScrolling(e.target as FocusableElement);
+
// If opened with a screen reader, auto focus the first item.
// Otherwise, the menu itself will be focused.
state.open(e.pointerType === 'virtual' ? 'first' : null);
diff --git a/packages/@react-aria/menu/test/useMenuTrigger.test.js b/packages/@react-aria/menu/test/useMenuTrigger.test.js
index c31c577029a..8a5d9038011 100644
--- a/packages/@react-aria/menu/test/useMenuTrigger.test.js
+++ b/packages/@react-aria/menu/test/useMenuTrigger.test.js
@@ -77,7 +77,7 @@ describe('useMenuTrigger', function () {
let {menuTriggerProps} = renderMenuTriggerHook(props, state);
expect(typeof menuTriggerProps.onPressStart).toBe('function');
- menuTriggerProps.onPressStart({pointerType: 'mouse'});
+ menuTriggerProps.onPressStart({pointerType: 'mouse', target: document.createElement('button')});
expect(setOpen).toHaveBeenCalledTimes(1);
expect(setOpen).toHaveBeenCalledWith(!state.isOpen);
expect(setFocusStrategy).toHaveBeenCalledTimes(1);
diff --git a/packages/@react-aria/selection/test/useSelectableCollection.test.js b/packages/@react-aria/selection/test/useSelectableCollection.test.js
index bb0f5d5d6e7..b83705e5248 100644
--- a/packages/@react-aria/selection/test/useSelectableCollection.test.js
+++ b/packages/@react-aria/selection/test/useSelectableCollection.test.js
@@ -77,11 +77,17 @@ describe('useSelectableCollection', () => {
type | prepare | actions
${'VO Events'} | ${installPointerEvent}| ${[
(el) => fireEvent.pointerDown(el, {button: 0, pointerType: 'virtual'}),
- (el) => fireEvent.pointerUp(el, {button: 0, pointerType: 'virtual'})
+ (el) => {
+ fireEvent.pointerUp(el, {button: 0, pointerType: 'virtual'});
+ fireEvent.click(el, {detail: 1});
+ }
]}
${'Touch Pointer Events'} | ${installPointerEvent}| ${[
(el) => fireEvent.pointerDown(el, {button: 0, pointerType: 'touch', pointerId: 1}),
- (el) => fireEvent.pointerUp(el, {button: 0, pointerType: 'touch', pointerId: 1})
+ (el) => {
+ fireEvent.pointerUp(el, {button: 0, pointerType: 'touch', pointerId: 1});
+ fireEvent.click(el, {detail: 1});
+ }
]}
`('always uses toggle for $type', ({prepare, actions: [start, end]}) => {
prepare();
diff --git a/packages/@react-aria/slider/docs/useSlider.mdx b/packages/@react-aria/slider/docs/useSlider.mdx
index ecdd4728e66..5760c1ecb58 100644
--- a/packages/@react-aria/slider/docs/useSlider.mdx
+++ b/packages/@react-aria/slider/docs/useSlider.mdx
@@ -375,7 +375,7 @@ function Example() {
### Custom value scale
-By default, slider values are precentages between 0 and 100. A different scale can be used by setting the `minValue` and `maxValue` props.
+By default, slider values are percentages between 0 and 100. A different scale can be used by setting the `minValue` and `maxValue` props.
```tsx example
(props: AriaTableColumnHeaderProps, st
return {
columnHeaderProps: {
...mergeProps(
+ focusableProps,
gridCellProps,
pressProps,
- focusableProps,
descriptionProps,
// If the table is empty, make all column headers untabbable
shouldDisableFocus ? {tabIndex: -1} : null
diff --git a/packages/@react-aria/table/src/useTableColumnResize.ts b/packages/@react-aria/table/src/useTableColumnResize.ts
index aa8993c8984..6913138acb0 100644
--- a/packages/@react-aria/table/src/useTableColumnResize.ts
+++ b/packages/@react-aria/table/src/useTableColumnResize.ts
@@ -224,6 +224,7 @@ export function useTableColumnResize(props: AriaTableColumnResizeProps, st
};
let {pressProps} = usePress({
+ preventFocusOnPress: true,
onPressStart: (e) => {
if (e.ctrlKey || e.altKey || e.metaKey || e.shiftKey || e.pointerType === 'keyboard') {
return;
diff --git a/packages/@react-aria/test-utils/src/events.ts b/packages/@react-aria/test-utils/src/events.ts
index 6683cbc60f4..73a048de8d8 100644
--- a/packages/@react-aria/test-utils/src/events.ts
+++ b/packages/@react-aria/test-utils/src/events.ts
@@ -22,14 +22,39 @@ export const DEFAULT_LONG_PRESS_TIME = 500;
* @param opts.advanceTimer - Function that when called advances the timers in your test suite by a specific amount of time(ms).
* @param opts.pointeropts - Options to pass to the simulated event. Defaults to mouse. See https://testing-library.com/docs/dom-testing-library/api-events/#fireevent for more info.
*/
-export async function triggerLongPress(opts: {element: HTMLElement, advanceTimer: (time?: number) => void | Promise, pointerOpts?: {}}) {
+export async function triggerLongPress(opts: {element: HTMLElement, advanceTimer: (time?: number) => void | Promise, pointerOpts?: Record}) {
// TODO: note that this only works if the code from installPointerEvent is called somewhere in the test BEFORE the
// render. Perhaps we should rely on the user setting that up since I'm not sure there is a great way to set that up here in the
// util before first render. Will need to document it well
let {element, advanceTimer, pointerOpts = {}} = opts;
- await fireEvent.pointerDown(element, {pointerType: 'mouse', ...pointerOpts});
+ let pointerType = pointerOpts.pointerType ?? 'mouse';
+ let shouldFireCompatibilityEvents = fireEvent.pointerDown(element, {pointerType, ...pointerOpts});
+ let shouldFocus = true;
+ if (shouldFireCompatibilityEvents) {
+ if (pointerType === 'touch') {
+ shouldFocus = shouldFireCompatibilityEvents = fireEvent.touchStart(element, {targetTouches: [{identifier: pointerOpts.pointerId, clientX: pointerOpts.clientX, clientY: pointerOpts.clientY}]});
+ } else if (pointerType === 'mouse') {
+ shouldFocus = fireEvent.mouseDown(element, pointerOpts);
+ if (shouldFocus) {
+ act(() => element.focus());
+ }
+ }
+ }
await act(async () => await advanceTimer(DEFAULT_LONG_PRESS_TIME));
- await fireEvent.pointerUp(element, {pointerType: 'mouse', ...pointerOpts});
+ fireEvent.pointerUp(element, {pointerType, ...pointerOpts});
+ if (shouldFireCompatibilityEvents) {
+ if (pointerType === 'touch') {
+ shouldFocus = fireEvent.touchEnd(element, {targetTouches: [{identifier: pointerOpts.pointerId, clientX: pointerOpts.clientX, clientY: pointerOpts.clientY}]});
+ shouldFocus = fireEvent.mouseDown(element, pointerOpts);
+ if (shouldFocus) {
+ act(() => element.focus());
+ }
+ fireEvent.mouseUp(element, pointerOpts);
+ } else if (pointerType === 'mouse') {
+ fireEvent.mouseUp(element, pointerOpts);
+ }
+ }
+ fireEvent.click(element, {detail: 1, ...pointerOpts});
}
diff --git a/packages/@react-aria/test-utils/src/table.ts b/packages/@react-aria/test-utils/src/table.ts
index 614f4f9c0b2..a7a14aaf0cf 100644
--- a/packages/@react-aria/test-utils/src/table.ts
+++ b/packages/@react-aria/test-utils/src/table.ts
@@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/
-import {act, fireEvent, waitFor, within} from '@testing-library/react';
+import {act, waitFor, within} from '@testing-library/react';
import {GridRowActionOpts, TableTesterOpts, ToggleGridRowOpts, UserOpts} from './types';
import {pressElement, triggerLongPress} from './events';
@@ -88,10 +88,6 @@ export class TableTester {
// Note that long press interactions with rows is strictly touch only for grid rows
await triggerLongPress({element: cell, advanceTimer: this._advanceTimer, pointerOpts: {pointerType: 'touch'}});
- // TODO: interestingly enough, we need to do a followup click otherwise future row selections may not fire properly?
- // To reproduce, try removing this, forcing toggleRowSelection to hit "needsLongPress ? await triggerLongPress(cell) : await action(cell);" and
- // run Table.test's "should support long press to enter selection mode on touch" test to see what happens
- await fireEvent.click(cell);
} else {
await pressElement(this.user, cell, interactionType);
}
diff --git a/packages/@react-aria/tooltip/src/useTooltipTrigger.ts b/packages/@react-aria/tooltip/src/useTooltipTrigger.ts
index 14becae8ed4..fecf751b24e 100644
--- a/packages/@react-aria/tooltip/src/useTooltipTrigger.ts
+++ b/packages/@react-aria/tooltip/src/useTooltipTrigger.ts
@@ -140,7 +140,8 @@ export function useTooltipTrigger(props: TooltipTriggerProps, state: TooltipTrig
'aria-describedby': state.isOpen ? tooltipId : undefined,
...mergeProps(focusableProps, hoverProps, {
onPointerDown: onPressStart,
- onKeyDown: onPressStart
+ onKeyDown: onPressStart,
+ tabIndex: undefined
})
},
tooltipProps: {
diff --git a/packages/@react-aria/utils/src/index.ts b/packages/@react-aria/utils/src/index.ts
index 20e2ffd7b86..413e1f46639 100644
--- a/packages/@react-aria/utils/src/index.ts
+++ b/packages/@react-aria/utils/src/index.ts
@@ -49,3 +49,4 @@ export {inertValue} from './inertValue';
export {CLEAR_FOCUS_EVENT, FOCUS_EVENT, UPDATE_ACTIVEDESCENDANT} from './constants';
export {isCtrlKeyPressed} from './keyboard';
export {useEnterAnimation, useExitAnimation} from './animation';
+export {isFocusable, isTabbable} from './isFocusable';
diff --git a/packages/@react-aria/utils/src/isFocusable.ts b/packages/@react-aria/utils/src/isFocusable.ts
new file mode 100644
index 00000000000..33780652c43
--- /dev/null
+++ b/packages/@react-aria/utils/src/isFocusable.ts
@@ -0,0 +1,28 @@
+const focusableElements = [
+ 'input:not([disabled]):not([type=hidden])',
+ 'select:not([disabled])',
+ 'textarea:not([disabled])',
+ 'button:not([disabled])',
+ 'a[href]',
+ 'area[href]',
+ 'summary',
+ 'iframe',
+ 'object',
+ 'embed',
+ 'audio[controls]',
+ 'video[controls]',
+ '[contenteditable]:not([contenteditable^="false"])'
+];
+
+const FOCUSABLE_ELEMENT_SELECTOR = focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
+
+focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
+const TABBABLE_ELEMENT_SELECTOR = focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
+
+export function isFocusable(element: Element) {
+ return element.matches(FOCUSABLE_ELEMENT_SELECTOR);
+}
+
+export function isTabbable(element: Element) {
+ return element.matches(TABBABLE_ELEMENT_SELECTOR);
+}
diff --git a/packages/@react-aria/utils/src/useGlobalListeners.ts b/packages/@react-aria/utils/src/useGlobalListeners.ts
index 834dd2c5ffc..300517ad0b6 100644
--- a/packages/@react-aria/utils/src/useGlobalListeners.ts
+++ b/packages/@react-aria/utils/src/useGlobalListeners.ts
@@ -13,6 +13,7 @@
import {useCallback, useEffect, useRef} from 'react';
interface GlobalListeners {
+ addGlobalListener(el: Window, type: K, listener: (this: Document, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void,
addGlobalListener(el: EventTarget, type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void,
addGlobalListener(el: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void,
removeGlobalListener(el: EventTarget, type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void,
diff --git a/packages/@react-aria/utils/src/useUpdateEffect.ts b/packages/@react-aria/utils/src/useUpdateEffect.ts
index fab098c0c4b..17ea4ec01e4 100644
--- a/packages/@react-aria/utils/src/useUpdateEffect.ts
+++ b/packages/@react-aria/utils/src/useUpdateEffect.ts
@@ -13,7 +13,7 @@
import {EffectCallback, useEffect, useRef} from 'react';
// Like useEffect, but only called for updates after the initial render.
-export function useUpdateEffect(effect: EffectCallback, dependencies: any[]) {
+export function useUpdateEffect(effect: EffectCallback, dependencies: any[]): (() => void) | void {
const isInitialMount = useRef(true);
const lastDeps = useRef(null);
@@ -28,7 +28,7 @@ export function useUpdateEffect(effect: EffectCallback, dependencies: any[]) {
if (isInitialMount.current) {
isInitialMount.current = false;
} else if (!lastDeps.current || dependencies.some((dep, i) => !Object.is(dep, lastDeps[i]))) {
- effect();
+ return effect();
}
lastDeps.current = dependencies;
// eslint-disable-next-line react-hooks/exhaustive-deps
diff --git a/packages/@react-spectrum/calendar/test/CalendarBase.test.js b/packages/@react-spectrum/calendar/test/CalendarBase.test.js
index 39fa06f1b14..1680a007b86 100644
--- a/packages/@react-spectrum/calendar/test/CalendarBase.test.js
+++ b/packages/@react-spectrum/calendar/test/CalendarBase.test.js
@@ -759,7 +759,7 @@ describe('CalendarBase', () => {
);
let grid = getByRole('grid');
- let selected = getAllByRole('button').find(cell => cell.getAttribute('tabIndex') === '0');
+ let selected = getAllByRole('button').find(cell => cell.tagName === 'SPAN' && cell.getAttribute('tabIndex') === '0');
expect(document.activeElement).toBe(selected);
await user.keyboard('{ArrowLeft}');
@@ -779,7 +779,7 @@ describe('CalendarBase', () => {
fireEvent.blur(grid);
fireEvent.focus(grid);
- selected = getAllByRole('button').find(cell => cell.getAttribute('tabIndex') === '0');
+ selected = getAllByRole('button').find(cell => cell.tagName === 'SPAN' && cell.getAttribute('tabIndex') === '0');
expect(document.activeElement).toBe(selected);
await user.keyboard('{ArrowLeft}');
diff --git a/packages/@react-spectrum/combobox/test/ComboBox.test.js b/packages/@react-spectrum/combobox/test/ComboBox.test.js
index abddf4d2174..ebdb76e8f54 100644
--- a/packages/@react-spectrum/combobox/test/ComboBox.test.js
+++ b/packages/@react-spectrum/combobox/test/ComboBox.test.js
@@ -1708,7 +1708,7 @@ describe('ComboBox', function () {
expect(listbox).toBeVisible();
let items = within(listbox).getAllByRole('option');
- fireEvent.mouseDown(items[0]);
+ await user.pointer({target: items[0], keys: '[MouseLeft>]'});
act(() => {
jest.runAllTimers();
});
@@ -1720,7 +1720,7 @@ describe('ComboBox', function () {
expect(document.activeElement).toBe(combobox);
expect(listbox).toBeVisible();
- fireEvent.mouseUp(items[0]);
+ await user.pointer({target: items[0], keys: '[/MouseLeft]'});
act(() => {
jest.runAllTimers();
});
diff --git a/packages/@react-spectrum/datepicker/test/DatePickerBase.test.js b/packages/@react-spectrum/datepicker/test/DatePickerBase.test.js
index 7d4b4301d26..3937bb3880e 100644
--- a/packages/@react-spectrum/datepicker/test/DatePickerBase.test.js
+++ b/packages/@react-spectrum/datepicker/test/DatePickerBase.test.js
@@ -73,7 +73,7 @@ describe('DatePickerBase', function () {
let button = getAllByRole('button')[0];
expect(button).toBeVisible();
- expect(button).not.toHaveAttribute('tabindex');
+ expect(button).toHaveAttribute('tabindex', '0');
});
it.each`
diff --git a/packages/@react-spectrum/list/test/ListView.test.js b/packages/@react-spectrum/list/test/ListView.test.js
index 8eb86c93e4c..e96b694f8c6 100644
--- a/packages/@react-spectrum/list/test/ListView.test.js
+++ b/packages/@react-spectrum/list/test/ListView.test.js
@@ -13,7 +13,7 @@
jest.mock('@react-aria/live-announcer');
jest.mock('@react-aria/utils/src/scrollIntoView');
-import {act, fireEvent, installPointerEvent, mockClickDefault, pointerMap, render as renderComponent, within} from '@react-spectrum/test-utils-internal';
+import {act, fireEvent, installPointerEvent, mockClickDefault, pointerMap, render as renderComponent, triggerTouch, within} from '@react-spectrum/test-utils-internal';
import {ActionButton} from '@react-spectrum/button';
import {announce} from '@react-aria/live-announcer';
import {FocusExample} from '../stories/ListViewActions.stories';
@@ -746,8 +746,7 @@ describe('ListView', function () {
let row = tree.getAllByRole('row')[0];
await user.tab();
expect(row).toHaveAttribute('aria-selected', 'false');
- fireEvent.keyDown(row, {key: ' '});
- fireEvent.keyUp(row, {key: ' '});
+ await user.keyboard(' ');
checkSelection(onSelectionChange, ['foo']);
expect(row).toHaveAttribute('aria-selected', 'true');
@@ -761,8 +760,7 @@ describe('ListView', function () {
let row = tree.getAllByRole('row')[0];
await user.tab();
expect(row).toHaveAttribute('aria-selected', 'false');
- fireEvent.keyDown(row, {key: 'Enter'});
- fireEvent.keyUp(row, {key: 'Enter'});
+ await user.keyboard('{Enter}');
checkSelection(onSelectionChange, ['foo']);
expect(row).toHaveAttribute('aria-selected', 'true');
@@ -850,8 +848,8 @@ describe('ListView', function () {
expect(announce).toHaveBeenCalledTimes(1);
expect(gridListTester.selectedRows).toHaveLength(1);
- fireEvent.keyDown(rows[0], {key: 'a', ctrlKey: true});
- fireEvent.keyUp(rows[0], {key: 'a', ctrlKey: true});
+ await user.keyboard('{Control>}a{/Control}');
+ act(() => jest.runAllTimers());
checkSelection(onSelectionChange, 'all');
onSelectionChange.mockClear();
expect(announce).toHaveBeenLastCalledWith('All items selected.');
@@ -932,17 +930,13 @@ describe('ListView', function () {
fireEvent.pointerUp(rows[1], {pointerType: 'touch'});
onSelectionChange.mockReset();
- fireEvent.pointerDown(rows[2], {pointerType: 'touch'});
- fireEvent.pointerUp(rows[2], {pointerType: 'touch'});
-
+ triggerTouch(rows[2]);
checkSelection(onSelectionChange, ['bar', 'baz']);
// Deselect all to exit selection mode
- fireEvent.pointerDown(rows[2], {pointerType: 'touch'});
- fireEvent.pointerUp(rows[2], {pointerType: 'touch'});
+ triggerTouch(rows[2]);
onSelectionChange.mockReset();
- fireEvent.pointerDown(rows[1], {pointerType: 'touch'});
- fireEvent.pointerUp(rows[1], {pointerType: 'touch'});
+ triggerTouch(rows[1]);
act(() => jest.runAllTimers());
checkSelection(onSelectionChange, []);
@@ -1202,9 +1196,7 @@ describe('ListView', function () {
let row = tree.getAllByRole('row')[1];
expect(row).toHaveAttribute('aria-selected', 'false');
await user.keyboard('[ControlLeft>]');
- fireEvent.pointerDown(getRow(tree, 'Bar'), {pointerType: 'mouse', ctrlKey: true});
- fireEvent.pointerUp(getRow(tree, 'Bar'), {pointerType: 'mouse', ctrlKey: true});
- fireEvent.click(getRow(tree, 'Bar'), {ctrlKey: true});
+ await user.pointer({target: getRow(tree, 'Bar'), keys: '[MouseLeft]', coords: {width: 1}});
await user.keyboard('[/ControlLeft]');
checkSelection(onSelectionChange, ['bar']);
@@ -1246,22 +1238,19 @@ describe('ListView', function () {
checkSelection(onSelectionChange, ['foo']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown'});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown'});
+ await user.keyboard('{ArrowDown}');
expect(announce).toHaveBeenLastCalledWith('Bar selected.');
expect(announce).toHaveBeenCalledTimes(2);
checkSelection(onSelectionChange, ['bar']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowUp'});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowUp'});
+ await user.keyboard('{ArrowUp}');
expect(announce).toHaveBeenLastCalledWith('Foo selected.');
expect(announce).toHaveBeenCalledTimes(3);
checkSelection(onSelectionChange, ['foo']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown', shiftKey: true});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown', shiftKey: true});
+ await user.keyboard('{Shift>}{ArrowDown}{/Shift}');
expect(announce).toHaveBeenLastCalledWith('Bar selected. 2 items selected.');
expect(announce).toHaveBeenCalledTimes(4);
checkSelection(onSelectionChange, ['foo', 'bar']);
@@ -1277,15 +1266,13 @@ describe('ListView', function () {
checkSelection(onSelectionChange, ['foo']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown', shiftKey: true});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown', shiftKey: true});
+ await user.keyboard('{Shift>}{ArrowDown}{/Shift}');
expect(announce).toHaveBeenLastCalledWith('Bar selected. 2 items selected.');
expect(announce).toHaveBeenCalledTimes(2);
checkSelection(onSelectionChange, ['foo', 'bar']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown'});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown'});
+ await user.keyboard('{ArrowDown}');
expect(announce).toHaveBeenLastCalledWith('Baz selected. 1 item selected.');
checkSelection(onSelectionChange, ['baz']);
});
@@ -1300,27 +1287,23 @@ describe('ListView', function () {
checkSelection(onSelectionChange, ['foo']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
+ await user.keyboard('{Control>}{ArrowDown}{/Control}');
expect(announce).toHaveBeenCalledTimes(1);
expect(onSelectionChange).not.toHaveBeenCalled();
expect(document.activeElement).toBe(getRow(tree, 'Bar'));
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
+ await user.keyboard('{Control>}{ArrowDown}{/Control}');
expect(announce).toHaveBeenCalledTimes(1);
expect(onSelectionChange).not.toHaveBeenCalled();
expect(document.activeElement).toBe(getRow(tree, 'Baz'));
- fireEvent.keyDown(document.activeElement, {key: ' ', ctrlKey: true});
- fireEvent.keyUp(document.activeElement, {key: ' ', ctrlKey: true});
+ await user.keyboard('{Control>} {/Control}');
expect(announce).toHaveBeenCalledWith('Baz selected. 2 items selected.');
expect(announce).toHaveBeenCalledTimes(2);
checkSelection(onSelectionChange, ['foo', 'baz']);
onSelectionChange.mockClear();
- fireEvent.keyDown(document.activeElement, {key: ' '});
- fireEvent.keyUp(document.activeElement, {key: ' '});
+ await user.keyboard(' ');
expect(announce).toHaveBeenCalledWith('Baz selected. 1 item selected.');
expect(announce).toHaveBeenCalledTimes(3);
checkSelection(onSelectionChange, ['baz']);
@@ -1330,23 +1313,19 @@ describe('ListView', function () {
let tree = renderSelectionList({onSelectionChange, selectionStyle: 'highlight', onAction, selectionMode: 'multiple'});
let rows = tree.getAllByRole('row');
- fireEvent.pointerDown(rows[0], {pointerType: 'mouse'});
- fireEvent.pointerUp(rows[0], {pointerType: 'mouse'});
- fireEvent.click(rows[0], {pointerType: 'mouse'});
+ await user.pointer({target: rows[0], keys: '[MouseLeft]', coords: {width: 1}});
checkSelection(onSelectionChange, ['foo']);
onSelectionChange.mockClear();
expect(announce).toHaveBeenLastCalledWith('Foo selected.');
expect(announce).toHaveBeenCalledTimes(1);
- fireEvent.keyDown(rows[0], {key: 'a', ctrlKey: true});
- fireEvent.keyUp(rows[0], {key: 'a', ctrlKey: true});
+ await user.keyboard('{Control>}a{/Control}');
checkSelection(onSelectionChange, 'all');
onSelectionChange.mockClear();
expect(announce).toHaveBeenLastCalledWith('All items selected.');
expect(announce).toHaveBeenCalledTimes(2);
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown'});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown'});
+ await user.keyboard('{ArrowDown}');
expect(announce).toHaveBeenLastCalledWith('Bar selected. 1 item selected.');
expect(announce).toHaveBeenCalledTimes(3);
checkSelection(onSelectionChange, ['bar']);
@@ -1386,6 +1365,7 @@ describe('ListView', function () {
expect(within(rows[0]).getByRole('checkbox')).toBeTruthy();
fireEvent.pointerUp(rows[0], {pointerType: 'touch'});
+ fireEvent.click(rows[0], {detail: 1});
await user.pointer({target: rows[1], keys: '[TouchA]'});
expect(announce).toHaveBeenLastCalledWith('Bar selected. 2 items selected.');
diff --git a/packages/@react-spectrum/list/test/ListViewDnd.test.js b/packages/@react-spectrum/list/test/ListViewDnd.test.js
index d81e4fcb480..9d3e8bdfddc 100644
--- a/packages/@react-spectrum/list/test/ListViewDnd.test.js
+++ b/packages/@react-spectrum/list/test/ListViewDnd.test.js
@@ -418,6 +418,7 @@ describe('ListView', function () {
let dataTransfer = new DataTransfer();
fireEvent.pointerDown(cell, {pointerType: 'mouse', button: 0, pointerId: 1, clientX: 0, clientY: 0});
+ act(() => rows[1].focus());
fireEvent(cell, new DragEvent('dragstart', {dataTransfer, clientX: 0, clientY: 0}));
expect(onDragStart).toHaveBeenCalledTimes(1);
@@ -469,6 +470,7 @@ describe('ListView', function () {
let dataTransfer = new DataTransfer();
fireEvent.pointerDown(cell, {pointerType: 'mouse', button: 0, pointerId: 1, clientX: 0, clientY: 0});
+ act(() => rows[1].focus());
fireEvent(cell, new DragEvent('dragstart', {dataTransfer, clientX: 0, clientY: 0}));
expect(onDragStart).toHaveBeenCalledTimes(1);
@@ -2935,6 +2937,7 @@ describe('ListView', function () {
expect(draggableRow).toHaveAttribute('aria-selected', 'false');
expect(onSelectionChange).toHaveBeenCalledTimes(0);
fireEvent.pointerUp(draggableRow, {pointerType: 'mouse'});
+ fireEvent.click(draggableRow, {detail: 1});
expect(draggableRow).toHaveAttribute('aria-selected', 'true');
checkSelection(onSelectionChange, ['a']);
});
diff --git a/packages/@react-spectrum/s2/style/__tests__/style-macro.test.js b/packages/@react-spectrum/s2/style/__tests__/style-macro.test.js
index d5d1336adc5..3762768c1b6 100644
--- a/packages/@react-spectrum/s2/style/__tests__/style-macro.test.js
+++ b/packages/@react-spectrum/s2/style/__tests__/style-macro.test.js
@@ -59,7 +59,7 @@ describe('style-macro', () => {
"
`);
- expect(js).toMatchInlineSnapshot('" . A-13alit4c A-13alit4ed"');
+ expect(js).toMatchInlineSnapshot('" A-13alit4c A-13alit4ed"');
});
it('should support self references', () => {
diff --git a/packages/@react-spectrum/s2/style/style-macro.ts b/packages/@react-spectrum/s2/style/style-macro.ts
index a871a80afa4..4fa4a8d8b16 100644
--- a/packages/@react-spectrum/s2/style/style-macro.ts
+++ b/packages/@react-spectrum/s2/style/style-macro.ts
@@ -268,7 +268,7 @@ export function createTheme(theme: T): StyleFunction();
for (let [property, propertyRules] of rules) {
if (isStatic) {
diff --git a/packages/@react-spectrum/table/test/Table.test.js b/packages/@react-spectrum/table/test/Table.test.js
index d1e73383944..4d1f5683475 100644
--- a/packages/@react-spectrum/table/test/Table.test.js
+++ b/packages/@react-spectrum/table/test/Table.test.js
@@ -3183,7 +3183,9 @@ export let tableTests = () => {
expect(onAction).not.toHaveBeenCalled();
expect(tree.queryByLabelText('Select All')).not.toBeNull();
- fireEvent.pointerUp(getCell(tree, 'Baz 5'), {pointerType: 'touch'});
+ let cell = getCell(tree, 'Baz 5');
+ fireEvent.pointerUp(cell, {pointerType: 'touch'});
+ fireEvent.click(cell, {detail: 1});
onSelectionChange.mockReset();
act(() => {
jest.runAllTimers();
@@ -3231,6 +3233,7 @@ export let tableTests = () => {
await user.keyboard('{ArrowUp}'.repeat(5));
onSelectionChange.mockReset();
announce.mockReset();
+ onSelectionChange.mockReset();
await user.keyboard('{Enter}');
expect(onSelectionChange).not.toHaveBeenCalled();
expect(announce).not.toHaveBeenCalled();
@@ -3309,28 +3312,24 @@ export let tableTests = () => {
announce.mockReset();
onSelectionChange.mockReset();
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
+ await user.keyboard('{Control>}{ArrowDown}{/Control}');
expect(announce).not.toHaveBeenCalled();
expect(onSelectionChange).not.toHaveBeenCalled();
- expect(document.activeElement).toBe(getCell(tree, 'Baz 6').closest('[role="row"]'));
+ expect(document.activeElement).toBe(getCell(tree, 'Baz 6'));
- fireEvent.keyDown(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
- fireEvent.keyUp(document.activeElement, {key: 'ArrowDown', ctrlKey: true});
+ await user.keyboard('{Control>}{ArrowDown}{/Control}');
expect(announce).not.toHaveBeenCalled();
expect(onSelectionChange).not.toHaveBeenCalled();
- expect(document.activeElement).toBe(getCell(tree, 'Baz 7').closest('[role="row"]'));
+ expect(document.activeElement).toBe(getCell(tree, 'Baz 7'));
- fireEvent.keyDown(document.activeElement, {key: ' ', ctrlKey: true});
- fireEvent.keyUp(document.activeElement, {key: ' ', ctrlKey: true});
+ await user.keyboard('{Control>} {/Control}');
expect(announce).toHaveBeenCalledWith('Foo 7 selected. 2 items selected.');
expect(announce).toHaveBeenCalledTimes(1);
checkSelection(onSelectionChange, ['Foo 5', 'Foo 7']);
announce.mockReset();
onSelectionChange.mockReset();
- fireEvent.keyDown(document.activeElement, {key: ' '});
- fireEvent.keyUp(document.activeElement, {key: ' '});
+ await user.keyboard(' ');
expect(announce).toHaveBeenCalledWith('Foo 7 selected. 1 item selected.');
expect(announce).toHaveBeenCalledTimes(1);
checkSelection(onSelectionChange, ['Foo 7']);
diff --git a/packages/@react-spectrum/table/test/TableDnd.test.js b/packages/@react-spectrum/table/test/TableDnd.test.js
index 0700ba44043..d4be98204c6 100644
--- a/packages/@react-spectrum/table/test/TableDnd.test.js
+++ b/packages/@react-spectrum/table/test/TableDnd.test.js
@@ -2839,6 +2839,7 @@ describe('TableView', function () {
expect(draggableRow).toHaveAttribute('aria-selected', 'false');
expect(onSelectionChange).toHaveBeenCalledTimes(0);
fireEvent.pointerUp(draggableRow, {pointerType: 'mouse'});
+ fireEvent.click(draggableRow);
expect(draggableRow).toHaveAttribute('aria-selected', 'true');
checkSelection(onSelectionChange, ['a']);
});
diff --git a/packages/@react-spectrum/table/test/TableSizing.test.tsx b/packages/@react-spectrum/table/test/TableSizing.test.tsx
index 22440fb3020..76fb9c07b67 100644
--- a/packages/@react-spectrum/table/test/TableSizing.test.tsx
+++ b/packages/@react-spectrum/table/test/TableSizing.test.tsx
@@ -17,7 +17,7 @@ import Add from '@spectrum-icons/workflow/Add';
import {Cell, Column, Row, TableBody, TableHeader, TableView} from '../';
import {ColumnSize} from '@react-types/table';
import {ControllingResize} from '../stories/ControllingResize';
-import {fireEvent, installPointerEvent, pointerMap, simulateDesktop} from '@react-spectrum/test-utils-internal';
+import {fireEvent, installPointerEvent, pointerMap, simulateDesktop, triggerTouch} from '@react-spectrum/test-utils-internal';
import {HidingColumns} from '../stories/HidingColumns';
import {Key} from '@react-types/shared';
import {Provider} from '@react-spectrum/provider';
@@ -978,14 +978,12 @@ describe('TableViewSizing', function () {
let header = tree.getAllByRole('columnheader')[0];
let resizableHeader = within(header).getByRole('button');
- fireEvent.pointerDown(resizableHeader, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(resizableHeader, {pointerType: 'touch', pointerId: 1});
+ triggerTouch(resizableHeader);
act(() => {jest.runAllTimers();});
let resizeMenuItem = tree.getAllByRole('menuitem')[0];
- fireEvent.pointerDown(resizeMenuItem, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(resizeMenuItem, {pointerType: 'touch', pointerId: 1});
+ triggerTouch(resizeMenuItem);
act(() => {jest.runAllTimers();});
let resizer = tree.getByRole('slider');
diff --git a/packages/@react-spectrum/table/test/TreeGridTable.test.tsx b/packages/@react-spectrum/table/test/TreeGridTable.test.tsx
index 4cca024b418..180b3ce1b21 100644
--- a/packages/@react-spectrum/table/test/TreeGridTable.test.tsx
+++ b/packages/@react-spectrum/table/test/TreeGridTable.test.tsx
@@ -1413,7 +1413,7 @@ describe('TableView with expandable rows', function () {
describe('selectionStyle highlight', function () {
installPointerEvent();
- it('should toggle selection with mouse', function () {
+ it('should toggle selection with mouse', async function () {
let treegrid = render();
expect(treegrid.queryByLabelText('Select All')).toBeNull();
@@ -1422,8 +1422,7 @@ describe('TableView with expandable rows', function () {
let cell = getCell(treegrid, 'Row 1, Lvl 3, Foo');
checkRowSelection(rows, false);
- fireEvent.pointerDown(cell, {pointerType: 'mouse', pointerId: 1});
- fireEvent.pointerUp(cell, {pointerType: 'mouse', pointerId: 1});
+ await user.pointer({target: cell, keys: '[MouseLeft]', coords: {width: 1}});
act(() => jest.runAllTimers());
expect(announce).toHaveBeenLastCalledWith('Row 1, Lvl 3, Foo selected.');
expect(announce).toHaveBeenCalledTimes(1);
@@ -1432,8 +1431,7 @@ describe('TableView with expandable rows', function () {
onSelectionChange.mockReset();
cell = getCell(treegrid, 'Row 1, Lvl 1, Foo');
- fireEvent.pointerDown(cell, {pointerType: 'mouse', pointerId: 1});
- fireEvent.pointerUp(cell, {pointerType: 'mouse', pointerId: 1});
+ await user.pointer({target: cell, keys: '[MouseLeft]', coords: {width: 1}});
act(() => jest.runAllTimers());
expect(announce).toHaveBeenLastCalledWith('Row 1, Lvl 1, Foo selected.');
expect(announce).toHaveBeenCalledTimes(2);
@@ -1442,7 +1440,7 @@ describe('TableView with expandable rows', function () {
checkRowSelection(rows.slice(1), false);
});
- it('should toggle selection with touch', function () {
+ it('should toggle selection with touch', async function () {
let treegrid = render();
expect(treegrid.queryByLabelText('Select All')).toBeNull();
@@ -1451,8 +1449,7 @@ describe('TableView with expandable rows', function () {
let cell = getCell(treegrid, 'Row 1, Lvl 3, Foo');
checkRowSelection(rows, false);
- fireEvent.pointerDown(cell, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(cell, {pointerType: 'touch', pointerId: 1});
+ await user.pointer({target: cell, keys: '[TouchA]', coords: {width: 1}});
act(() => jest.runAllTimers());
expect(announce).toHaveBeenLastCalledWith('Row 1, Lvl 3, Foo selected.');
expect(announce).toHaveBeenCalledTimes(1);
@@ -1461,8 +1458,7 @@ describe('TableView with expandable rows', function () {
onSelectionChange.mockReset();
cell = getCell(treegrid, 'Row 1, Lvl 1, Foo');
- fireEvent.pointerDown(cell, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(cell, {pointerType: 'touch', pointerId: 1});
+ await user.pointer({target: cell, keys: '[TouchA]', coords: {width: 1}});
act(() => jest.runAllTimers());
expect(announce).toHaveBeenLastCalledWith('Row 1, Lvl 1, Foo selected. 2 items selected.');
expect(announce).toHaveBeenCalledTimes(2);
@@ -1478,7 +1474,7 @@ describe('TableView with expandable rows', function () {
let firstCell = getCell(treegrid, 'Row 1, Lvl 3, Foo');
let secondCell = getCell(treegrid, 'Row 1, Lvl 1, Foo');
- fireEvent.pointerDown(firstCell, {pointerType: 'touch'});
+ await user.pointer({target: firstCell, keys: '[TouchA>]', coords: {width: 1}});
expect(onSelectionChange).not.toHaveBeenCalled();
expect(onAction).not.toHaveBeenCalled();
@@ -1488,22 +1484,19 @@ describe('TableView with expandable rows', function () {
checkRowSelection([rows[2]], true);
expect(onAction).not.toHaveBeenCalled();
- fireEvent.pointerUp(firstCell, {pointerType: 'touch'});
+ await user.pointer({target: firstCell, keys: '[/TouchA]', coords: {width: 1}});
onSelectionChange.mockReset();
- fireEvent.pointerDown(secondCell, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(secondCell, {pointerType: 'touch', pointerId: 1});
+ await user.pointer({target: secondCell, keys: '[TouchA]', coords: {width: 1}});
act(() => jest.runAllTimers());
checkSelection(onSelectionChange, ['Row 1 Lvl 1', 'Row 1 Lvl 3']);
checkRowSelection([rows[0], rows[2]], true);
// Deselect all to exit selection mode
- fireEvent.pointerDown(firstCell, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(firstCell, {pointerType: 'touch', pointerId: 1});
+ await user.pointer({target: firstCell, keys: '[TouchA]', coords: {width: 1}});
act(() => jest.runAllTimers());
onSelectionChange.mockReset();
- fireEvent.pointerDown(secondCell, {pointerType: 'touch', pointerId: 1});
- fireEvent.pointerUp(secondCell, {pointerType: 'touch', pointerId: 1});
+ await user.pointer({target: secondCell, keys: '[TouchA]', coords: {width: 1}});
act(() => jest.runAllTimers());
checkSelection(onSelectionChange, []);
expect(onAction).not.toHaveBeenCalled();
@@ -1519,15 +1512,14 @@ describe('TableView with expandable rows', function () {
let cell = getCell(treegrid, 'Row 1, Lvl 3, Foo');
checkRowSelection(rows, false);
- fireEvent.pointerDown(cell, {pointerType: 'mouse', pointerId: 1});
- fireEvent.pointerUp(cell, {pointerType: 'mouse', pointerId: 1});
+ await user.pointer({target: cell, keys: '[MouseLeft]', coords: {width: 1}});
act(() => jest.runAllTimers());
expect(announce).toHaveBeenLastCalledWith('Row 1, Lvl 3, Foo selected.');
expect(announce).toHaveBeenCalledTimes(1);
checkSelection(onSelectionChange, ['Row 1 Lvl 3']);
expect(onAction).not.toHaveBeenCalled();
onSelectionChange.mockReset();
- await user.dblClick(cell);
+ await user.pointer({target: cell, keys: '[MouseLeft][MouseLeft]', coords: {width: 1}});
act(() => jest.runAllTimers());
expect(announce).toHaveBeenCalledTimes(1);
expect(onSelectionChange).not.toHaveBeenCalled();
diff --git a/packages/@react-spectrum/tree/test/TreeView.test.tsx b/packages/@react-spectrum/tree/test/TreeView.test.tsx
index 5af771e4069..be7bc2bd8a9 100644
--- a/packages/@react-spectrum/tree/test/TreeView.test.tsx
+++ b/packages/@react-spectrum/tree/test/TreeView.test.tsx
@@ -515,40 +515,40 @@ describe('Tree', () => {
let row = tree.getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
rerender(tree, );
row = tree.getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
});
- it('should not update the press state if the row is not interactive', () => {
+ it('should not update the press state if the row is not interactive', async () => {
let tree = render();
let row = tree.getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).not.toHaveAttribute('data-pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
let expandableRow = tree.getAllByRole('row')[1];
expect(expandableRow).not.toHaveAttribute('data-pressed');
- fireEvent.mouseDown(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[MouseLeft>]'});
expect(expandableRow).toHaveAttribute('data-pressed', 'true');
- fireEvent.mouseUp(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[/MouseLeft]'});
expect(expandableRow).not.toHaveAttribute('data-pressed');
// Test a completely inert expandable row
@@ -557,9 +557,9 @@ describe('Tree', () => {
expect(expandableRow).toHaveAttribute('data-disabled', 'true');
expect(expandableRow).not.toHaveAttribute('data-pressed');
- fireEvent.mouseDown(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[MouseLeft>]'});
expect(expandableRow).not.toHaveAttribute('data-pressed');
- fireEvent.mouseUp(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[/MouseLeft]'});
});
it('should support focus', async () => {
diff --git a/packages/dev/test-utils/src/events.ts b/packages/dev/test-utils/src/events.ts
index d63c19af256..c607dc427bb 100644
--- a/packages/dev/test-utils/src/events.ts
+++ b/packages/dev/test-utils/src/events.ts
@@ -14,8 +14,9 @@ import {fireEvent} from '@testing-library/react';
// Triggers a "touch" event on an element.
export function triggerTouch(element, opts = {}) {
- fireEvent.pointerDown(element, {pointerType: 'touch', ...opts});
- fireEvent.pointerUp(element, {pointerType: 'touch', ...opts});
+ fireEvent.pointerDown(element, {pointerType: 'touch', pointerId: 1, ...opts});
+ fireEvent.pointerUp(element, {pointerType: 'touch', pointerId: 1, ...opts});
+ fireEvent.click(element, opts);
}
// Mocks and prevents the next click's default operation
diff --git a/packages/react-aria-components/docs/Autocomplete.mdx b/packages/react-aria-components/docs/Autocomplete.mdx
index 82c61436e56..ec907dbbb50 100644
--- a/packages/react-aria-components/docs/Autocomplete.mdx
+++ b/packages/react-aria-components/docs/Autocomplete.mdx
@@ -105,7 +105,7 @@ function Example() {
## Anatomy
-`Autocomplete` is a controller for a child text input, such as a [TextField](TextField.html) or [SearchField](SearchField), and a collection component such as a [Menu](Menu.html) or [ListBox](ListBox.html). It enables the user to filter a list of items, and navigate via the arrow keys while keeping focus on the input.
+`Autocomplete` is a controller for a child text input, such as a [TextField](TextField.html) or [SearchField](SearchField.html), and a collection component such as a [Menu](Menu.html) or [ListBox](ListBox.html). It enables the user to filter a list of items, and navigate via the arrow keys while keeping focus on the input.
```tsx
import {UNSTABLE_Autocomplete as Autocomplete, SearchField, Menu} from 'react-aria-components';
diff --git a/packages/react-aria-components/docs/Slider.mdx b/packages/react-aria-components/docs/Slider.mdx
index 88fefdb6f18..2f84e3efc6e 100644
--- a/packages/react-aria-components/docs/Slider.mdx
+++ b/packages/react-aria-components/docs/Slider.mdx
@@ -313,7 +313,7 @@ function Example() {
### Custom value scale
-By default, slider values are precentages between 0 and 100. A different scale can be used by setting the `minValue` and `maxValue` props.
+By default, slider values are percentages between 0 and 100. A different scale can be used by setting the `minValue` and `maxValue` props.
```tsx example
fireEvent.mouseLeave(triggerButton);
fireEvent.mouseEnter(triggerButton);
fireEvent.mouseUp(triggerButton, {detail: 1});
+ fireEvent.click(triggerButton);
expect(triggerButton).toHaveAttribute('aria-expanded', 'true');
});
diff --git a/packages/react-aria-components/test/Button.test.js b/packages/react-aria-components/test/Button.test.js
index cd5acfec747..1d16303fa07 100644
--- a/packages/react-aria-components/test/Button.test.js
+++ b/packages/react-aria-components/test/Button.test.js
@@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/
-import {act, fireEvent, pointerMap, render} from '@react-spectrum/test-utils-internal';
+import {act, pointerMap, render} from '@react-spectrum/test-utils-internal';
import {Button, ButtonContext, ProgressBar, Text} from '../';
import React, {useState} from 'react';
import userEvent from '@testing-library/user-event';
@@ -103,7 +103,7 @@ describe('Button', () => {
expect(button).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let onPress = jest.fn();
let {getByRole} = render();
let button = getByRole('button');
@@ -111,11 +111,11 @@ describe('Button', () => {
expect(button).not.toHaveAttribute('data-pressed');
expect(button).not.toHaveClass('pressed');
- fireEvent.mouseDown(button);
+ await user.pointer({target: button, keys: '[MouseLeft>]'});
expect(button).toHaveAttribute('data-pressed', 'true');
expect(button).toHaveClass('pressed');
- fireEvent.mouseUp(button);
+ await user.pointer({target: button, keys: '[/MouseLeft]'});
expect(button).not.toHaveAttribute('data-pressed');
expect(button).not.toHaveClass('pressed');
@@ -130,16 +130,16 @@ describe('Button', () => {
expect(button).toHaveClass('disabled');
});
- it('should support render props', () => {
+ it('should support render props', async () => {
let {getByRole} = render();
let button = getByRole('button');
expect(button).toHaveTextContent('Test');
- fireEvent.mouseDown(button);
+ await user.pointer({target: button, keys: '[MouseLeft>]'});
expect(button).toHaveTextContent('Pressed');
- fireEvent.mouseUp(button);
+ await user.pointer({target: button, keys: '[/MouseLeft]'});
expect(button).toHaveTextContent('Test');
});
diff --git a/packages/react-aria-components/test/Calendar.test.js b/packages/react-aria-components/test/Calendar.test.js
index ec2fde00154..09eace257b5 100644
--- a/packages/react-aria-components/test/Calendar.test.js
+++ b/packages/react-aria-components/test/Calendar.test.js
@@ -200,7 +200,7 @@ describe('Calendar', () => {
expect(cell).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getByRole} = renderCalendar({}, {}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let grid = getByRole('grid');
let cell = within(grid).getAllByRole('button')[7];
@@ -208,11 +208,11 @@ describe('Calendar', () => {
expect(cell).not.toHaveAttribute('data-pressed');
expect(cell).not.toHaveClass('pressed');
- fireEvent.mouseDown(cell);
+ await user.pointer({target: cell, keys: '[MouseLeft>]'});
expect(cell).toHaveAttribute('data-pressed', 'true');
expect(cell).toHaveClass('pressed');
- fireEvent.mouseUp(cell);
+ await user.pointer({target: cell, keys: '[/MouseLeft]'});
expect(cell).not.toHaveAttribute('data-pressed');
expect(cell).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/Checkbox.test.js b/packages/react-aria-components/test/Checkbox.test.js
index fabe661b676..6754c5dd5ef 100644
--- a/packages/react-aria-components/test/Checkbox.test.js
+++ b/packages/react-aria-components/test/Checkbox.test.js
@@ -11,7 +11,7 @@
*/
import {Checkbox, CheckboxContext} from '../';
-import {fireEvent, pointerMap, render} from '@react-spectrum/test-utils-internal';
+import {pointerMap, render} from '@react-spectrum/test-utils-internal';
import React from 'react';
import userEvent from '@testing-library/user-event';
@@ -122,18 +122,18 @@ describe('Checkbox', () => {
expect(onFocusChange).toHaveBeenLastCalledWith(false);
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getByRole} = render( isPressed ? 'pressed' : ''}>Test);
let checkbox = getByRole('checkbox').closest('label');
expect(checkbox).not.toHaveAttribute('data-pressed');
expect(checkbox).not.toHaveClass('pressed');
- fireEvent.mouseDown(checkbox);
+ await user.pointer({target: checkbox, keys: '[MouseLeft>]'});
expect(checkbox).toHaveAttribute('data-pressed', 'true');
expect(checkbox).toHaveClass('pressed');
- fireEvent.mouseUp(checkbox);
+ await user.pointer({target: checkbox, keys: '[/MouseLeft]'});
expect(checkbox).not.toHaveAttribute('data-pressed');
expect(checkbox).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/GridList.test.js b/packages/react-aria-components/test/GridList.test.js
index f51f5c3107f..bb072553e80 100644
--- a/packages/react-aria-components/test/GridList.test.js
+++ b/packages/react-aria-components/test/GridList.test.js
@@ -189,34 +189,34 @@ describe('GridList', () => {
expect(row).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderGridList({selectionMode: 'multiple'}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let row = getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
expect(row).toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
- it('should not show press state when not interactive', () => {
+ it('should not show press state when not interactive', async () => {
let {getAllByRole} = renderGridList({}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let row = getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/Link.test.js b/packages/react-aria-components/test/Link.test.js
index 02b3168c6d8..04bd48763a6 100644
--- a/packages/react-aria-components/test/Link.test.js
+++ b/packages/react-aria-components/test/Link.test.js
@@ -10,8 +10,8 @@
* governing permissions and limitations under the License.
*/
-import {fireEvent, pointerMap, render} from '@react-spectrum/test-utils-internal';
import {Link, LinkContext, RouterProvider} from '../';
+import {pointerMap, render} from '@react-spectrum/test-utils-internal';
import React from 'react';
import userEvent from '@testing-library/user-event';
@@ -107,7 +107,7 @@ describe('Link', () => {
expect(link).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let onPress = jest.fn();
let {getByRole} = render( isPressed ? 'pressed' : ''} onPress={onPress}>Test);
let link = getByRole('link');
@@ -115,11 +115,11 @@ describe('Link', () => {
expect(link).not.toHaveAttribute('data-pressed');
expect(link).not.toHaveClass('pressed');
- fireEvent.mouseDown(link);
+ await user.pointer({target: link, keys: '[MouseLeft>]'});
expect(link).toHaveAttribute('data-pressed', 'true');
expect(link).toHaveClass('pressed');
- fireEvent.mouseUp(link);
+ await user.pointer({target: link, keys: '[/MouseLeft]'});
expect(link).not.toHaveAttribute('data-pressed');
expect(link).not.toHaveClass('pressed');
diff --git a/packages/react-aria-components/test/ListBox.test.js b/packages/react-aria-components/test/ListBox.test.js
index c2443fb1582..dcab5c3e5c8 100644
--- a/packages/react-aria-components/test/ListBox.test.js
+++ b/packages/react-aria-components/test/ListBox.test.js
@@ -400,34 +400,34 @@ describe('ListBox', () => {
expect(option).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderListbox({selectionMode: 'multiple'}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let option = getAllByRole('option')[0];
expect(option).not.toHaveAttribute('data-pressed');
expect(option).not.toHaveClass('pressed');
- fireEvent.mouseDown(option);
+ await user.pointer({target: option, keys: '[MouseLeft>]'});
expect(option).toHaveAttribute('data-pressed', 'true');
expect(option).toHaveClass('pressed');
- fireEvent.mouseUp(option);
+ await user.pointer({target: option, keys: '[/MouseLeft]'});
expect(option).not.toHaveAttribute('data-pressed');
expect(option).not.toHaveClass('pressed');
});
- it('should not show press state when not interactive', () => {
+ it('should not show press state when not interactive', async () => {
let {getAllByRole} = renderListbox({}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let option = getAllByRole('option')[0];
expect(option).not.toHaveAttribute('data-pressed');
expect(option).not.toHaveClass('pressed');
- fireEvent.mouseDown(option);
+ await user.pointer({target: option, keys: '[MouseLeft>]'});
expect(option).not.toHaveAttribute('data-pressed');
expect(option).not.toHaveClass('pressed');
- fireEvent.mouseUp(option);
+ await user.pointer({target: option, keys: '[/MouseLeft]'});
expect(option).not.toHaveAttribute('data-pressed');
expect(option).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/Menu.test.tsx b/packages/react-aria-components/test/Menu.test.tsx
index 226b12cb0ba..4ac8f863ef9 100644
--- a/packages/react-aria-components/test/Menu.test.tsx
+++ b/packages/react-aria-components/test/Menu.test.tsx
@@ -301,18 +301,18 @@ describe('Menu', () => {
expect(menuitem).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderMenu({}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let menuitem = getAllByRole('menuitem')[0];
expect(menuitem).not.toHaveAttribute('data-pressed');
expect(menuitem).not.toHaveClass('pressed');
- fireEvent.mouseDown(menuitem);
+ await user.pointer({target: menuitem, keys: '[MouseLeft>]'});
expect(menuitem).toHaveAttribute('data-pressed', 'true');
expect(menuitem).toHaveClass('pressed');
- fireEvent.mouseUp(menuitem);
+ await user.pointer({target: menuitem, keys: '[/MouseLeft]'});
expect(menuitem).not.toHaveAttribute('data-pressed');
expect(menuitem).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/RadioGroup.test.js b/packages/react-aria-components/test/RadioGroup.test.js
index e74268740bc..bab80b346b3 100644
--- a/packages/react-aria-components/test/RadioGroup.test.js
+++ b/packages/react-aria-components/test/RadioGroup.test.js
@@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/
-import {act, fireEvent, pointerMap, render, within} from '@react-spectrum/test-utils-internal';
+import {act, pointerMap, render, within} from '@react-spectrum/test-utils-internal';
import {Button, Dialog, DialogTrigger, FieldError, Label, Modal, Radio, RadioContext, RadioGroup, RadioGroupContext, Text} from '../';
import React from 'react';
import userEvent from '@testing-library/user-event';
@@ -166,18 +166,18 @@ describe('RadioGroup', () => {
expect(label).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderGroup({}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let radio = getAllByRole('radio')[0].closest('label');
expect(radio).not.toHaveAttribute('data-pressed');
expect(radio).not.toHaveClass('pressed');
- fireEvent.mouseDown(radio);
+ await user.pointer({target: radio, keys: '[MouseLeft>]'});
expect(radio).toHaveAttribute('data-pressed', 'true');
expect(radio).toHaveClass('pressed');
- fireEvent.mouseUp(radio);
+ await user.pointer({target: radio, keys: '[/MouseLeft]'});
expect(radio).not.toHaveAttribute('data-pressed');
expect(radio).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/RangeCalendar.test.tsx b/packages/react-aria-components/test/RangeCalendar.test.tsx
index 40205915507..8d6f69e6290 100644
--- a/packages/react-aria-components/test/RangeCalendar.test.tsx
+++ b/packages/react-aria-components/test/RangeCalendar.test.tsx
@@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/
-import {act, fireEvent, pointerMap, render, within} from '@react-spectrum/test-utils-internal';
+import {act, pointerMap, render, within} from '@react-spectrum/test-utils-internal';
import {Button, CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, Heading, RangeCalendar, RangeCalendarContext} from 'react-aria-components';
import {CalendarDate, getLocalTimeZone, startOfMonth, startOfWeek, today} from '@internationalized/date';
import {DateValue} from '@react-types/calendar';
@@ -220,7 +220,7 @@ describe('RangeCalendar', () => {
expect(cell).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getByRole} = renderCalendar({}, {}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let grid = getByRole('grid');
let cell = within(grid).getAllByRole('button')[7];
@@ -228,11 +228,11 @@ describe('RangeCalendar', () => {
expect(cell).not.toHaveAttribute('data-pressed');
expect(cell).not.toHaveClass('pressed');
- fireEvent.mouseDown(cell);
+ await user.pointer({target: cell, keys: '[MouseLeft>]'});
expect(cell).toHaveAttribute('data-pressed', 'true');
expect(cell).toHaveClass('pressed');
- fireEvent.mouseUp(cell);
+ await user.pointer({target: cell, keys: '[/MouseLeft]'});
expect(cell).not.toHaveAttribute('data-pressed');
expect(cell).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/Switch.test.js b/packages/react-aria-components/test/Switch.test.js
index 81f37548f23..987088625a8 100644
--- a/packages/react-aria-components/test/Switch.test.js
+++ b/packages/react-aria-components/test/Switch.test.js
@@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/
-import {fireEvent, pointerMap, render} from '@react-spectrum/test-utils-internal';
+import {pointerMap, render} from '@react-spectrum/test-utils-internal';
import React from 'react';
import {Switch, SwitchContext} from '../';
import userEvent from '@testing-library/user-event';
@@ -138,18 +138,18 @@ describe('Switch', () => {
expect(onFocusChange).toHaveBeenLastCalledWith(false);
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getByRole} = render( isPressed ? 'pressed' : ''}>Test);
let s = getByRole('switch').closest('label');
expect(s).not.toHaveAttribute('data-pressed');
expect(s).not.toHaveClass('pressed');
- fireEvent.mouseDown(s);
+ await user.pointer({target: s, keys: '[MouseLeft>]'});
expect(s).toHaveAttribute('data-pressed', 'true');
expect(s).toHaveClass('pressed');
- fireEvent.mouseUp(s);
+ await user.pointer({target: s, keys: '[/MouseLeft]'});
expect(s).not.toHaveAttribute('data-pressed');
expect(s).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/Table.test.js b/packages/react-aria-components/test/Table.test.js
index 3480cc758b7..a1bcbbf1df9 100644
--- a/packages/react-aria-components/test/Table.test.js
+++ b/packages/react-aria-components/test/Table.test.js
@@ -477,7 +477,7 @@ describe('Table', () => {
expect(column).toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderTable({
tableProps: {selectionMode: 'multiple'},
rowProps: {className: ({isPressed}) => isPressed ? 'pressed' : ''}
@@ -488,16 +488,16 @@ describe('Table', () => {
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
expect(row).toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
- it('should not show press state when not interactive', () => {
+ it('should not show press state when not interactive', async () => {
let {getAllByRole} = renderTable({
rowProps: {className: ({isPressed}) => isPressed ? 'pressed' : ''}
});
@@ -506,16 +506,16 @@ describe('Table', () => {
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
- it('should support row actions', () => {
+ it('should support row actions', async () => {
let onRowAction = jest.fn();
let {getAllByRole} = renderTable({
tableProps: {onRowAction},
@@ -527,11 +527,11 @@ describe('Table', () => {
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
expect(row).toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
diff --git a/packages/react-aria-components/test/Tabs.test.js b/packages/react-aria-components/test/Tabs.test.js
index bc979391568..6b39a181bcd 100644
--- a/packages/react-aria-components/test/Tabs.test.js
+++ b/packages/react-aria-components/test/Tabs.test.js
@@ -180,18 +180,18 @@ describe('Tabs', () => {
expect(tab).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderTabs({}, {}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let tab = getAllByRole('tab')[0];
expect(tab).not.toHaveAttribute('data-pressed');
expect(tab).not.toHaveClass('pressed');
- fireEvent.mouseDown(tab);
+ await user.pointer({target: tab, keys: '[MouseLeft>]'});
expect(tab).toHaveAttribute('data-pressed', 'true');
expect(tab).toHaveClass('pressed');
- fireEvent.mouseUp(tab);
+ await user.pointer({target: tab, keys: '[/MouseLeft]'});
expect(tab).not.toHaveAttribute('data-pressed');
expect(tab).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/TagGroup.test.js b/packages/react-aria-components/test/TagGroup.test.js
index 6f44b762cbb..7ec163dd5d8 100644
--- a/packages/react-aria-components/test/TagGroup.test.js
+++ b/packages/react-aria-components/test/TagGroup.test.js
@@ -176,34 +176,34 @@ describe('TagGroup', () => {
expect(row).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let {getAllByRole} = renderTagGroup({selectionMode: 'multiple'}, {}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let row = getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
expect(row).toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
- it('should not show press state when not interactive', () => {
+ it('should not show press state when not interactive', async () => {
let {getAllByRole} = renderTagGroup({}, {}, {className: ({isPressed}) => isPressed ? 'pressed' : ''});
let row = getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
diff --git a/packages/react-aria-components/test/ToggleButton.test.js b/packages/react-aria-components/test/ToggleButton.test.js
index b3614d80d4c..a3bc945ae6d 100644
--- a/packages/react-aria-components/test/ToggleButton.test.js
+++ b/packages/react-aria-components/test/ToggleButton.test.js
@@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/
-import {fireEvent, pointerMap, render} from '@react-spectrum/test-utils-internal';
+import {pointerMap, render} from '@react-spectrum/test-utils-internal';
import React from 'react';
import {ToggleButton, ToggleButtonContext} from '../';
import userEvent from '@testing-library/user-event';
@@ -93,7 +93,7 @@ describe('ToggleButton', () => {
expect(button).not.toHaveClass('focus');
});
- it('should support press state', () => {
+ it('should support press state', async () => {
let onPress = jest.fn();
let {getByRole} = render( isPressed ? 'pressed' : ''} onPress={onPress}>Test);
let button = getByRole('button');
@@ -101,11 +101,11 @@ describe('ToggleButton', () => {
expect(button).not.toHaveAttribute('data-pressed');
expect(button).not.toHaveClass('pressed');
- fireEvent.mouseDown(button);
+ await user.pointer({target: button, keys: '[MouseLeft>]'});
expect(button).toHaveAttribute('data-pressed', 'true');
expect(button).toHaveClass('pressed');
- fireEvent.mouseUp(button);
+ await user.pointer({target: button, keys: '[/MouseLeft]'});
expect(button).not.toHaveAttribute('data-pressed');
expect(button).not.toHaveClass('pressed');
diff --git a/packages/react-aria-components/test/Tree.test.tsx b/packages/react-aria-components/test/Tree.test.tsx
index b3c6df16214..98539d80ee4 100644
--- a/packages/react-aria-components/test/Tree.test.tsx
+++ b/packages/react-aria-components/test/Tree.test.tsx
@@ -497,11 +497,11 @@ describe('Tree', () => {
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
expect(row).toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
@@ -510,36 +510,36 @@ describe('Tree', () => {
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).toHaveAttribute('data-pressed', 'true');
expect(row).toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
});
- it('should not update the press state if the row is not interactive', () => {
+ it('should not update the press state if the row is not interactive', async () => {
let {getAllByRole, rerender} = render( isPressed ? 'pressed' : ''}} />);
let row = getAllByRole('row')[0];
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseDown(row);
+ await user.pointer({target: row, keys: '[MouseLeft>]'});
expect(row).not.toHaveAttribute('data-pressed');
expect(row).not.toHaveClass('pressed');
- fireEvent.mouseUp(row);
+ await user.pointer({target: row, keys: '[/MouseLeft]'});
let expandableRow = getAllByRole('row')[1];
expect(expandableRow).not.toHaveAttribute('data-pressed');
expect(expandableRow).not.toHaveClass('pressed');
- fireEvent.mouseDown(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[MouseLeft>]'});
expect(expandableRow).toHaveAttribute('data-pressed', 'true');
expect(expandableRow).toHaveClass('pressed');
- fireEvent.mouseUp(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[/MouseLeft]'});
expect(expandableRow).not.toHaveAttribute('data-pressed');
expect(expandableRow).not.toHaveClass('pressed');
@@ -550,10 +550,10 @@ describe('Tree', () => {
expect(expandableRow).not.toHaveAttribute('data-pressed');
expect(expandableRow).not.toHaveClass('pressed');
- fireEvent.mouseDown(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[MouseLeft>]'});
expect(expandableRow).not.toHaveAttribute('data-pressed');
expect(expandableRow).not.toHaveClass('pressed');
- fireEvent.mouseUp(expandableRow);
+ await user.pointer({target: expandableRow, keys: '[/MouseLeft]'});
});
it('should support focus', async () => {