Remove React Flare Keyboard responder (#19222)

This commit is contained in:
Dominic Gannaway
2020-07-01 15:43:16 +01:00
committed by GitHub
parent f918b0eb41
commit b2bac7311a
10 changed files with 0 additions and 1896 deletions

View File

@@ -1,10 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
export * from './src/dom/Keyboard';

View File

@@ -1,10 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
export * from './src/dom/Press';

View File

@@ -1,242 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {
ReactDOMResponderEvent,
ReactDOMResponderContext,
} from 'react-dom/src/shared/ReactDOMTypes';
import type {ReactEventResponderListener} from 'shared/ReactTypes';
import * as React from 'react';
import {DiscreteEvent} from 'shared/ReactTypes';
import {isVirtualClick} from './shared';
type KeyboardEventType =
| 'keyboard:click'
| 'keyboard:keydown'
| 'keyboard:keyup';
type KeyboardProps = {|
disabled?: boolean,
onClick?: (e: KeyboardEvent) => void,
onKeyDown?: (e: KeyboardEvent) => void,
onKeyUp?: (e: KeyboardEvent) => void,
|};
type KeyboardState = {|
isActive: boolean,
|};
export type KeyboardEvent = {|
altKey: boolean,
ctrlKey: boolean,
defaultPrevented: boolean,
isComposing?: boolean,
key?: string,
metaKey: boolean,
pointerType: 'keyboard',
shiftKey: boolean,
target: Element | Document,
type: KeyboardEventType,
timeStamp: number,
continuePropagation: () => void,
preventDefault: () => void,
|};
const targetEventTypes = ['click_active', 'keydown_active', 'keyup'];
/**
* Normalization of deprecated HTML5 `key` values
* @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
*/
const normalizeKey = {
Esc: 'Escape',
Spacebar: ' ',
Left: 'ArrowLeft',
Up: 'ArrowUp',
Right: 'ArrowRight',
Down: 'ArrowDown',
Del: 'Delete',
Win: 'OS',
Menu: 'ContextMenu',
Apps: 'ContextMenu',
Scroll: 'ScrollLock',
MozPrintableKey: 'Unidentified',
};
/**
* Translation from legacy `keyCode` to HTML5 `key`
* Only special keys supported, all others depend on keyboard layout or browser
* @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
*/
const translateToKey = {
'8': 'Backspace',
'9': 'Tab',
'12': 'Clear',
'13': 'Enter',
'16': 'Shift',
'17': 'Control',
'18': 'Alt',
'19': 'Pause',
'20': 'CapsLock',
'27': 'Escape',
'32': ' ',
'33': 'PageUp',
'34': 'PageDown',
'35': 'End',
'36': 'Home',
'37': 'ArrowLeft',
'38': 'ArrowUp',
'39': 'ArrowRight',
'40': 'ArrowDown',
'45': 'Insert',
'46': 'Delete',
'112': 'F1',
'113': 'F2',
'114': 'F3',
'115': 'F4',
'116': 'F5',
'117': 'F6',
'118': 'F7',
'119': 'F8',
'120': 'F9',
'121': 'F10',
'122': 'F11',
'123': 'F12',
'144': 'NumLock',
'145': 'ScrollLock',
'224': 'Meta',
};
function getEventKey(nativeEvent: Object): string {
const nativeKey = nativeEvent.key;
if (nativeKey) {
// Normalize inconsistent values reported by browsers due to
// implementations of a working draft specification.
// FireFox implements `key` but returns `MozPrintableKey` for all
// printable characters (normalized to `Unidentified`), ignore it.
const key = normalizeKey[nativeKey] || nativeKey;
if (key !== 'Unidentified') {
return key;
}
}
return translateToKey[nativeEvent.keyCode] || 'Unidentified';
}
function createKeyboardEvent(
event: ReactDOMResponderEvent,
context: ReactDOMResponderContext,
type: KeyboardEventType,
): KeyboardEvent {
const nativeEvent = (event: any).nativeEvent;
const {altKey, ctrlKey, metaKey, shiftKey} = nativeEvent;
let keyboardEvent = {
altKey,
ctrlKey,
defaultPrevented: nativeEvent.defaultPrevented === true,
metaKey,
pointerType: 'keyboard',
shiftKey,
target: event.target,
timeStamp: context.getTimeStamp(),
type,
// We don't use stopPropagation, as the default behavior
// is to not propagate. Plus, there might be confusion
// using stopPropagation as we don't actually stop
// native propagation from working, but instead only
// allow propagation to the others keyboard responders.
continuePropagation() {
context.continuePropagation();
},
preventDefault() {
keyboardEvent.defaultPrevented = true;
nativeEvent.preventDefault();
},
};
if (type !== 'keyboard:click') {
const key = getEventKey(nativeEvent);
const isComposing = nativeEvent.isComposing;
keyboardEvent = context.objectAssign({isComposing, key}, keyboardEvent);
}
return keyboardEvent;
}
function dispatchKeyboardEvent(
event: ReactDOMResponderEvent,
listener: KeyboardEvent => void,
context: ReactDOMResponderContext,
type: KeyboardEventType,
): void {
const syntheticEvent = createKeyboardEvent(event, context, type);
context.dispatchEvent(syntheticEvent, listener, DiscreteEvent);
}
const keyboardResponderImpl = {
targetEventTypes,
targetPortalPropagation: true,
getInitialState(): KeyboardState {
return {
isActive: false,
};
},
onEvent(
event: ReactDOMResponderEvent,
context: ReactDOMResponderContext,
props: KeyboardProps,
state: KeyboardState,
): void {
const {type} = event;
if (props.disabled) {
return;
}
if (type === 'keydown') {
state.isActive = true;
const onKeyDown = props.onKeyDown;
if (onKeyDown != null) {
dispatchKeyboardEvent(
event,
((onKeyDown: any): (e: KeyboardEvent) => void),
context,
'keyboard:keydown',
);
}
} else if (type === 'click' && isVirtualClick(event)) {
const onClick = props.onClick;
if (onClick != null) {
dispatchKeyboardEvent(event, onClick, context, 'keyboard:click');
}
} else if (type === 'keyup') {
state.isActive = false;
const onKeyUp = props.onKeyUp;
if (onKeyUp != null) {
dispatchKeyboardEvent(
event,
((onKeyUp: any): (e: KeyboardEvent) => void),
context,
'keyboard:keyup',
);
}
}
},
};
// $FlowFixMe Can't add generic types without causing a parsing/syntax errors
export const KeyboardResponder = React.DEPRECATED_createResponder(
'Keyboard',
keyboardResponderImpl,
);
export function useKeyboard(
props: KeyboardProps,
): ?ReactEventResponderListener<any, any> {
return React.DEPRECATED_useResponder(KeyboardResponder, props);
}

View File

@@ -1,227 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {PointerType} from 'react-dom/src/shared/ReactDOMTypes';
import * as React from 'react';
import {useTap} from 'react-interactions/events/tap';
import {useKeyboard} from 'react-interactions/events/keyboard';
const emptyObject = {};
type PressProps = $ReadOnly<{|
disabled?: boolean,
preventDefault?: boolean,
onPress?: (e: PressEvent) => void,
onPressChange?: boolean => void,
onPressEnd?: (e: PressEvent) => void,
onPressMove?: (e: PressEvent) => void,
onPressStart?: (e: PressEvent) => void,
|}>;
type PressEventType =
| 'pressstart'
| 'presschange'
| 'pressmove'
| 'pressend'
| 'press';
type PressEvent = {|
altKey: boolean,
buttons: null | 1 | 4,
ctrlKey: boolean,
defaultPrevented: boolean,
key: null | string,
metaKey: boolean,
pageX: number,
pageY: number,
pointerType: PointerType,
shiftKey: boolean,
target: null | Element,
timeStamp: number,
type: PressEventType,
x: number,
y: number,
preventDefault: () => void,
stopPropagation: () => void,
|};
function createGestureState(e: any, type: PressEventType): PressEvent {
return {
altKey: e.altKey,
buttons: e.type === 'tap:auxiliary' ? 4 : 1,
ctrlKey: e.ctrlKey,
defaultPrevented: e.defaultPrevented,
key: e.key,
metaKey: e.metaKey,
pageX: e.pageX,
pageY: e.pageX,
pointerType: e.pointerType,
shiftKey: e.shiftKey,
target: e.target,
timeStamp: e.timeStamp,
type,
x: e.x,
y: e.y,
preventDefault() {
// NO-OP, we should remove this in the future
if (__DEV__) {
console.error(
'preventDefault is not available on event objects created from event responder modules (React Flare). ' +
'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.preventDefault() }`',
);
}
},
stopPropagation() {
// NO-OP, we should remove this in the future
if (__DEV__) {
console.error(
'stopPropagation is not available on event objects created from event responder modules (React Flare). ' +
'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.stopPropagation() }`',
);
}
},
};
}
function isValidKey(e): boolean {
const {key, target} = e;
const {tagName, isContentEditable} = (target: any);
return (
(key === 'Enter' || key === ' ' || key === 'Spacebar') &&
tagName !== 'INPUT' &&
tagName !== 'TEXTAREA' &&
isContentEditable !== true
);
}
function handlePreventDefault(preventDefault: ?boolean, e: any): void {
const key = e.key;
if (
preventDefault !== false &&
(key === ' ' || key === 'Enter' || key === 'Spacebar')
) {
e.preventDefault();
}
}
/**
* The lack of built-in composition for gesture responders means we have to
* selectively ignore callbacks from useKeyboard or useTap if the other is
* active.
*/
export function usePress(props: PressProps) {
const safeProps = props || emptyObject;
const {
disabled,
preventDefault,
onPress,
onPressChange,
onPressEnd,
onPressMove,
onPressStart,
} = safeProps;
const activeResponder = React.useRef(null);
const tap = useTap({
disabled: disabled || activeResponder.current === 'keyboard',
preventDefault,
onAuxiliaryTap(e) {
if (onPressStart != null) {
onPressStart(createGestureState(e, 'pressstart'));
}
if (onPressEnd != null) {
onPressEnd(createGestureState(e, 'pressend'));
}
// Here we rely on Tap only calling 'onAuxiliaryTap' with modifiers when
// the primary button is pressed
if (onPress != null && (e.metaKey || e.shiftKey)) {
onPress(createGestureState(e, 'press'));
}
},
onTapStart(e) {
if (activeResponder.current == null) {
activeResponder.current = 'tap';
if (onPressStart != null) {
onPressStart(createGestureState(e, 'pressstart'));
}
}
},
onTapChange: onPressChange,
onTapUpdate(e) {
if (activeResponder.current === 'tap') {
if (onPressMove != null) {
onPressMove(createGestureState(e, 'pressmove'));
}
}
},
onTapEnd(e) {
if (activeResponder.current === 'tap') {
if (onPressEnd != null) {
onPressEnd(createGestureState(e, 'pressend'));
}
if (onPress != null) {
onPress(createGestureState(e, 'press'));
}
activeResponder.current = null;
}
},
onTapCancel(e) {
if (activeResponder.current === 'tap') {
if (onPressEnd != null) {
onPressEnd(createGestureState(e, 'pressend'));
}
activeResponder.current = null;
}
},
});
const keyboard = useKeyboard({
disabled: disabled || activeResponder.current === 'tap',
onClick(e) {
if (preventDefault !== false) {
e.preventDefault();
}
if (activeResponder.current == null && onPress != null) {
onPress(createGestureState(e, 'press'));
}
},
onKeyDown(e) {
if (activeResponder.current == null && isValidKey(e)) {
handlePreventDefault(preventDefault, e);
activeResponder.current = 'keyboard';
if (onPressStart != null) {
onPressStart(createGestureState(e, 'pressstart'));
}
if (onPressChange != null) {
onPressChange(true);
}
}
},
onKeyUp(e) {
if (activeResponder.current === 'keyboard' && isValidKey(e)) {
handlePreventDefault(preventDefault, e);
if (onPressChange != null) {
onPressChange(false);
}
if (onPressEnd != null) {
onPressEnd(createGestureState(e, 'pressend'));
}
if (onPress != null) {
onPress(createGestureState(e, 'press'));
}
activeResponder.current = null;
}
},
});
return [tap, keyboard];
}

View File

@@ -1,506 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
let React;
let ReactFeatureFlags;
let ReactDOM;
let useKeyboard;
import {createEventTarget} from 'dom-event-testing-library';
function initializeModules(hasPointerEvents) {
jest.resetModules();
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.enableDeprecatedFlareAPI = true;
React = require('react');
ReactDOM = require('react-dom');
// TODO: This import throws outside of experimental mode. Figure out better
// strategy for gated imports.
if (__EXPERIMENTAL__) {
useKeyboard = require('react-interactions/events/keyboard').useKeyboard;
}
}
describe('Keyboard responder', () => {
let container;
beforeEach(() => {
initializeModules();
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
ReactDOM.render(null, container);
document.body.removeChild(container);
container = null;
});
function renderPropagationTest(propagates) {
const onClickInner = jest.fn(e => propagates && e.continuePropagation());
const onKeyDownInner = jest.fn(e => propagates && e.continuePropagation());
const onKeyUpInner = jest.fn(e => propagates && e.continuePropagation());
const onClickOuter = jest.fn();
const onKeyDownOuter = jest.fn();
const onKeyUpOuter = jest.fn();
const ref = React.createRef();
const Component = () => {
const listenerInner = useKeyboard({
onClick: onClickInner,
onKeyDown: onKeyDownInner,
onKeyUp: onKeyUpInner,
});
const listenerOuter = useKeyboard({
onClick: onClickOuter,
onKeyDown: onKeyDownOuter,
onKeyUp: onKeyUpOuter,
});
return (
<div DEPRECATED_flareListeners={listenerOuter}>
<div ref={ref} DEPRECATED_flareListeners={listenerInner} />
</div>
);
};
ReactDOM.render(<Component />, container);
return {
onClickInner,
onKeyDownInner,
onKeyUpInner,
onClickOuter,
onKeyDownOuter,
onKeyUpOuter,
ref,
};
}
// @gate experimental
test('propagates key event when a continuePropagation() is used', () => {
const {
onClickInner,
onKeyDownInner,
onKeyUpInner,
onClickOuter,
onKeyDownOuter,
onKeyUpOuter,
ref,
} = renderPropagationTest(true);
const target = createEventTarget(ref.current);
target.keydown();
expect(onKeyDownInner).toBeCalled();
expect(onKeyDownOuter).toBeCalled();
target.keyup();
expect(onKeyUpInner).toBeCalled();
expect(onKeyUpOuter).toBeCalled();
target.virtualclick();
expect(onClickInner).toBeCalled();
expect(onClickOuter).toBeCalled();
});
// @gate experimental
test('does not propagate key event by default', () => {
const {
onClickInner,
onKeyDownInner,
onKeyUpInner,
onClickOuter,
onKeyDownOuter,
onKeyUpOuter,
ref,
} = renderPropagationTest(false);
const target = createEventTarget(ref.current);
target.keydown();
expect(onKeyDownInner).toBeCalled();
expect(onKeyDownOuter).not.toBeCalled();
target.keyup();
expect(onKeyUpInner).toBeCalled();
expect(onKeyUpOuter).not.toBeCalled();
target.virtualclick();
expect(onClickInner).toBeCalled();
expect(onClickOuter).not.toBeCalled();
});
describe('disabled', () => {
let onKeyDown, onKeyUp, ref;
const componentInit = () => {
onKeyDown = jest.fn();
onKeyUp = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = useKeyboard({disabled: true, onKeyDown, onKeyUp});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
};
// @gate experimental
test('does not call callbacks', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown();
target.keyup();
expect(onKeyDown).not.toBeCalled();
expect(onKeyUp).not.toBeCalled();
});
});
describe('onClick', () => {
let onClick, ref;
const componentInit = () => {
onClick = jest.fn(e => {
e.preventDefault();
});
ref = React.createRef();
const Component = () => {
const listener = useKeyboard({onClick});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
};
// e.g, "Enter" on link
// @gate experimental
test('click is between key events', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keyup({key: 'Enter'});
target.virtualclick();
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledWith(
expect.objectContaining({
altKey: false,
ctrlKey: false,
defaultPrevented: true,
metaKey: false,
pointerType: 'keyboard',
shiftKey: false,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:click',
}),
);
});
// e.g., "Spacebar" on button
// @gate experimental
test('click is after key events', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keyup({key: 'Enter'});
target.virtualclick();
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledWith(
expect.objectContaining({
altKey: false,
ctrlKey: false,
defaultPrevented: true,
metaKey: false,
pointerType: 'keyboard',
shiftKey: false,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:click',
}),
);
});
// e.g, generated by a screen-reader
// @gate experimental
test('click is orphan', () => {
componentInit();
const target = createEventTarget(ref.current);
target.virtualclick();
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledWith(
expect.objectContaining({
altKey: false,
ctrlKey: false,
defaultPrevented: true,
metaKey: false,
pointerType: 'keyboard',
shiftKey: false,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:click',
}),
);
});
});
describe('onKeyDown', () => {
let onKeyDown, ref;
const componentInit = () => {
onKeyDown = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = useKeyboard({onKeyDown});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
};
// @gate experimental
test('key down', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Q'});
expect(onKeyDown).toHaveBeenCalledTimes(1);
expect(onKeyDown).toHaveBeenCalledWith(
expect.objectContaining({
altKey: false,
ctrlKey: false,
defaultPrevented: false,
isComposing: false,
key: 'Q',
metaKey: false,
pointerType: 'keyboard',
shiftKey: false,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:keydown',
}),
);
});
// @gate experimental
test('modified key down', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({
key: 'Q',
altKey: true,
ctrlKey: true,
shiftKey: true,
metaKey: true,
});
expect(onKeyDown).toHaveBeenCalledWith(
expect.objectContaining({
altKey: true,
ctrlKey: true,
defaultPrevented: false,
isComposing: false,
key: 'Q',
metaKey: true,
pointerType: 'keyboard',
shiftKey: true,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:keydown',
}),
);
});
});
describe('onKeyUp', () => {
let onKeyUp, ref;
const componentInit = () => {
onKeyUp = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = useKeyboard({onKeyUp});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
};
// @gate experimental
test('key up', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Q'});
target.keyup({key: 'Q'});
expect(onKeyUp).toHaveBeenCalledTimes(1);
expect(onKeyUp).toHaveBeenCalledWith(
expect.objectContaining({
altKey: false,
ctrlKey: false,
defaultPrevented: false,
isComposing: false,
key: 'Q',
metaKey: false,
pointerType: 'keyboard',
shiftKey: false,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:keyup',
}),
);
});
// @gate experimental
test('modified key up', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Q'});
target.keyup({
key: 'Q',
altKey: true,
ctrlKey: true,
shiftKey: true,
metaKey: true,
});
expect(onKeyUp).toHaveBeenCalledWith(
expect.objectContaining({
altKey: true,
ctrlKey: true,
defaultPrevented: false,
isComposing: false,
key: 'Q',
metaKey: true,
pointerType: 'keyboard',
shiftKey: true,
target: target.node,
timeStamp: expect.any(Number),
type: 'keyboard:keyup',
}),
);
});
});
describe('preventDefault for onClick', () => {
function render(props) {
const ref = React.createRef();
const Component = () => {
const listener = useKeyboard(props);
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
return ref;
}
// @gate experimental
test('does not prevent native click by default', () => {
const onClick = jest.fn();
const preventDefault = jest.fn();
const ref = render({onClick});
const target = createEventTarget(ref.current);
target.virtualclick({preventDefault});
expect(preventDefault).not.toBeCalled();
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledWith(
expect.objectContaining({
defaultPrevented: false,
}),
);
});
// @gate experimental
test('prevents native behaviour with preventDefault', () => {
const onClick = jest.fn(e => e.preventDefault());
const preventDefault = jest.fn();
const ref = render({onClick});
const target = createEventTarget(ref.current);
target.virtualclick({preventDefault});
expect(preventDefault).toBeCalled();
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledWith(
expect.objectContaining({
defaultPrevented: true,
}),
);
});
});
describe('preventDefault for onKeyDown', () => {
function render(props) {
const ref = React.createRef();
const Component = () => {
const listener = useKeyboard(props);
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
return ref;
}
// @gate experimental
test('key config matches', () => {
const onKeyDown = jest.fn(e => {
if (e.key === 'Tab') {
e.preventDefault();
}
});
const preventDefault = jest.fn();
const preventDefaultClick = jest.fn();
const ref = render({onKeyDown});
const target = createEventTarget(ref.current);
target.keydown({key: 'Tab', preventDefault});
target.virtualclick({preventDefault: preventDefaultClick});
expect(preventDefault).toBeCalled();
expect(onKeyDown).toHaveBeenCalledTimes(1);
expect(onKeyDown).toHaveBeenCalledWith(
expect.objectContaining({
defaultPrevented: true,
key: 'Tab',
type: 'keyboard:keydown',
}),
);
});
// @gate experimental
test('key config matches (modifier keys)', () => {
const onKeyDown = jest.fn(e => {
if (e.key === 'Tab' && e.shiftKey) {
e.preventDefault();
}
});
const preventDefault = jest.fn();
const ref = render({onKeyDown});
const target = createEventTarget(ref.current);
target.keydown({key: 'Tab', preventDefault, shiftKey: true});
expect(preventDefault).toBeCalled();
expect(onKeyDown).toHaveBeenCalledTimes(1);
expect(onKeyDown).toHaveBeenCalledWith(
expect.objectContaining({
defaultPrevented: true,
key: 'Tab',
shiftKey: true,
type: 'keyboard:keydown',
}),
);
});
// @gate experimental
test('key config does not match (modifier keys)', () => {
const onKeyDown = jest.fn(e => {
if (e.key === 'Tab' && e.shiftKey) {
e.preventDefault();
}
});
const preventDefault = jest.fn();
const ref = render({onKeyDown});
const target = createEventTarget(ref.current);
target.keydown({key: 'Tab', preventDefault, shiftKey: false});
expect(preventDefault).not.toBeCalled();
expect(onKeyDown).toHaveBeenCalledTimes(1);
expect(onKeyDown).toHaveBeenCalledWith(
expect.objectContaining({
defaultPrevented: false,
key: 'Tab',
shiftKey: false,
type: 'keyboard:keydown',
}),
);
});
});
});

