diff --git a/packages/react-events/docs/Press.md b/packages/react-events/docs/Press.md index 00addb9484..bc95b88c96 100644 --- a/packages/react-events/docs/Press.md +++ b/packages/react-events/docs/Press.md @@ -3,9 +3,9 @@ The `Press` module responds to press events on the element it wraps. Press events are dispatched for `mouse`, `pen`, `touch`, `trackpad`, and `keyboard` pointer types. Press events are only dispatched for keyboards when pressing the -Enter or Spacebar keys. If neither `onPress` nor `onLongPress` are called, this -signifies that the press ended outside of the element hit bounds (i.e., the user -aborted the press). +Enter or Spacebar keys. If `onPress` is not called, this signifies that the +press ended outside of the element hit bounds (i.e., the user aborted the +press). Press events do not propagate between `Press` event responders. @@ -17,7 +17,6 @@ const Button = (props) => (
void - -Called once the element has been pressed for the length of `delayLongPress`. If -the press point moves more than 10px `onLongPress` is cancelled. - -### onLongPressChange: boolean => void - -Called when the element changes long-press state. - -### longPressShouldCancelPress: () => boolean - -Determines whether calling `onPress` should be cancelled if `onLongPress` or -`onLongPressChange` have already been called. Default is `false`. - ### onPress: (e: PressEvent) => void -Called immediately after a press is released, unless either 1) the press is -released outside the hit bounds of the element (accounting for -`pressRetentionOffset`), or 2) the press was a long press, -and `onLongPress` or `onLongPressChange` props are provided, and -`onLongPressCancelsPress()` is `true`. +Called immediately after a press is released, unless the press is released +outside the hit bounds of the element (accounting for `pressRetentionOffset`. ### onPressChange: boolean => void @@ -164,7 +140,6 @@ is still called. Whether to `preventDefault()` native events. Native behavior is prevented by default. If an anchor is the child of `Press`, internal and external navigation -should be performed in `onPress`/`onLongPress`. To rely on native behavior -instead, set `preventDefault` to `false`, but be aware that native behavior will -take place immediately after interaction without respect for delays or long -press. +should be performed in `onPress`. To rely on native behavior instead, set +`preventDefault` to `false`, but be aware that native behavior will take place +immediately after interaction without respect for delays or long press. diff --git a/packages/react-events/src/dom/Press.js b/packages/react-events/src/dom/Press.js index b2d8941590..732ee866f6 100644 --- a/packages/react-events/src/dom/Press.js +++ b/packages/react-events/src/dom/Press.js @@ -19,8 +19,6 @@ import {DiscreteEvent, UserBlockingEvent} from 'shared/ReactTypes'; type PressListenerProps = {| onContextMenu: (e: PressEvent) => void, - onLongPress: (e: PressEvent) => void, - onLongPressChange: boolean => void, onPress: (e: PressEvent) => void, onPressChange: boolean => void, onPressEnd: (e: PressEvent) => void, @@ -30,7 +28,6 @@ type PressListenerProps = {| type PressProps = {| disabled: boolean, - delayLongPress: number, delayPressEnd: number, delayPressStart: number, pressRetentionOffset: { @@ -42,8 +39,6 @@ type PressProps = {| preventContextMenu: boolean, preventDefault: boolean, stopPropagation: boolean, - enableLongPress: boolean, - longPressShouldCancelPress: () => boolean, |}; type PressState = { @@ -54,10 +49,8 @@ type PressState = { addedRootEvents: boolean, isActivePressed: boolean, isActivePressStart: boolean, - isLongPressed: boolean, isPressed: boolean, isPressWithinResponderRegion: boolean, - longPressTimeout: null | number, pointerType: PointerType, pressTarget: null | Element | Document, pressEndTimeout: null | number, @@ -86,8 +79,6 @@ type PressEventType = | 'pressstart' | 'pressend' | 'presschange' - | 'longpress' - | 'longpresschange' | 'contextmenu'; type PressEvent = {| @@ -117,7 +108,6 @@ const isMac = : false; const DEFAULT_PRESS_END_DELAY_MS = 0; const DEFAULT_PRESS_START_DELAY_MS = 0; -const DEFAULT_LONG_PRESS_DELAY_MS = 500; const DEFAULT_PRESS_RETENTION_OFFSET = { bottom: 20, top: 20, @@ -250,14 +240,6 @@ function dispatchPressChangeEvent( context.dispatchEvent('onPressChange', bool, DiscreteEvent); } -function dispatchLongPressChangeEvent( - context: ReactDOMResponderContext, - state: PressState, -): void { - const bool = state.isLongPressed; - context.dispatchEvent('onLongPressChange', bool, DiscreteEvent); -} - function activate(event: ReactDOMResponderEvent, context, props, state) { const nativeEvent: any = event.nativeEvent; const {clientX: x, clientY: y} = state.touchEvent || nativeEvent; @@ -281,15 +263,10 @@ function activate(event: ReactDOMResponderEvent, context, props, state) { } function deactivate(event: ?ReactDOMResponderEvent, context, props, state) { - const wasLongPressed = state.isLongPressed; state.isActivePressed = false; - state.isLongPressed = false; dispatchEvent('onPressEnd', event, context, state, 'pressend', DiscreteEvent); dispatchPressChangeEvent(context, state); - if (wasLongPressed && props.enableLongPress) { - dispatchLongPressChangeEvent(context, state); - } } function dispatchPressStartEvents( @@ -308,27 +285,6 @@ function dispatchPressStartEvents( const dispatch = () => { state.isActivePressStart = true; activate(event, context, props, state); - - if (!state.isLongPressed && props.enableLongPress) { - const delayLongPress = calculateDelayMS( - props.delayLongPress, - 10, - DEFAULT_LONG_PRESS_DELAY_MS, - ); - state.longPressTimeout = context.setTimeout(() => { - state.isLongPressed = true; - state.longPressTimeout = null; - dispatchEvent( - 'onLongPress', - event, - context, - state, - 'longpress', - DiscreteEvent, - ); - dispatchLongPressChangeEvent(context, state); - }, delayLongPress); - } }; if (!state.isActivePressStart) { @@ -360,11 +316,6 @@ function dispatchPressEndEvents( state.isActivePressStart = false; state.isPressed = false; - if (state.longPressTimeout !== null) { - context.clearTimeout(state.longPressTimeout); - state.longPressTimeout = null; - } - if (!wasActivePressStart && state.pressStartTimeout !== null) { context.clearTimeout(state.pressStartTimeout); state.pressStartTimeout = null; @@ -596,10 +547,8 @@ const pressResponderImpl = { addedRootEvents: false, isActivePressed: false, isActivePressStart: false, - isLongPressed: false, isPressed: false, isPressWithinResponderRegion: true, - longPressTimeout: null, pointerType: '', pressEndTimeout: null, pressStartTimeout: null, @@ -823,19 +772,6 @@ const pressResponderImpl = { 'pressmove', UserBlockingEvent, ); - if ( - state.activationPosition != null && - state.longPressTimeout != null - ) { - const deltaX = state.activationPosition.x - nativeEvent.clientX; - const deltaY = state.activationPosition.y - nativeEvent.clientY; - if ( - Math.hypot(deltaX, deltaY) > 10 && - state.longPressTimeout != null - ) { - context.clearTimeout(state.longPressTimeout); - } - } } else { dispatchPressStartEvents(event, context, props, state); } @@ -900,7 +836,6 @@ const pressResponderImpl = { } } - const wasLongPressed = state.isLongPressed; const pressTarget = state.pressTarget; dispatchPressEndEvents(event, context, props, state); @@ -928,23 +863,14 @@ const pressResponderImpl = { } } if (state.isPressWithinResponderRegion && button !== 1) { - if ( - !( - wasLongPressed && - props.enableLongPress && - props.longPressShouldCancelPress && - props.longPressShouldCancelPress() - ) - ) { - dispatchEvent( - 'onPress', - event, - context, - state, - 'press', - DiscreteEvent, - ); - } + dispatchEvent( + 'onPress', + event, + context, + state, + 'press', + DiscreteEvent, + ); } } state.touchEvent = null; diff --git a/packages/react-events/src/dom/__tests__/Press-test.internal.js b/packages/react-events/src/dom/__tests__/Press-test.internal.js index 6c9930811c..adbac1adc1 100644 --- a/packages/react-events/src/dom/__tests__/Press-test.internal.js +++ b/packages/react-events/src/dom/__tests__/Press-test.internal.js @@ -928,258 +928,6 @@ describe('Event responder: Press', () => { // }); }); - describe('onLongPress', () => { - let onLongPress, ref; - - beforeEach(() => { - onLongPress = jest.fn(); - ref = React.createRef(); - const Component = () => { - usePressListener({ - onLongPress, - }); - return ( -
} - /> - ); - }; - ReactDOM.render(, container); - }); - - it('is called if "pointerdown" lasts default delay', () => { - ref.current.dispatchEvent( - createEvent('pointerdown', {pointerType: 'pen'}), - ); - ref.current.dispatchEvent( - createTouchEvent('touchstart', 0, { - target: ref.current, - }), - ); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY - 1); - expect(onLongPress).not.toBeCalled(); - jest.advanceTimersByTime(1); - expect(onLongPress).toHaveBeenCalledTimes(1); - expect(onLongPress).toHaveBeenCalledWith( - expect.objectContaining({pointerType: 'pen', type: 'longpress'}), - ); - }); - - it('is not called if "pointerup" is dispatched before delay', () => { - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY - 1); - ref.current.dispatchEvent(createEvent('pointerup')); - jest.advanceTimersByTime(1); - expect(onLongPress).not.toBeCalled(); - }); - - it('is called if valid "keydown" lasts default delay', () => { - ref.current.dispatchEvent(createKeyboardEvent('keydown', {key: 'Enter'})); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY - 1); - expect(onLongPress).not.toBeCalled(); - jest.advanceTimersByTime(1); - expect(onLongPress).toHaveBeenCalledTimes(1); - expect(onLongPress).toHaveBeenCalledWith( - expect.objectContaining({pointerType: 'keyboard', type: 'longpress'}), - ); - }); - - it('is not called if valid "keyup" is dispatched before delay', () => { - ref.current.dispatchEvent(createKeyboardEvent('keydown', {key: 'Enter'})); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY - 1); - ref.current.dispatchEvent(createKeyboardEvent('keyup', {key: 'Enter'})); - jest.advanceTimersByTime(1); - expect(onLongPress).not.toBeCalled(); - }); - - it('is not called when a large enough move occurs before delay', () => { - ref.current.getBoundingClientRect = () => ({ - top: 0, - left: 0, - bottom: 100, - right: 100, - }); - ref.current.dispatchEvent( - createEvent('pointerdown', {clientX: 10, clientY: 10}), - ); - ref.current.dispatchEvent( - createEvent('pointermove', {clientX: 50, clientY: 50}), - ); - jest.runAllTimers(); - expect(onLongPress).not.toBeCalled(); - }); - - describe('delayLongPress', () => { - it('can be configured', () => { - const Component = () => { - usePressListener({ - onLongPress, - }); - return ( -
- } - /> - ); - }; - ReactDOM.render(, container); - - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime(1999); - expect(onLongPress).not.toBeCalled(); - jest.advanceTimersByTime(1); - expect(onLongPress).toHaveBeenCalledTimes(1); - }); - - it('uses 10ms minimum delay length', () => { - const Component = () => { - usePressListener({ - onLongPress, - }); - return ( -
- } - /> - ); - }; - ReactDOM.render(, container); - - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime(9); - expect(onLongPress).not.toBeCalled(); - jest.advanceTimersByTime(1); - expect(onLongPress).toHaveBeenCalledTimes(1); - }); - - it('compounds with "delayPressStart"', () => { - const delayPressStart = 100; - const Component = () => { - usePressListener({ - onLongPress, - }); - return ( -
- } - /> - ); - }; - ReactDOM.render(, container); - - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime( - delayPressStart + DEFAULT_LONG_PRESS_DELAY - 1, - ); - expect(onLongPress).not.toBeCalled(); - jest.advanceTimersByTime(1); - expect(onLongPress).toHaveBeenCalledTimes(1); - }); - }); - }); - - describe('onLongPressChange', () => { - it('is called when long press state changes', () => { - const onLongPressChange = jest.fn(); - const ref = React.createRef(); - const Component = () => { - usePressListener({ - onLongPressChange, - }); - return ( -
} - /> - ); - }; - ReactDOM.render(, container); - - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY); - expect(onLongPressChange).toHaveBeenCalledTimes(1); - expect(onLongPressChange).toHaveBeenCalledWith(true); - ref.current.dispatchEvent(createEvent('pointerup')); - expect(onLongPressChange).toHaveBeenCalledTimes(2); - expect(onLongPressChange).toHaveBeenCalledWith(false); - }); - - it('is called after delayed onPressEnd', () => { - const onLongPressChange = jest.fn(); - const ref = React.createRef(); - const Component = () => { - usePressListener({ - onLongPressChange, - }); - return ( -
- } - /> - ); - }; - ReactDOM.render(, container); - - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY); - expect(onLongPressChange).toHaveBeenCalledTimes(1); - expect(onLongPressChange).toHaveBeenCalledWith(true); - ref.current.dispatchEvent(createEvent('pointerup')); - jest.advanceTimersByTime(499); - expect(onLongPressChange).toHaveBeenCalledTimes(1); - jest.advanceTimersByTime(1); - expect(onLongPressChange).toHaveBeenCalledTimes(2); - expect(onLongPressChange).toHaveBeenCalledWith(false); - }); - }); - - describe('longPressShouldCancelPress', () => { - it('if true it cancels "onPress"', () => { - const onPress = jest.fn(); - const onPressChange = jest.fn(); - const ref = React.createRef(); - const Component = () => { - usePressListener({ - onLongPress: () => {}, - onPressChange, - onPress, - }); - return ( -
true} - enableLongPress={true} - /> - } - /> - ); - }; - ReactDOM.render(, container); - - // NOTE: onPressChange behavior should not be affected - ref.current.dispatchEvent(createEvent('pointerdown')); - expect(onPressChange).toHaveBeenCalledTimes(1); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY); - ref.current.dispatchEvent(createEvent('pointerup')); - expect(onPress).not.toBeCalled(); - expect(onPressChange).toHaveBeenCalledTimes(2); - }); - }); - describe('onPressMove', () => { it('is called after "pointermove"', () => { const onPressMove = jest.fn(); @@ -1621,7 +1369,6 @@ describe('Event responder: Press', () => { const Component = () => { usePressListener({ - onLongPress: createEventHandler('onLongPress'), onPress: createEventHandler('onPress'), onPressChange: createEventHandler('onPressChange'), onPressMove: createEventHandler('onPressMove'), @@ -1632,11 +1379,7 @@ describe('Event responder: Press', () => {
+ } /> ); @@ -2243,7 +1986,6 @@ describe('Event responder: Press', () => { const Component = () => { usePressListener({ - onLongPress: createEventHandler('onLongPress'), onPress: createEventHandler('onPress'), onPressChange: createEventHandler('onPressChange'), onPressMove: createEventHandler('onPressMove'), @@ -2254,11 +1996,7 @@ describe('Event responder: Press', () => {
+ } /> ); @@ -2378,8 +2116,6 @@ describe('Event responder: Press', () => { const Component = () => { usePressListener({ - onLongPress: createEventHandler('onLongPress'), - onLongPressChange: createEventHandler('onLongPressChange'), onPress: createEventHandler('onPress'), onPressChange: createEventHandler('onPressChange'), onPressMove: createEventHandler('onPressMove'), @@ -2390,11 +2126,7 @@ describe('Event responder: Press', () => {
+ } /> ); @@ -2443,12 +2175,9 @@ describe('Event responder: Press', () => { expect(events).toEqual([ 'onPressStart', 'onPressChange', - 'onLongPress', - 'onLongPressChange', 'onPress', 'onPressEnd', 'onPressChange', - 'onLongPressChange', ]); }); }); @@ -2557,40 +2286,6 @@ describe('Event responder: Press', () => { expect(fn).toHaveBeenCalledTimes(1); }); - it('for onLongPress', () => { - const ref = React.createRef(); - const fn = jest.fn(); - - const Inner = () => { - usePressListener({ - onLongPress: fn, - }); - return ( -
} - /> - ); - }; - - const Outer = () => { - usePressListener({ - onLongPress: fn, - }); - return ( -
}> - -
- ); - }; - ReactDOM.render(, container); - - ref.current.dispatchEvent(createEvent('pointerdown')); - jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY); - ref.current.dispatchEvent(createEvent('pointerup')); - expect(fn).toHaveBeenCalledTimes(1); - }); - it('for onPressStart/onPressEnd', () => { const ref = React.createRef(); const fn = jest.fn(); @@ -2863,22 +2558,14 @@ describe('Event responder: Press', () => { describe('responder cancellation', () => { it('ends on "pointercancel", "touchcancel", "scroll", and "dragstart"', () => { - const onLongPress = jest.fn(); const onPressEnd = jest.fn(); const ref = React.createRef(); const Component = () => { usePressListener({ - onLongPress, onPressEnd, }); - return ( - } - /> - ); + return } />; }; ReactDOM.render(, container); @@ -2890,8 +2577,6 @@ describe('Event responder: Press', () => { ); ref.current.dispatchEvent(createEvent('scroll')); expect(onPressEnd).toHaveBeenCalledTimes(1); - jest.runAllTimers(); - expect(onLongPress).not.toBeCalled(); onPressEnd.mockReset(); @@ -2903,9 +2588,6 @@ describe('Event responder: Press', () => { ); ref.current.dispatchEvent(createEvent('scroll')); expect(onPressEnd).toHaveBeenCalledTimes(0); - jest.runAllTimers(); - - onLongPress.mockReset(); // When pointer events are supported ref.current.dispatchEvent( @@ -2919,10 +2601,7 @@ describe('Event responder: Press', () => { }), ); expect(onPressEnd).toHaveBeenCalledTimes(1); - jest.runAllTimers(); - expect(onLongPress).not.toBeCalled(); - onLongPress.mockReset(); onPressEnd.mockReset(); // Touch fallback @@ -2937,18 +2616,13 @@ describe('Event responder: Press', () => { }), ); expect(onPressEnd).toHaveBeenCalledTimes(1); - jest.runAllTimers(); - expect(onLongPress).not.toBeCalled(); - onLongPress.mockReset(); onPressEnd.mockReset(); // Mouse fallback ref.current.dispatchEvent(createEvent('mousedown')); ref.current.dispatchEvent(createEvent('dragstart')); expect(onPressEnd).toHaveBeenCalledTimes(1); - jest.runAllTimers(); - expect(onLongPress).not.toBeCalled(); }); }); @@ -3059,15 +2733,9 @@ describe('Event responder: Press', () => { onPressStart: logEvent, onPressEnd: logEvent, onPressMove: logEvent, - onLongPress: logEvent, onPress: logEvent, }); - return ( -