mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[Flare] Fix isPressWithinResponderRegion logic (#15808)
Compare the viewport-relative coordinates of getBoundingClientRect with those
of the event's client{X,Y} values. This fixes press within scrollable nodes.
This commit is contained in:
Vendored
+13
-79
@@ -42,8 +42,8 @@ type PointerType = '' | 'mouse' | 'keyboard' | 'pen' | 'touch';
|
||||
|
||||
type PressState = {
|
||||
activationPosition: null | $ReadOnly<{|
|
||||
pageX: number,
|
||||
pageY: number,
|
||||
x: number,
|
||||
y: number,
|
||||
|}>,
|
||||
addedRootEvents: boolean,
|
||||
isActivePressed: boolean,
|
||||
@@ -247,14 +247,11 @@ function dispatchLongPressChangeEvent(
|
||||
|
||||
function activate(event: ReactResponderEvent, context, props, state) {
|
||||
const nativeEvent: any = event.nativeEvent;
|
||||
const {x, y} = getEventPageCoords(nativeEvent);
|
||||
const {x, y} = getEventViewportCoords(nativeEvent);
|
||||
const wasActivePressed = state.isActivePressed;
|
||||
state.isActivePressed = true;
|
||||
if (x !== null && y !== null) {
|
||||
state.activationPosition = {
|
||||
pageX: x,
|
||||
pageY: y,
|
||||
};
|
||||
state.activationPosition = {x, y};
|
||||
}
|
||||
|
||||
if (props.onPressStart) {
|
||||
@@ -432,66 +429,6 @@ function calculateDelayMS(delay: ?number, min = 0, fallback = 0) {
|
||||
return Math.max(min, maybeNumber != null ? maybeNumber : fallback);
|
||||
}
|
||||
|
||||
function isNodeFixedPositioned(node: Node | null | void): boolean {
|
||||
return (
|
||||
node != null &&
|
||||
(node: any).offsetParent === null &&
|
||||
!isNodeDocumentNode(node.parentNode)
|
||||
);
|
||||
}
|
||||
|
||||
function isNodeDocumentNode(node: Node | null | void): boolean {
|
||||
return node != null && node.nodeType === Node.DOCUMENT_NODE;
|
||||
}
|
||||
|
||||
function getAbsoluteBoundingClientRect(
|
||||
target: Element,
|
||||
): {left: number, right: number, bottom: number, top: number} {
|
||||
const clientRect = target.getBoundingClientRect();
|
||||
let {left, right, bottom, top} = clientRect;
|
||||
let node = target.parentNode;
|
||||
let offsetX = 0;
|
||||
let offsetY = 0;
|
||||
|
||||
// Traverse through all offset nodes
|
||||
while (node != null) {
|
||||
const parent = node.parentNode;
|
||||
const scrollTop = (node: any).scrollTop;
|
||||
const scrollLeft = (node: any).scrollLeft;
|
||||
|
||||
// We first need to check if it's a scrollable container by
|
||||
// checking if either scrollLeft or scrollTop are not 0.
|
||||
// Then we check if either the current node or its parent
|
||||
// are fixed position, using offsetParent node for a fast-path.
|
||||
// We need to check both as offsetParent accounts for both
|
||||
// itself and the parent; so we need to align with that API.
|
||||
// If these all pass, we can skip traversing the relevant
|
||||
// node and go directly to its parent.
|
||||
if (scrollLeft !== 0 || scrollTop !== 0) {
|
||||
if (isNodeFixedPositioned(parent)) {
|
||||
node = ((parent: any): Node).parentNode;
|
||||
continue;
|
||||
}
|
||||
if (isNodeFixedPositioned(node)) {
|
||||
node = parent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
offsetX += scrollLeft;
|
||||
offsetY += scrollTop;
|
||||
if (isNodeDocumentNode(parent)) {
|
||||
break;
|
||||
}
|
||||
node = parent;
|
||||
}
|
||||
return {
|
||||
left: left + offsetX,
|
||||
right: right + offsetX,
|
||||
bottom: bottom + offsetY,
|
||||
top: top + offsetY,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: account for touch hit slop
|
||||
function calculateResponderRegion(
|
||||
context: ReactResponderContext,
|
||||
@@ -504,8 +441,7 @@ function calculateResponderRegion(
|
||||
props.pressRetentionOffset,
|
||||
);
|
||||
|
||||
const clientRect = getAbsoluteBoundingClientRect(target);
|
||||
let {left, right, bottom, top} = clientRect;
|
||||
let {left, right, bottom, top} = target.getBoundingClientRect();
|
||||
|
||||
if (pressRetentionOffset) {
|
||||
if (pressRetentionOffset.bottom != null) {
|
||||
@@ -543,18 +479,18 @@ function getTouchFromPressEvent(nativeEvent: TouchEvent): Touch {
|
||||
: (nativeEvent: any);
|
||||
}
|
||||
|
||||
function getEventPageCoords(
|
||||
function getEventViewportCoords(
|
||||
nativeEvent: Event,
|
||||
): {x: null | number, y: null | number} {
|
||||
let eventObject = (nativeEvent: any);
|
||||
if (isTouchEvent(eventObject)) {
|
||||
eventObject = getTouchFromPressEvent(eventObject);
|
||||
}
|
||||
const pageX = eventObject.pageX;
|
||||
const pageY = eventObject.pageY;
|
||||
const x = eventObject.clientX;
|
||||
const y = eventObject.clientY;
|
||||
return {
|
||||
x: pageX != null ? pageX : null,
|
||||
y: pageY != null ? pageY : null,
|
||||
x: x != null ? x : null,
|
||||
y: y != null ? y : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -578,7 +514,7 @@ function isPressWithinResponderRegion(
|
||||
bottom = Math.max(bottom, responderRegionOnDeactivation.bottom);
|
||||
}
|
||||
}
|
||||
const {x, y} = getEventPageCoords(((nativeEvent: any): Event));
|
||||
const {x, y} = getEventViewportCoords(((nativeEvent: any): Event));
|
||||
|
||||
return (
|
||||
left != null &&
|
||||
@@ -833,10 +769,8 @@ const PressResponder = {
|
||||
state.activationPosition != null &&
|
||||
state.longPressTimeout != null
|
||||
) {
|
||||
const deltaX =
|
||||
state.activationPosition.pageX - nativeEvent.pageX;
|
||||
const deltaY =
|
||||
state.activationPosition.pageY - nativeEvent.pageY;
|
||||
const deltaX = state.activationPosition.x - nativeEvent.clientX;
|
||||
const deltaY = state.activationPosition.y - nativeEvent.clientY;
|
||||
if (
|
||||
Math.hypot(deltaX, deltaY) > 10 &&
|
||||
state.longPressTimeout != null
|
||||
|
||||
@@ -206,8 +206,8 @@ describe('Event responder: Press', () => {
|
||||
expect(onPressStart).toHaveBeenCalledTimes(0);
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {
|
||||
pageX: 55,
|
||||
pageY: 55,
|
||||
clientX: 55,
|
||||
clientY: 55,
|
||||
}),
|
||||
);
|
||||
expect(onPressStart).toHaveBeenCalledTimes(1);
|
||||
@@ -471,8 +471,8 @@ describe('Event responder: Press', () => {
|
||||
jest.advanceTimersByTime(100);
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {
|
||||
pageX: 55,
|
||||
pageY: 55,
|
||||
clientX: 55,
|
||||
clientY: 55,
|
||||
}),
|
||||
);
|
||||
jest.advanceTimersByTime(10);
|
||||
@@ -544,7 +544,7 @@ describe('Event responder: Press', () => {
|
||||
createEvent('pointerdown', {pointerType: 'pen'}),
|
||||
);
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
expect(onPress).toHaveBeenCalledTimes(1);
|
||||
expect(onPress).toHaveBeenCalledWith(
|
||||
@@ -592,7 +592,7 @@ describe('Event responder: Press', () => {
|
||||
|
||||
ref.current.dispatchEvent(createEvent('pointerdown'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
expect(onPress).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -668,10 +668,10 @@ describe('Event responder: Press', () => {
|
||||
right: 100,
|
||||
});
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerdown', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerdown', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointermove', {pageX: 50, pageY: 50}),
|
||||
createEvent('pointermove', {clientX: 50, clientY: 50}),
|
||||
);
|
||||
jest.runAllTimers();
|
||||
expect(onLongPress).not.toBeCalled();
|
||||
@@ -820,8 +820,8 @@ describe('Event responder: Press', () => {
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointermove', {
|
||||
pointerType: 'touch',
|
||||
pageX: 10,
|
||||
pageY: 10,
|
||||
clientX: 10,
|
||||
clientY: 10,
|
||||
}),
|
||||
);
|
||||
expect(onPressMove).toHaveBeenCalledTimes(1);
|
||||
@@ -850,8 +850,8 @@ describe('Event responder: Press', () => {
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointermove', {
|
||||
pointerType: 'mouse',
|
||||
pageX: 10,
|
||||
pageY: 10,
|
||||
clientX: 10,
|
||||
clientY: 10,
|
||||
}),
|
||||
);
|
||||
expect(onPressMove).not.toBeCalled();
|
||||
@@ -880,8 +880,8 @@ describe('Event responder: Press', () => {
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointermove', {
|
||||
pointerType: 'touch',
|
||||
pageX: 10,
|
||||
pageY: 10,
|
||||
clientX: 10,
|
||||
clientY: 10,
|
||||
}),
|
||||
);
|
||||
ref.current.dispatchEvent(createEvent('touchmove'));
|
||||
@@ -902,12 +902,12 @@ describe('Event responder: Press', () => {
|
||||
const pressRectOffset = 20;
|
||||
const getBoundingClientRectMock = () => rectMock;
|
||||
const coordinatesInside = {
|
||||
pageX: rectMock.left - pressRectOffset,
|
||||
pageY: rectMock.top - pressRectOffset,
|
||||
clientX: rectMock.left - pressRectOffset,
|
||||
clientY: rectMock.top - pressRectOffset,
|
||||
};
|
||||
const coordinatesOutside = {
|
||||
pageX: rectMock.left - pressRectOffset - 1,
|
||||
pageY: rectMock.top - pressRectOffset - 1,
|
||||
clientX: rectMock.left - pressRectOffset - 1,
|
||||
clientY: rectMock.top - pressRectOffset - 1,
|
||||
};
|
||||
|
||||
describe('within bounds of hit rect', () => {
|
||||
@@ -1019,8 +1019,8 @@ describe('Event responder: Press', () => {
|
||||
ref.current.dispatchEvent(createEvent('pointerdown'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointermove', {
|
||||
pageX: rectMock.left - pressRetentionOffset.left,
|
||||
pageY: rectMock.top - pressRetentionOffset.top,
|
||||
clientX: rectMock.left - pressRetentionOffset.left,
|
||||
clientY: rectMock.top - pressRetentionOffset.top,
|
||||
}),
|
||||
);
|
||||
ref.current.dispatchEvent(createEvent('pointerup', coordinatesInside));
|
||||
@@ -1063,8 +1063,8 @@ describe('Event responder: Press', () => {
|
||||
bottom: 490,
|
||||
});
|
||||
const coordinates = {
|
||||
pageX: rectMock.left,
|
||||
pageY: rectMock.top,
|
||||
clientX: rectMock.left,
|
||||
clientY: rectMock.top,
|
||||
};
|
||||
// move to an area within the pre-activation region
|
||||
ref.current.dispatchEvent(createEvent('pointermove', coordinates));
|
||||
@@ -1101,8 +1101,8 @@ describe('Event responder: Press', () => {
|
||||
bottom: 550,
|
||||
});
|
||||
const coordinates = {
|
||||
pageX: rectMock.left - 50,
|
||||
pageY: rectMock.top - 50,
|
||||
clientX: rectMock.left - 50,
|
||||
clientY: rectMock.top - 50,
|
||||
};
|
||||
// move to an area within the post-activation region
|
||||
ref.current.dispatchEvent(createEvent('pointermove', coordinates));
|
||||
@@ -1111,176 +1111,6 @@ describe('Event responder: Press', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('the page offset changes', () => {
|
||||
it('"onPress" is called on release', () => {
|
||||
let events = [];
|
||||
const ref = React.createRef();
|
||||
const createEventHandler = msg => () => {
|
||||
events.push(msg);
|
||||
};
|
||||
|
||||
const element = (
|
||||
<Press
|
||||
onPress={createEventHandler('onPress')}
|
||||
onPressChange={createEventHandler('onPressChange')}
|
||||
onPressMove={createEventHandler('onPressMove')}
|
||||
onPressStart={createEventHandler('onPressStart')}
|
||||
onPressEnd={createEventHandler('onPressEnd')}>
|
||||
<div ref={ref} />
|
||||
</Press>
|
||||
);
|
||||
|
||||
ReactDOM.render(element, container);
|
||||
|
||||
ref.current.getBoundingClientRect = getBoundingClientRectMock;
|
||||
// Emulate the <html> element being offset with scroll
|
||||
document.firstElementChild.scrollTop = 1000;
|
||||
const updatedCoordinatesInside = {
|
||||
pageX: coordinatesInside.pageX,
|
||||
pageY: coordinatesInside.pageY + 1000,
|
||||
};
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerdown', updatedCoordinatesInside),
|
||||
);
|
||||
container.dispatchEvent(
|
||||
createEvent('pointermove', updatedCoordinatesInside),
|
||||
);
|
||||
container.dispatchEvent(
|
||||
createEvent('pointerup', updatedCoordinatesInside),
|
||||
);
|
||||
jest.runAllTimers();
|
||||
document.firstElementChild.scrollTop = 0;
|
||||
|
||||
expect(events).toEqual([
|
||||
'onPressStart',
|
||||
'onPressChange',
|
||||
'onPressMove',
|
||||
'onPressEnd',
|
||||
'onPressChange',
|
||||
'onPress',
|
||||
]);
|
||||
});
|
||||
|
||||
it('"onPress" is called on release inside a fixed container', () => {
|
||||
let events = [];
|
||||
const ref = React.createRef();
|
||||
const fixedContainerRef = React.createRef();
|
||||
const createEventHandler = msg => () => {
|
||||
events.push(msg);
|
||||
};
|
||||
|
||||
const element = (
|
||||
<div ref={fixedContainerRef}>
|
||||
<Press
|
||||
onPress={createEventHandler('onPress')}
|
||||
onPressChange={createEventHandler('onPressChange')}
|
||||
onPressMove={createEventHandler('onPressMove')}
|
||||
onPressStart={createEventHandler('onPressStart')}
|
||||
onPressEnd={createEventHandler('onPressEnd')}>
|
||||
<div ref={ref} />
|
||||
</Press>
|
||||
</div>
|
||||
);
|
||||
|
||||
ReactDOM.render(element, container);
|
||||
|
||||
const fixedDiv = fixedContainerRef.current;
|
||||
Object.defineProperty(fixedDiv, 'offsetParent', {
|
||||
value: null,
|
||||
});
|
||||
|
||||
// The fixed container is not scrolled
|
||||
fixedDiv.scrollTop = 0;
|
||||
fixedDiv.scrollLeft = 0;
|
||||
ref.current.getBoundingClientRect = getBoundingClientRectMock;
|
||||
// Emulate the <html> element being offset with scroll
|
||||
document.firstElementChild.scrollTop = 1000;
|
||||
const updatedCoordinatesInside = {
|
||||
pageX: coordinatesInside.pageX,
|
||||
pageY: coordinatesInside.pageY + 1000,
|
||||
};
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerdown', updatedCoordinatesInside),
|
||||
);
|
||||
container.dispatchEvent(
|
||||
createEvent('pointermove', updatedCoordinatesInside),
|
||||
);
|
||||
container.dispatchEvent(
|
||||
createEvent('pointerup', updatedCoordinatesInside),
|
||||
);
|
||||
jest.runAllTimers();
|
||||
document.firstElementChild.scrollTop = 0;
|
||||
|
||||
expect(events).toEqual([
|
||||
'onPressStart',
|
||||
'onPressChange',
|
||||
'onPressMove',
|
||||
'onPressEnd',
|
||||
'onPressChange',
|
||||
'onPress',
|
||||
]);
|
||||
});
|
||||
|
||||
it('"onPress" is called on release inside a fixed scrolled container', () => {
|
||||
let events = [];
|
||||
const ref = React.createRef();
|
||||
const fixedContainerRef = React.createRef();
|
||||
const createEventHandler = msg => () => {
|
||||
events.push(msg);
|
||||
};
|
||||
|
||||
const element = (
|
||||
<div ref={fixedContainerRef}>
|
||||
<Press
|
||||
onPress={createEventHandler('onPress')}
|
||||
onPressChange={createEventHandler('onPressChange')}
|
||||
onPressMove={createEventHandler('onPressMove')}
|
||||
onPressStart={createEventHandler('onPressStart')}
|
||||
onPressEnd={createEventHandler('onPressEnd')}>
|
||||
<div ref={ref} />
|
||||
</Press>
|
||||
</div>
|
||||
);
|
||||
|
||||
ReactDOM.render(element, container);
|
||||
|
||||
const fixedDiv = fixedContainerRef.current;
|
||||
Object.defineProperty(fixedDiv, 'offsetParent', {
|
||||
value: null,
|
||||
});
|
||||
|
||||
// The fixed container is scrolled
|
||||
fixedDiv.scrollTop = 100;
|
||||
ref.current.getBoundingClientRect = getBoundingClientRectMock;
|
||||
// Emulate the <html> element being offset with scroll
|
||||
document.firstElementChild.scrollTop = 1000;
|
||||
const updatedCoordinatesInside = {
|
||||
pageX: coordinatesInside.pageX,
|
||||
pageY: coordinatesInside.pageY + 1100,
|
||||
};
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerdown', updatedCoordinatesInside),
|
||||
);
|
||||
container.dispatchEvent(
|
||||
createEvent('pointermove', updatedCoordinatesInside),
|
||||
);
|
||||
container.dispatchEvent(
|
||||
createEvent('pointerup', updatedCoordinatesInside),
|
||||
);
|
||||
jest.runAllTimers();
|
||||
document.firstElementChild.scrollTop = 0;
|
||||
|
||||
expect(events).toEqual([
|
||||
'onPressStart',
|
||||
'onPressChange',
|
||||
'onPressMove',
|
||||
'onPressEnd',
|
||||
'onPressChange',
|
||||
'onPress',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('beyond bounds of hit rect', () => {
|
||||
/** ┌──────────────────┐
|
||||
* │ ┌────────────┐ │
|
||||
@@ -1569,16 +1399,16 @@ describe('Event responder: Press', () => {
|
||||
const coordinatesInside = {
|
||||
changedTouches: [
|
||||
{
|
||||
pageX: rectMock.left - pressRectOffset,
|
||||
pageY: rectMock.top - pressRectOffset,
|
||||
clientX: rectMock.left - pressRectOffset,
|
||||
clientY: rectMock.top - pressRectOffset,
|
||||
},
|
||||
],
|
||||
};
|
||||
const coordinatesOutside = {
|
||||
changedTouches: [
|
||||
{
|
||||
pageX: rectMock.left - pressRectOffset - 1,
|
||||
pageY: rectMock.top - pressRectOffset - 1,
|
||||
clientX: rectMock.left - pressRectOffset - 1,
|
||||
clientY: rectMock.top - pressRectOffset - 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1688,8 +1518,8 @@ describe('Event responder: Press', () => {
|
||||
ref.current.dispatchEvent(createEvent('touchstart'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('touchmove', {
|
||||
pageX: rectMock.left - pressRetentionOffset.left,
|
||||
pageY: rectMock.top - pressRetentionOffset.top,
|
||||
clientX: rectMock.left - pressRetentionOffset.left,
|
||||
clientY: rectMock.top - pressRetentionOffset.top,
|
||||
}),
|
||||
);
|
||||
ref.current.dispatchEvent(createEvent('touchend', coordinatesInside));
|
||||
@@ -1732,8 +1562,8 @@ describe('Event responder: Press', () => {
|
||||
bottom: 490,
|
||||
});
|
||||
const coordinates = {
|
||||
pageX: rectMock.left,
|
||||
pageY: rectMock.top,
|
||||
clientX: rectMock.left,
|
||||
clientY: rectMock.top,
|
||||
};
|
||||
// move to an area within the pre-activation region
|
||||
ref.current.dispatchEvent(createEvent('touchmove', coordinates));
|
||||
@@ -1770,8 +1600,8 @@ describe('Event responder: Press', () => {
|
||||
bottom: 550,
|
||||
});
|
||||
const coordinates = {
|
||||
pageX: rectMock.left - 50,
|
||||
pageY: rectMock.top - 50,
|
||||
clientX: rectMock.left - 50,
|
||||
clientY: rectMock.top - 50,
|
||||
};
|
||||
// move to an area within the post-activation region
|
||||
ref.current.dispatchEvent(createEvent('touchmove', coordinates));
|
||||
@@ -1963,11 +1793,11 @@ describe('Event responder: Press', () => {
|
||||
events = [];
|
||||
ref.current.dispatchEvent(createEvent('pointerdown'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
ref.current.dispatchEvent(createEvent('pointerdown'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
jest.runAllTimers();
|
||||
|
||||
@@ -1987,7 +1817,7 @@ describe('Event responder: Press', () => {
|
||||
jest.advanceTimersByTime(250);
|
||||
jest.advanceTimersByTime(500);
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
jest.runAllTimers();
|
||||
|
||||
@@ -2045,7 +1875,7 @@ describe('Event responder: Press', () => {
|
||||
|
||||
ref.current.dispatchEvent(createEvent('pointerdown'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
expect(events).toEqual([
|
||||
'inner: onPressStart',
|
||||
@@ -2079,7 +1909,7 @@ describe('Event responder: Press', () => {
|
||||
|
||||
ref.current.dispatchEvent(createEvent('pointerdown'));
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerup', {pageX: 10, pageY: 10}),
|
||||
createEvent('pointerup', {clientX: 10, clientY: 10}),
|
||||
);
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -2344,6 +2174,13 @@ describe('Event responder: Press', () => {
|
||||
);
|
||||
ReactDOM.render(element, container);
|
||||
|
||||
ref.current.getBoundingClientRect = () => ({
|
||||
top: 10,
|
||||
left: 10,
|
||||
bottom: 20,
|
||||
right: 20,
|
||||
});
|
||||
|
||||
ref.current.dispatchEvent(
|
||||
createEvent('pointerdown', {
|
||||
pointerType: 'mouse',
|
||||
|
||||
Reference in New Issue
Block a user