View File

@@ -1,832 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
import {
buttonType,
buttonsType,
createEventTarget,
describeWithPointerEvent,
resetActivePointers,
setPointerEvent,
} from 'dom-event-testing-library';
let React;
let ReactFeatureFlags;
let ReactDOM;
let usePress;
function initializeModules(hasPointerEvents) {
jest.resetModules();
setPointerEvent(hasPointerEvents);
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.enableDeprecatedFlareAPI = true;
React = require('react');
ReactDOM = require('react-dom');
// TODO: This import throws outside of experimental mode. Figure out better
// strategy for gated imports.
if (__EXPERIMENTAL__) {
usePress = require('react-interactions/events/press').usePress;
}
}
describeWithPointerEvent('Press responder', hasPointerEvents => {
let container;
beforeEach(() => {
initializeModules(hasPointerEvents);
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
ReactDOM.render(null, container);
document.body.removeChild(container);
container = null;
resetActivePointers();
});
describe('disabled', () => {
let onPressStart, onPressChange, onPressMove, onPressEnd, onPress, ref;
const componentInit = () => {
onPressStart = jest.fn();
onPressChange = jest.fn();
onPressMove = jest.fn();
onPressEnd = jest.fn();
onPress = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = usePress({
disabled: true,
onPressStart,
onPressChange,
onPressMove,
onPressEnd,
onPress,
});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
};
// @gate experimental
test('does not call callbacks for pointers', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown();
target.pointerup();
expect(onPressStart).not.toBeCalled();
expect(onPressChange).not.toBeCalled();
expect(onPressMove).not.toBeCalled();
expect(onPressEnd).not.toBeCalled();
expect(onPress).not.toBeCalled();
});
// @gate experimental
test('does not call callbacks for keyboard', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keyup({key: 'Enter'});
expect(onPressStart).not.toBeCalled();
expect(onPressChange).not.toBeCalled();
expect(onPressMove).not.toBeCalled();
expect(onPressEnd).not.toBeCalled();
expect(onPress).not.toBeCalled();
});
});
describe('onPressStart', () => {
let onPressStart, ref;
const componentInit = () => {
onPressStart = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = usePress({
onPressStart,
});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
document.elementFromPoint = () => ref.current;
};
// @gate experimental
it('is called after pointer down: mouse', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'mouse'});
expect(onPressStart).toHaveBeenCalledTimes(1);
expect(onPressStart).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'mouse', type: 'pressstart'}),
);
});
// @gate experimental
it('is called after pointer down: mouse', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'touch'});
expect(onPressStart).toHaveBeenCalledTimes(1);
expect(onPressStart).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'touch', type: 'pressstart'}),
);
});
// @gate experimental
it('is called after middle-button pointer down', () => {
componentInit();
const target = createEventTarget(ref.current);
const pointerType = 'mouse';
target.pointerdown({
button: buttonType.auxiliary,
buttons: buttonsType.auxiliary,
pointerType,
});
target.pointerup({pointerType});
expect(onPressStart).toHaveBeenCalledTimes(1);
expect(onPressStart).toHaveBeenCalledWith(
expect.objectContaining({
buttons: buttonsType.auxiliary,
pointerType: 'mouse',
type: 'pressstart',
}),
);
});
// @gate experimental
it('is called after virtual middle-button pointer down', () => {
componentInit();
const target = createEventTarget(ref.current);
const pointerType = 'mouse';
target.pointerdown({
button: buttonType.auxiliary,
buttons: 0,
pointerType,
});
target.pointerup({pointerType});
expect(onPressStart).toHaveBeenCalledTimes(1);
expect(onPressStart).toHaveBeenCalledWith(
expect.objectContaining({
buttons: buttonsType.auxiliary,
pointerType: 'mouse',
type: 'pressstart',
}),
);
});
// @gate experimental
it('ignores any events not caused by primary/middle-click or touch/pen contact', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({buttons: buttonsType.secondary});
target.pointerup({buttons: buttonsType.secondary});
target.pointerdown({buttons: buttonsType.eraser});
target.pointerup({buttons: buttonsType.eraser});
expect(onPressStart).toHaveBeenCalledTimes(0);
});
// @gate experimental
it('is called once after "keydown" events for Enter', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keydown({key: 'Enter'});
target.keydown({key: 'Enter'});
expect(onPressStart).toHaveBeenCalledTimes(1);
expect(onPressStart).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'keyboard', type: 'pressstart'}),
);
});
// @gate experimental
it('is called once after "keydown" events for Spacebar', () => {
componentInit();
const target = createEventTarget(ref.current);
const preventDefault = jest.fn();
target.keydown({key: ' ', preventDefault});
expect(preventDefault).toBeCalled();
target.keydown({key: ' ', preventDefault});
expect(onPressStart).toHaveBeenCalledTimes(1);
expect(onPressStart).toHaveBeenCalledWith(
expect.objectContaining({
pointerType: 'keyboard',
type: 'pressstart',
}),
);
});
// @gate experimental
it('is not called after "keydown" for other keys', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'a'});
expect(onPressStart).not.toBeCalled();
});
});
describe('onPressEnd', () => {
let onPressEnd, ref;
const componentInit = () => {
onPressEnd = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = usePress({
onPressEnd,
});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
document.elementFromPoint = () => ref.current;
};
// @gate experimental
it('is called after pointer up: mouse', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'mouse'});
target.pointerup({pointerType: 'mouse'});
expect(onPressEnd).toHaveBeenCalledTimes(1);
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'mouse', type: 'pressend'}),
);
});
// @gate experimental
it('is called after pointer up: touch', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'touch'});
target.pointerup({pointerType: 'touch'});
expect(onPressEnd).toHaveBeenCalledTimes(1);
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'touch', type: 'pressend'}),
);
});
// @gate experimental
it('is called after middle-button pointer up', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({
button: buttonType.auxiliary,
buttons: buttonsType.auxiliary,
pointerType: 'mouse',
});
target.pointerup({pointerType: 'mouse'});
expect(onPressEnd).toHaveBeenCalledTimes(1);
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({
buttons: buttonsType.auxiliary,
pointerType: 'mouse',
type: 'pressend',
}),
);
});
// @gate experimental
it('is called after virtual middle-button pointer up', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({
button: buttonType.auxiliary,
buttons: 0,
pointerType: 'mouse',
});
target.pointerup({pointerType: 'mouse'});
expect(onPressEnd).toHaveBeenCalledTimes(1);
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({
buttons: buttonsType.auxiliary,
pointerType: 'mouse',
type: 'pressend',
}),
);
});
// @gate experimental
it('is called after "keyup" event for Enter', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
// click occurs before keyup
target.virtualclick();
target.keyup({key: 'Enter'});
expect(onPressEnd).toHaveBeenCalledTimes(1);
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}),
);
});
// @gate experimental
it('is called after "keyup" event for Spacebar', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: ' '});
target.keyup({key: ' '});
expect(onPressEnd).toHaveBeenCalledTimes(1);
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}),
);
});
// @gate experimental
it('is not called after "keyup" event for other keys', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keyup({key: 'a'});
expect(onPressEnd).not.toBeCalled();
});
// @gate experimental
it('is called with keyboard modifiers', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keyup({
key: 'Enter',
metaKey: true,
ctrlKey: true,
altKey: true,
shiftKey: true,
});
expect(onPressEnd).toHaveBeenCalledWith(
expect.objectContaining({
pointerType: 'keyboard',
type: 'pressend',
metaKey: true,
ctrlKey: true,
altKey: true,
shiftKey: true,
}),
);
});
});
describe('onPressChange', () => {
let onPressChange, ref;
const componentInit = () => {
onPressChange = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = usePress({
onPressChange,
});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
document.elementFromPoint = () => ref.current;
};
// @gate experimental
it('is called after pointer down and up: %s', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'mouse'});
expect(onPressChange).toHaveBeenCalledTimes(1);
expect(onPressChange).toHaveBeenCalledWith(true);
target.pointerup({pointerType: 'mouse'});
expect(onPressChange).toHaveBeenCalledTimes(2);
expect(onPressChange).toHaveBeenCalledWith(false);
});
// @gate experimental
it('is called after pointer down and up: touch', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'touch'});
expect(onPressChange).toHaveBeenCalledTimes(1);
expect(onPressChange).toHaveBeenCalledWith(true);
target.pointerup({pointerType: 'touch'});
expect(onPressChange).toHaveBeenCalledTimes(2);
expect(onPressChange).toHaveBeenCalledWith(false);
});
// @gate experimental
it('is called after valid "keydown" and "keyup" events', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
expect(onPressChange).toHaveBeenCalledTimes(1);
expect(onPressChange).toHaveBeenCalledWith(true);
target.keyup({key: 'Enter'});
expect(onPressChange).toHaveBeenCalledTimes(2);
expect(onPressChange).toHaveBeenCalledWith(false);
});
});
describe('onPress', () => {
let onPress, ref;
const componentInit = () => {
onPress = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = usePress({
onPress,
});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
ref.current.getBoundingClientRect = () => ({
top: 0,
left: 0,
bottom: 100,
right: 100,
});
document.elementFromPoint = () => ref.current;
};
// @gate experimental
it('is called after pointer up: %s', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'mouse'});
target.pointerup({pointerType: 'mouse', x: 10, y: 10});
expect(onPress).toHaveBeenCalledTimes(1);
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'mouse', type: 'press'}),
);
});
// @gate experimental
it('is called after pointer up: %s', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({pointerType: 'touch'});
target.pointerup({pointerType: 'touch', x: 10, y: 10});
expect(onPress).toHaveBeenCalledTimes(1);
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'touch', type: 'press'}),
);
});
// @gate experimental
it('is not called after middle-button press', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({
button: buttonType.auxiliary,
buttons: buttonsType.auxiliary,
pointerType: 'mouse',
});
target.pointerup({pointerType: 'mouse'});
expect(onPress).not.toHaveBeenCalled();
});
// @gate experimental
it('is not called after virtual middle-button press', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({
button: buttonType.auxiliary,
buttons: 0,
pointerType: 'mouse',
});
target.pointerup({pointerType: 'mouse'});
expect(onPress).not.toHaveBeenCalled();
});
// @gate experimental
it('is called after valid "keyup" event', () => {
componentInit();
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.keyup({key: 'Enter'});
expect(onPress).toHaveBeenCalledTimes(1);
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'keyboard', type: 'press'}),
);
});
// @gate experimental
it('is not called after invalid "keyup" event', () => {
componentInit();
const inputRef = React.createRef();
const Component = () => {
const listener = usePress({onPress});
return <input ref={inputRef} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(inputRef.current);
target.keydown({key: 'Enter'});
target.keyup({key: 'Enter'});
target.keydown({key: ' '});
target.keyup({key: ' '});
expect(onPress).not.toBeCalled();
});
// @gate experimental
it('is called with modifier keys', () => {
componentInit();
const target = createEventTarget(ref.current);
target.pointerdown({metaKey: true, pointerType: 'mouse'});
target.pointerup({metaKey: true, pointerType: 'mouse'});
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({
pointerType: 'mouse',
type: 'press',
metaKey: true,
}),
);
});
// @gate experimental
it('is called once after virtual screen reader "click" event', () => {
componentInit();
const target = createEventTarget(ref.current);
const preventDefault = jest.fn();
target.virtualclick({preventDefault});
expect(preventDefault).toBeCalled();
expect(onPress).toHaveBeenCalledTimes(1);
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({
pointerType: 'keyboard',
type: 'press',
}),
);
});
});
describe('onPressMove', () => {
let onPressMove, ref;
const componentInit = () => {
onPressMove = jest.fn();
ref = React.createRef();
const Component = () => {
const listener = usePress({
onPressMove,
});
return <div ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
ref.current.getBoundingClientRect = () => ({
top: 0,
left: 0,
bottom: 100,
right: 100,
});
document.elementFromPoint = () => ref.current;
};
// @gate experimental
it('is called after pointer move: mouse', () => {
componentInit();
const node = ref.current;
const target = createEventTarget(node);
target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
target.pointerdown({pointerType: 'mouse'});
target.pointermove({pointerType: 'mouse', x: 10, y: 10});
target.pointermove({pointerType: 'mouse', x: 20, y: 20});
expect(onPressMove).toHaveBeenCalledTimes(2);
expect(onPressMove).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'mouse', type: 'pressmove'}),
);
});
// @gate experimental
it('is called after pointer move: touch', () => {
componentInit();
const node = ref.current;
const target = createEventTarget(node);
target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
target.pointerdown({pointerType: 'touch'});
target.pointermove({pointerType: 'touch', x: 10, y: 10});
target.pointermove({pointerType: 'touch', x: 20, y: 20});
expect(onPressMove).toHaveBeenCalledTimes(2);
expect(onPressMove).toHaveBeenCalledWith(
expect.objectContaining({pointerType: 'touch', type: 'pressmove'}),
);
});
// @gate experimental
it('is not called if pointer move occurs during keyboard press', () => {
componentInit();
const target = createEventTarget(ref.current);
target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
target.keydown({key: 'Enter'});
target.pointermove({
buttons: buttonsType.none,
pointerType: 'mouse',
x: 10,
y: 10,
});
expect(onPressMove).not.toBeCalled();
});
});
describe('link components', () => {
// @gate experimental
it('prevents native behavior by default', () => {
const onPress = jest.fn();
const preventDefault = jest.fn();
const ref = React.createRef();
const Component = () => {
const listener = usePress({onPress});
return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(ref.current);
target.pointerdown();
target.pointerup({preventDefault});
expect(preventDefault).toBeCalled();
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({defaultPrevented: true}),
);
});
// @gate experimental
it('prevents native behaviour for keyboard events by default', () => {
const onPress = jest.fn();
const preventDefaultClick = jest.fn();
const preventDefaultKeyDown = jest.fn();
const ref = React.createRef();
const Component = () => {
const listener = usePress({onPress});
return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter', preventDefault: preventDefaultKeyDown});
target.virtualclick({preventDefault: preventDefaultClick});
target.keyup({key: 'Enter'});
expect(preventDefaultKeyDown).toBeCalled();
expect(preventDefaultClick).toBeCalled();
expect(onPress).toHaveBeenCalledTimes(1);
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({defaultPrevented: true}),
);
});
// @gate experimental
it('deeply prevents native behaviour by default', () => {
const onPress = jest.fn();
const preventDefault = jest.fn();
const buttonRef = React.createRef();
const Component = () => {
const listener = usePress({onPress});
return (
<a href="#">
<button ref={buttonRef} DEPRECATED_flareListeners={listener} />
</a>
);
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(buttonRef.current);
target.pointerdown();
target.pointerup({preventDefault});
expect(preventDefault).toBeCalled();
});
// @gate experimental
it('prevents native behaviour by default with nested elements', () => {
const onPress = jest.fn();
const preventDefault = jest.fn();
const ref = React.createRef();
const Component = () => {
const listener = usePress({onPress});
return (
<a href="#" DEPRECATED_flareListeners={listener}>
<div ref={ref} />
</a>
);
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(ref.current);
target.pointerdown();
target.pointerup({preventDefault});
expect(preventDefault).toBeCalled();
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({defaultPrevented: true}),
);
});
// @gate experimental
it('uses native behaviour for interactions with modifier keys', () => {
const onPress = jest.fn();
const preventDefault = jest.fn();
const ref = React.createRef();
const Component = () => {
const listener = usePress({onPress});
return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
['metaKey', 'ctrlKey', 'shiftKey'].forEach(modifierKey => {
const target = createEventTarget(ref.current);
target.pointerdown({[modifierKey]: true});
target.pointerup({[modifierKey]: true, preventDefault});
expect(preventDefault).not.toBeCalled();
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({defaultPrevented: false}),
);
});
});
// @gate experimental
it('uses native behaviour for pointer events if preventDefault is false', () => {
const onPress = jest.fn();
const preventDefault = jest.fn();
const ref = React.createRef();
const Component = () => {
const listener = usePress({onPress, preventDefault: false});
return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(ref.current);
target.pointerdown();
target.pointerup({preventDefault});
expect(preventDefault).not.toBeCalled();
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({defaultPrevented: false}),
);
});
// @gate experimental
it('uses native behaviour for keyboard events if preventDefault is false', () => {
const onPress = jest.fn();
const preventDefault = jest.fn();
const ref = React.createRef();
const Component = () => {
const listener = usePress({onPress, preventDefault: false});
return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(ref.current);
target.keydown({key: 'Enter'});
target.virtualclick({preventDefault});
target.keyup({key: 'Enter'});
expect(preventDefault).not.toBeCalled();
expect(onPress).toHaveBeenCalledTimes(1);
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({defaultPrevented: false}),
);
});
});
// @gate experimental
it('should not trigger an invariant in addRootEventTypes()', () => {
const ref = React.createRef();
const Component = () => {
const listener = usePress();
return <button ref={ref} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(ref.current);
target.pointerdown();
target.pointermove();
target.pointerup();
target.pointerdown();
});
// @gate experimental
it('when blur occurs on a pressed target, we should disengage press', () => {
const onPress = jest.fn();
const onPressStart = jest.fn();
const onPressEnd = jest.fn();
const buttonRef = React.createRef();
const Component = () => {
const listener = usePress({onPress, onPressStart, onPressEnd});
return <button ref={buttonRef} DEPRECATED_flareListeners={listener} />;
};
ReactDOM.render(<Component />, container);
const target = createEventTarget(buttonRef.current);
target.pointerdown();
expect(onPressStart).toBeCalled();
target.blur();
expect(onPressEnd).toBeCalled();
target.pointerup();
expect(onPress).not.toBeCalled();
});
});

View File

@@ -1,7 +0,0 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-interactions-events/keyboard.production.min.js');
} else {
module.exports = require('./cjs/react-interactions-events/keyboard.development.js');
}

View File

@@ -9,8 +9,6 @@
'use strict';
import {createEventTarget} from 'dom-event-testing-library';
let React;
let ReactFeatureFlags;
let ReactDOMServer;
@@ -240,49 +238,6 @@ describe('ReactScope', () => {
expect(nodes).toEqual([divRef.current, spanRef.current, aRef.current]);
});
// @gate experimental
it('event responders can be attached to scopes', () => {
let onKeyDown = jest.fn();
const TestScope = React.unstable_createScope();
const ref = React.createRef();
const useKeyboard = require('react-interactions/events/keyboard')
.useKeyboard;
let Component = () => {
const listener = useKeyboard({
onKeyDown,
});
return (
<TestScope DEPRECATED_flareListeners={listener}>
<div ref={ref} />
</TestScope>
);
};
ReactDOM.render(<Component />, container);
let target = createEventTarget(ref.current);
target.keydown({key: 'Q'});
expect(onKeyDown).toHaveBeenCalledTimes(1);
onKeyDown = jest.fn();
Component = () => {
const listener = useKeyboard({
onKeyDown,
});
return (
<div>
<TestScope DEPRECATED_flareListeners={listener}>
<div ref={ref} />
</TestScope>
</div>
);
};
ReactDOM.render(<Component />, container);
target = createEventTarget(ref.current);
target.keydown({key: 'Q'});
expect(onKeyDown).toHaveBeenCalledTimes(1);
});
// @gate experimental
it('getChildContextValues() works as intended', () => {
const TestContext = React.createContext();

View File

@@ -748,21 +748,6 @@ const bundles = [
externals: ['react'],
},
{
bundleTypes: [
UMD_DEV,
UMD_PROD,
NODE_DEV,
NODE_PROD,
FB_WWW_DEV,
FB_WWW_PROD,
],
moduleType: NON_FIBER_RENDERER,
entry: 'react-interactions/events/keyboard',
global: 'ReactEventsKeyboard',
externals: ['react'],
},
{
bundleTypes: [
UMD_DEV,
@@ -781,7 +766,6 @@ const bundles = [
const fbBundleExternalsMap = {
'react-interactions/events/focus': 'ReactEventsFocus',
'react-interactions/events/keyboard': 'ReactEventsKeyboard',
'react-interactions/events/tap': 'ReactEventsTap',
};

View File

@@ -24,7 +24,6 @@ const knownGlobals = Object.freeze({
react: 'React',
'react-dom': 'ReactDOM',
'react-dom/server': 'ReactDOMServer',
'react-interactions/events/keyboard': 'ReactEventsKeyboard',
'react-interactions/events/tap': 'ReactEventsTap',
scheduler: 'Scheduler',
'scheduler/tracing': 'SchedulerTracing',