Remove React Flare Keyboard responder (#19222)
Dominic Gannaway committed
Jul 1, 2020 at 15:43 UTC
b2bac7311a5279f2e64fd5c38d6e78d2bf90e893
10 files changed
-1896
packages/react-interactions/events/keyboard.js
deleted
-10
@@ -1,10 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-export * from './src/dom/Keyboard';
packages/react-interactions/events/press.js
deleted
-10
@@ -1,10 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-export * from './src/dom/Press';
packages/react-interactions/events/src/dom/Keyboard.js
deleted
-242
@@ -1,242 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {
11
- ReactDOMResponderEvent,
12
- ReactDOMResponderContext,
13
-} from 'react-dom/src/shared/ReactDOMTypes';
14
-import type {ReactEventResponderListener} from 'shared/ReactTypes';
15
-
16
-import * as React from 'react';
17
-import {DiscreteEvent} from 'shared/ReactTypes';
18
-import {isVirtualClick} from './shared';
19
-
20
-type KeyboardEventType =
21
- | 'keyboard:click'
22
- | 'keyboard:keydown'
23
- | 'keyboard:keyup';
24
-
25
-type KeyboardProps = {|
26
- disabled?: boolean,
27
- onClick?: (e: KeyboardEvent) => void,
28
- onKeyDown?: (e: KeyboardEvent) => void,
29
- onKeyUp?: (e: KeyboardEvent) => void,
30
-|};
31
-
32
-type KeyboardState = {|
33
- isActive: boolean,
34
-|};
35
-
36
-export type KeyboardEvent = {|
37
- altKey: boolean,
38
- ctrlKey: boolean,
39
- defaultPrevented: boolean,
40
- isComposing?: boolean,
41
- key?: string,
42
- metaKey: boolean,
43
- pointerType: 'keyboard',
44
- shiftKey: boolean,
45
- target: Element | Document,
46
- type: KeyboardEventType,
47
- timeStamp: number,
48
- continuePropagation: () => void,
49
- preventDefault: () => void,
50
-|};
51
-
52
-const targetEventTypes = ['click_active', 'keydown_active', 'keyup'];
53
-
54
-/**
55
- * Normalization of deprecated HTML5 `key` values
56
- * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
57
- */
58
-const normalizeKey = {
59
- Esc: 'Escape',
60
- Spacebar: ' ',
61
- Left: 'ArrowLeft',
62
- Up: 'ArrowUp',
63
- Right: 'ArrowRight',
64
- Down: 'ArrowDown',
65
- Del: 'Delete',
66
- Win: 'OS',
67
- Menu: 'ContextMenu',
68
- Apps: 'ContextMenu',
69
- Scroll: 'ScrollLock',
70
- MozPrintableKey: 'Unidentified',
71
-};
72
-
73
-/**
74
- * Translation from legacy `keyCode` to HTML5 `key`
75
- * Only special keys supported, all others depend on keyboard layout or browser
76
- * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
77
- */
78
-const translateToKey = {
79
- '8': 'Backspace',
80
- '9': 'Tab',
81
- '12': 'Clear',
82
- '13': 'Enter',
83
- '16': 'Shift',
84
- '17': 'Control',
85
- '18': 'Alt',
86
- '19': 'Pause',
87
- '20': 'CapsLock',
88
- '27': 'Escape',
89
- '32': ' ',
90
- '33': 'PageUp',
91
- '34': 'PageDown',
92
- '35': 'End',
93
- '36': 'Home',
94
- '37': 'ArrowLeft',
95
- '38': 'ArrowUp',
96
- '39': 'ArrowRight',
97
- '40': 'ArrowDown',
98
- '45': 'Insert',
99
- '46': 'Delete',
100
- '112': 'F1',
101
- '113': 'F2',
102
- '114': 'F3',
103
- '115': 'F4',
104
- '116': 'F5',
105
- '117': 'F6',
106
- '118': 'F7',
107
- '119': 'F8',
108
- '120': 'F9',
109
- '121': 'F10',
110
- '122': 'F11',
111
- '123': 'F12',
112
- '144': 'NumLock',
113
- '145': 'ScrollLock',
114
- '224': 'Meta',
115
-};
116
-
117
-function getEventKey(nativeEvent: Object): string {
118
- const nativeKey = nativeEvent.key;
119
- if (nativeKey) {
120
- // Normalize inconsistent values reported by browsers due to
121
- // implementations of a working draft specification.
122
-
123
- // FireFox implements `key` but returns `MozPrintableKey` for all
124
- // printable characters (normalized to `Unidentified`), ignore it.
125
- const key = normalizeKey[nativeKey] || nativeKey;
126
- if (key !== 'Unidentified') {
127
- return key;
128
- }
129
- }
130
- return translateToKey[nativeEvent.keyCode] || 'Unidentified';
131
-}
132
-
133
-function createKeyboardEvent(
134
- event: ReactDOMResponderEvent,
135
- context: ReactDOMResponderContext,
136
- type: KeyboardEventType,
137
-): KeyboardEvent {
138
- const nativeEvent = (event: any).nativeEvent;
139
- const {altKey, ctrlKey, metaKey, shiftKey} = nativeEvent;
140
- let keyboardEvent = {
141
- altKey,
142
- ctrlKey,
143
- defaultPrevented: nativeEvent.defaultPrevented === true,
144
- metaKey,
145
- pointerType: 'keyboard',
146
- shiftKey,
147
- target: event.target,
148
- timeStamp: context.getTimeStamp(),
149
- type,
150
- // We don't use stopPropagation, as the default behavior
151
- // is to not propagate. Plus, there might be confusion
152
- // using stopPropagation as we don't actually stop
153
- // native propagation from working, but instead only
154
- // allow propagation to the others keyboard responders.
155
- continuePropagation() {
156
- context.continuePropagation();
157
- },
158
- preventDefault() {
159
- keyboardEvent.defaultPrevented = true;
160
- nativeEvent.preventDefault();
161
- },
162
- };
163
- if (type !== 'keyboard:click') {
164
- const key = getEventKey(nativeEvent);
165
- const isComposing = nativeEvent.isComposing;
166
- keyboardEvent = context.objectAssign({isComposing, key}, keyboardEvent);
167
- }
168
- return keyboardEvent;
169
-}
170
-
171
-function dispatchKeyboardEvent(
172
- event: ReactDOMResponderEvent,
173
- listener: KeyboardEvent => void,
174
- context: ReactDOMResponderContext,
175
- type: KeyboardEventType,
176
-): void {
177
- const syntheticEvent = createKeyboardEvent(event, context, type);
178
- context.dispatchEvent(syntheticEvent, listener, DiscreteEvent);
179
-}
180
-
181
-const keyboardResponderImpl = {
182
- targetEventTypes,
183
- targetPortalPropagation: true,
184
- getInitialState(): KeyboardState {
185
- return {
186
- isActive: false,
187
- };
188
- },
189
- onEvent(
190
- event: ReactDOMResponderEvent,
191
- context: ReactDOMResponderContext,
192
- props: KeyboardProps,
193
- state: KeyboardState,
194
- ): void {
195
- const {type} = event;
196
-
197
- if (props.disabled) {
198
- return;
199
- }
200
-
201
- if (type === 'keydown') {
202
- state.isActive = true;
203
- const onKeyDown = props.onKeyDown;
204
- if (onKeyDown != null) {
205
- dispatchKeyboardEvent(
206
- event,
207
- ((onKeyDown: any): (e: KeyboardEvent) => void),
208
- context,
209
- 'keyboard:keydown',
210
- );
211
- }
212
- } else if (type === 'click' && isVirtualClick(event)) {
213
- const onClick = props.onClick;
214
- if (onClick != null) {
215
- dispatchKeyboardEvent(event, onClick, context, 'keyboard:click');
216
- }
217
- } else if (type === 'keyup') {
218
- state.isActive = false;
219
- const onKeyUp = props.onKeyUp;
220
- if (onKeyUp != null) {
221
- dispatchKeyboardEvent(
222
- event,
223
- ((onKeyUp: any): (e: KeyboardEvent) => void),
224
- context,
225
- 'keyboard:keyup',
226
- );
227
- }
228
- }
229
- },
230
-};
231
-
232
-// $FlowFixMe Can't add generic types without causing a parsing/syntax errors
233
-export const KeyboardResponder = React.DEPRECATED_createResponder(
234
- 'Keyboard',
235
- keyboardResponderImpl,
236
-);
237
-
238
-export function useKeyboard(
239
- props: KeyboardProps,
240
-): ?ReactEventResponderListener<any, any> {
241
- return React.DEPRECATED_useResponder(KeyboardResponder, props);
242
-}
packages/react-interactions/events/src/dom/Press.js
deleted
-227
@@ -1,227 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {PointerType} from 'react-dom/src/shared/ReactDOMTypes';
11
-
12
-import * as React from 'react';
13
-import {useTap} from 'react-interactions/events/tap';
14
-import {useKeyboard} from 'react-interactions/events/keyboard';
15
-
16
-const emptyObject = {};
17
-
18
-type PressProps = $ReadOnly<{|
19
- disabled?: boolean,
20
- preventDefault?: boolean,
21
- onPress?: (e: PressEvent) => void,
22
- onPressChange?: boolean => void,
23
- onPressEnd?: (e: PressEvent) => void,
24
- onPressMove?: (e: PressEvent) => void,
25
- onPressStart?: (e: PressEvent) => void,
26
-|}>;
27
-
28
-type PressEventType =
29
- | 'pressstart'
30
- | 'presschange'
31
- | 'pressmove'
32
- | 'pressend'
33
- | 'press';
34
-
35
-type PressEvent = {|
36
- altKey: boolean,
37
- buttons: null | 1 | 4,
38
- ctrlKey: boolean,
39
- defaultPrevented: boolean,
40
- key: null | string,
41
- metaKey: boolean,
42
- pageX: number,
43
- pageY: number,
44
- pointerType: PointerType,
45
- shiftKey: boolean,
46
- target: null | Element,
47
- timeStamp: number,
48
- type: PressEventType,
49
- x: number,
50
- y: number,
51
- preventDefault: () => void,
52
- stopPropagation: () => void,
53
-|};
54
-
55
-function createGestureState(e: any, type: PressEventType): PressEvent {
56
- return {
57
- altKey: e.altKey,
58
- buttons: e.type === 'tap:auxiliary' ? 4 : 1,
59
- ctrlKey: e.ctrlKey,
60
- defaultPrevented: e.defaultPrevented,
61
- key: e.key,
62
- metaKey: e.metaKey,
63
- pageX: e.pageX,
64
- pageY: e.pageX,
65
- pointerType: e.pointerType,
66
- shiftKey: e.shiftKey,
67
- target: e.target,
68
- timeStamp: e.timeStamp,
69
- type,
70
- x: e.x,
71
- y: e.y,
72
- preventDefault() {
73
- // NO-OP, we should remove this in the future
74
- if (__DEV__) {
75
- console.error(
76
- 'preventDefault is not available on event objects created from event responder modules (React Flare). ' +
77
- 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.preventDefault() }`',
78
- );
79
- }
80
- },
81
- stopPropagation() {
82
- // NO-OP, we should remove this in the future
83
- if (__DEV__) {
84
- console.error(
85
- 'stopPropagation is not available on event objects created from event responder modules (React Flare). ' +
86
- 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.stopPropagation() }`',
87
- );
88
- }
89
- },
90
- };
91
-}
92
-
93
-function isValidKey(e): boolean {
94
- const {key, target} = e;
95
- const {tagName, isContentEditable} = (target: any);
96
- return (
97
- (key === 'Enter' || key === ' ' || key === 'Spacebar') &&
98
- tagName !== 'INPUT' &&
99
- tagName !== 'TEXTAREA' &&
100
- isContentEditable !== true
101
- );
102
-}
103
-
104
-function handlePreventDefault(preventDefault: ?boolean, e: any): void {
105
- const key = e.key;
106
- if (
107
- preventDefault !== false &&
108
- (key === ' ' || key === 'Enter' || key === 'Spacebar')
109
- ) {
110
- e.preventDefault();
111
- }
112
-}
113
-
114
-/**
115
- * The lack of built-in composition for gesture responders means we have to
116
- * selectively ignore callbacks from useKeyboard or useTap if the other is
117
- * active.
118
- */
119
-export function usePress(props: PressProps) {
120
- const safeProps = props || emptyObject;
121
- const {
122
- disabled,
123
- preventDefault,
124
- onPress,
125
- onPressChange,
126
- onPressEnd,
127
- onPressMove,
128
- onPressStart,
129
- } = safeProps;
130
-
131
- const activeResponder = React.useRef(null);
132
-
133
- const tap = useTap({
134
- disabled: disabled || activeResponder.current === 'keyboard',
135
- preventDefault,
136
- onAuxiliaryTap(e) {
137
- if (onPressStart != null) {
138
- onPressStart(createGestureState(e, 'pressstart'));
139
- }
140
- if (onPressEnd != null) {
141
- onPressEnd(createGestureState(e, 'pressend'));
142
- }
143
- // Here we rely on Tap only calling 'onAuxiliaryTap' with modifiers when
144
- // the primary button is pressed
145
- if (onPress != null && (e.metaKey || e.shiftKey)) {
146
- onPress(createGestureState(e, 'press'));
147
- }
148
- },
149
- onTapStart(e) {
150
- if (activeResponder.current == null) {
151
- activeResponder.current = 'tap';
152
- if (onPressStart != null) {
153
- onPressStart(createGestureState(e, 'pressstart'));
154
- }
155
- }
156
- },
157
- onTapChange: onPressChange,
158
- onTapUpdate(e) {
159
- if (activeResponder.current === 'tap') {
160
- if (onPressMove != null) {
161
- onPressMove(createGestureState(e, 'pressmove'));
162
- }
163
- }
164
- },
165
- onTapEnd(e) {
166
- if (activeResponder.current === 'tap') {
167
- if (onPressEnd != null) {
168
- onPressEnd(createGestureState(e, 'pressend'));
169
- }
170
- if (onPress != null) {
171
- onPress(createGestureState(e, 'press'));
172
- }
173
- activeResponder.current = null;
174
- }
175
- },
176
- onTapCancel(e) {
177
- if (activeResponder.current === 'tap') {
178
- if (onPressEnd != null) {
179
- onPressEnd(createGestureState(e, 'pressend'));
180
- }
181
- activeResponder.current = null;
182
- }
183
- },
184
- });
185
-
186
- const keyboard = useKeyboard({
187
- disabled: disabled || activeResponder.current === 'tap',
188
- onClick(e) {
189
- if (preventDefault !== false) {
190
- e.preventDefault();
191
- }
192
- if (activeResponder.current == null && onPress != null) {
193
- onPress(createGestureState(e, 'press'));
194
- }
195
- },
196
- onKeyDown(e) {
197
- if (activeResponder.current == null && isValidKey(e)) {
198
- handlePreventDefault(preventDefault, e);
199
- activeResponder.current = 'keyboard';
200
-
201
- if (onPressStart != null) {
202
- onPressStart(createGestureState(e, 'pressstart'));
203
- }
204
- if (onPressChange != null) {
205
- onPressChange(true);
206
- }
207
- }
208
- },
209
- onKeyUp(e) {
210
- if (activeResponder.current === 'keyboard' && isValidKey(e)) {
211
- handlePreventDefault(preventDefault, e);
212
- if (onPressChange != null) {
213
- onPressChange(false);
214
- }
215
- if (onPressEnd != null) {
216
- onPressEnd(createGestureState(e, 'pressend'));
217
- }
218
- if (onPress != null) {
219
- onPress(createGestureState(e, 'press'));
220
- }
221
- activeResponder.current = null;
222
- }
223
- },
224
- });
225
-
226
- return [tap, keyboard];
227
-}
packages/react-interactions/events/src/dom/__tests__/Keyboard-test.internal.js
deleted
-506
@@ -1,506 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @emails react-core
8
- */
9
-
10
-'use strict';
11
-
12
-let React;
13
-let ReactFeatureFlags;
14
-let ReactDOM;
15
-let useKeyboard;
16
-
17
-import {createEventTarget} from 'dom-event-testing-library';
18
-
19
-function initializeModules(hasPointerEvents) {
20
- jest.resetModules();
21
- ReactFeatureFlags = require('shared/ReactFeatureFlags');
22
- ReactFeatureFlags.enableDeprecatedFlareAPI = true;
23
- React = require('react');
24
- ReactDOM = require('react-dom');
25
-
26
- // TODO: This import throws outside of experimental mode. Figure out better
27
- // strategy for gated imports.
28
- if (__EXPERIMENTAL__) {
29
- useKeyboard = require('react-interactions/events/keyboard').useKeyboard;
30
- }
31
-}
32
-
33
-describe('Keyboard responder', () => {
34
- let container;
35
-
36
- beforeEach(() => {
37
- initializeModules();
38
- container = document.createElement('div');
39
- document.body.appendChild(container);
40
- });
41
-
42
- afterEach(() => {
43
- ReactDOM.render(null, container);
44
- document.body.removeChild(container);
45
- container = null;
46
- });
47
-
48
- function renderPropagationTest(propagates) {
49
- const onClickInner = jest.fn(e => propagates && e.continuePropagation());
50
- const onKeyDownInner = jest.fn(e => propagates && e.continuePropagation());
51
- const onKeyUpInner = jest.fn(e => propagates && e.continuePropagation());
52
- const onClickOuter = jest.fn();
53
- const onKeyDownOuter = jest.fn();
54
- const onKeyUpOuter = jest.fn();
55
- const ref = React.createRef();
56
- const Component = () => {
57
- const listenerInner = useKeyboard({
58
- onClick: onClickInner,
59
- onKeyDown: onKeyDownInner,
60
- onKeyUp: onKeyUpInner,
61
- });
62
- const listenerOuter = useKeyboard({
63
- onClick: onClickOuter,
64
- onKeyDown: onKeyDownOuter,
65
- onKeyUp: onKeyUpOuter,
66
- });
67
- return (
68
- <div DEPRECATED_flareListeners={listenerOuter}>
69
- <div ref={ref} DEPRECATED_flareListeners={listenerInner} />
70
- </div>
71
- );
72
- };
73
- ReactDOM.render(<Component />, container);
74
- return {
75
- onClickInner,
76
- onKeyDownInner,
77
- onKeyUpInner,
78
- onClickOuter,
79
- onKeyDownOuter,
80
- onKeyUpOuter,
81
- ref,
82
- };
83
- }
84
-
85
- // @gate experimental
86
- test('propagates key event when a continuePropagation() is used', () => {
87
- const {
88
- onClickInner,
89
- onKeyDownInner,
90
- onKeyUpInner,
91
- onClickOuter,
92
- onKeyDownOuter,
93
- onKeyUpOuter,
94
- ref,
95
- } = renderPropagationTest(true);
96
- const target = createEventTarget(ref.current);
97
- target.keydown();
98
- expect(onKeyDownInner).toBeCalled();
99
- expect(onKeyDownOuter).toBeCalled();
100
- target.keyup();
101
- expect(onKeyUpInner).toBeCalled();
102
- expect(onKeyUpOuter).toBeCalled();
103
- target.virtualclick();
104
- expect(onClickInner).toBeCalled();
105
- expect(onClickOuter).toBeCalled();
106
- });
107
-
108
- // @gate experimental
109
- test('does not propagate key event by default', () => {
110
- const {
111
- onClickInner,
112
- onKeyDownInner,
113
- onKeyUpInner,
114
- onClickOuter,
115
- onKeyDownOuter,
116
- onKeyUpOuter,
117
- ref,
118
- } = renderPropagationTest(false);
119
- const target = createEventTarget(ref.current);
120
- target.keydown();
121
- expect(onKeyDownInner).toBeCalled();
122
- expect(onKeyDownOuter).not.toBeCalled();
123
- target.keyup();
124
- expect(onKeyUpInner).toBeCalled();
125
- expect(onKeyUpOuter).not.toBeCalled();
126
- target.virtualclick();
127
- expect(onClickInner).toBeCalled();
128
- expect(onClickOuter).not.toBeCalled();
129
- });
130
-
131
- describe('disabled', () => {
132
- let onKeyDown, onKeyUp, ref;
133
-
134
- const componentInit = () => {
135
- onKeyDown = jest.fn();
136
- onKeyUp = jest.fn();
137
- ref = React.createRef();
138
- const Component = () => {
139
- const listener = useKeyboard({disabled: true, onKeyDown, onKeyUp});
140
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
141
- };
142
- ReactDOM.render(<Component />, container);
143
- };
144
-
145
- // @gate experimental
146
- test('does not call callbacks', () => {
147
- componentInit();
148
- const target = createEventTarget(ref.current);
149
- target.keydown();
150
- target.keyup();
151
- expect(onKeyDown).not.toBeCalled();
152
- expect(onKeyUp).not.toBeCalled();
153
- });
154
- });
155
-
156
- describe('onClick', () => {
157
- let onClick, ref;
158
-
159
- const componentInit = () => {
160
- onClick = jest.fn(e => {
161
- e.preventDefault();
162
- });
163
- ref = React.createRef();
164
- const Component = () => {
165
- const listener = useKeyboard({onClick});
166
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
167
- };
168
- ReactDOM.render(<Component />, container);
169
- };
170
-
171
- // e.g, "Enter" on link
172
- // @gate experimental
173
- test('click is between key events', () => {
174
- componentInit();
175
- const target = createEventTarget(ref.current);
176
- target.keydown({key: 'Enter'});
177
- target.keyup({key: 'Enter'});
178
- target.virtualclick();
179
- expect(onClick).toHaveBeenCalledTimes(1);
180
- expect(onClick).toHaveBeenCalledWith(
181
- expect.objectContaining({
182
- altKey: false,
183
- ctrlKey: false,
184
- defaultPrevented: true,
185
- metaKey: false,
186
- pointerType: 'keyboard',
187
- shiftKey: false,
188
- target: target.node,
189
- timeStamp: expect.any(Number),
190
- type: 'keyboard:click',
191
- }),
192
- );
193
- });
194
-
195
- // e.g., "Spacebar" on button
196
- // @gate experimental
197
- test('click is after key events', () => {
198
- componentInit();
199
- const target = createEventTarget(ref.current);
200
- target.keydown({key: 'Enter'});
201
- target.keyup({key: 'Enter'});
202
- target.virtualclick();
203
- expect(onClick).toHaveBeenCalledTimes(1);
204
- expect(onClick).toHaveBeenCalledWith(
205
- expect.objectContaining({
206
- altKey: false,
207
- ctrlKey: false,
208
- defaultPrevented: true,
209
- metaKey: false,
210
- pointerType: 'keyboard',
211
- shiftKey: false,
212
- target: target.node,
213
- timeStamp: expect.any(Number),
214
- type: 'keyboard:click',
215
- }),
216
- );
217
- });
218
-
219
- // e.g, generated by a screen-reader
220
- // @gate experimental
221
- test('click is orphan', () => {
222
- componentInit();
223
- const target = createEventTarget(ref.current);
224
- target.virtualclick();
225
- expect(onClick).toHaveBeenCalledTimes(1);
226
- expect(onClick).toHaveBeenCalledWith(
227
- expect.objectContaining({
228
- altKey: false,
229
- ctrlKey: false,
230
- defaultPrevented: true,
231
- metaKey: false,
232
- pointerType: 'keyboard',
233
- shiftKey: false,
234
- target: target.node,
235
- timeStamp: expect.any(Number),
236
- type: 'keyboard:click',
237
- }),
238
- );
239
- });
240
- });
241
-
242
- describe('onKeyDown', () => {
243
- let onKeyDown, ref;
244
-
245
- const componentInit = () => {
246
- onKeyDown = jest.fn();
247
- ref = React.createRef();
248
- const Component = () => {
249
- const listener = useKeyboard({onKeyDown});
250
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
251
- };
252
- ReactDOM.render(<Component />, container);
253
- };
254
-
255
- // @gate experimental
256
- test('key down', () => {
257
- componentInit();
258
- const target = createEventTarget(ref.current);
259
- target.keydown({key: 'Q'});
260
- expect(onKeyDown).toHaveBeenCalledTimes(1);
261
- expect(onKeyDown).toHaveBeenCalledWith(
262
- expect.objectContaining({
263
- altKey: false,
264
- ctrlKey: false,
265
- defaultPrevented: false,
266
- isComposing: false,
267
- key: 'Q',
268
- metaKey: false,
269
- pointerType: 'keyboard',
270
- shiftKey: false,
271
- target: target.node,
272
- timeStamp: expect.any(Number),
273
- type: 'keyboard:keydown',
274
- }),
275
- );
276
- });
277
-
278
- // @gate experimental
279
- test('modified key down', () => {
280
- componentInit();
281
- const target = createEventTarget(ref.current);
282
- target.keydown({
283
- key: 'Q',
284
- altKey: true,
285
- ctrlKey: true,
286
- shiftKey: true,
287
- metaKey: true,
288
- });
289
- expect(onKeyDown).toHaveBeenCalledWith(
290
- expect.objectContaining({
291
- altKey: true,
292
- ctrlKey: true,
293
- defaultPrevented: false,
294
- isComposing: false,
295
- key: 'Q',
296
- metaKey: true,
297
- pointerType: 'keyboard',
298
- shiftKey: true,
299
- target: target.node,
300
- timeStamp: expect.any(Number),
301
- type: 'keyboard:keydown',
302
- }),
303
- );
304
- });
305
- });
306
-
307
- describe('onKeyUp', () => {
308
- let onKeyUp, ref;
309
-
310
- const componentInit = () => {
311
- onKeyUp = jest.fn();
312
- ref = React.createRef();
313
- const Component = () => {
314
- const listener = useKeyboard({onKeyUp});
315
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
316
- };
317
- ReactDOM.render(<Component />, container);
318
- };
319
-
320
- // @gate experimental
321
- test('key up', () => {
322
- componentInit();
323
- const target = createEventTarget(ref.current);
324
- target.keydown({key: 'Q'});
325
- target.keyup({key: 'Q'});
326
- expect(onKeyUp).toHaveBeenCalledTimes(1);
327
- expect(onKeyUp).toHaveBeenCalledWith(
328
- expect.objectContaining({
329
- altKey: false,
330
- ctrlKey: false,
331
- defaultPrevented: false,
332
- isComposing: false,
333
- key: 'Q',
334
- metaKey: false,
335
- pointerType: 'keyboard',
336
- shiftKey: false,
337
- target: target.node,
338
- timeStamp: expect.any(Number),
339
- type: 'keyboard:keyup',
340
- }),
341
- );
342
- });
343
-
344
- // @gate experimental
345
- test('modified key up', () => {
346
- componentInit();
347
- const target = createEventTarget(ref.current);
348
- target.keydown({key: 'Q'});
349
- target.keyup({
350
- key: 'Q',
351
- altKey: true,
352
- ctrlKey: true,
353
- shiftKey: true,
354
- metaKey: true,
355
- });
356
- expect(onKeyUp).toHaveBeenCalledWith(
357
- expect.objectContaining({
358
- altKey: true,
359
- ctrlKey: true,
360
- defaultPrevented: false,
361
- isComposing: false,
362
- key: 'Q',
363
- metaKey: true,
364
- pointerType: 'keyboard',
365
- shiftKey: true,
366
- target: target.node,
367
- timeStamp: expect.any(Number),
368
- type: 'keyboard:keyup',
369
- }),
370
- );
371
- });
372
- });
373
-
374
- describe('preventDefault for onClick', () => {
375
- function render(props) {
376
- const ref = React.createRef();
377
- const Component = () => {
378
- const listener = useKeyboard(props);
379
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
380
- };
381
- ReactDOM.render(<Component />, container);
382
- return ref;
383
- }
384
-
385
- // @gate experimental
386
- test('does not prevent native click by default', () => {
387
- const onClick = jest.fn();
388
- const preventDefault = jest.fn();
389
- const ref = render({onClick});
390
-
391
- const target = createEventTarget(ref.current);
392
- target.virtualclick({preventDefault});
393
-
394
- expect(preventDefault).not.toBeCalled();
395
- expect(onClick).toHaveBeenCalledTimes(1);
396
- expect(onClick).toHaveBeenCalledWith(
397
- expect.objectContaining({
398
- defaultPrevented: false,
399
- }),
400
- );
401
- });
402
-
403
- // @gate experimental
404
- test('prevents native behaviour with preventDefault', () => {
405
- const onClick = jest.fn(e => e.preventDefault());
406
- const preventDefault = jest.fn();
407
- const ref = render({onClick});
408
-
409
- const target = createEventTarget(ref.current);
410
- target.virtualclick({preventDefault});
411
- expect(preventDefault).toBeCalled();
412
- expect(onClick).toHaveBeenCalledTimes(1);
413
- expect(onClick).toHaveBeenCalledWith(
414
- expect.objectContaining({
415
- defaultPrevented: true,
416
- }),
417
- );
418
- });
419
- });
420
-
421
- describe('preventDefault for onKeyDown', () => {
422
- function render(props) {
423
- const ref = React.createRef();
424
- const Component = () => {
425
- const listener = useKeyboard(props);
426
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
427
- };
428
- ReactDOM.render(<Component />, container);
429
- return ref;
430
- }
431
-
432
- // @gate experimental
433
- test('key config matches', () => {
434
- const onKeyDown = jest.fn(e => {
435
- if (e.key === 'Tab') {
436
- e.preventDefault();
437
- }
438
- });
439
- const preventDefault = jest.fn();
440
- const preventDefaultClick = jest.fn();
441
- const ref = render({onKeyDown});
442
-
443
- const target = createEventTarget(ref.current);
444
- target.keydown({key: 'Tab', preventDefault});
445
- target.virtualclick({preventDefault: preventDefaultClick});
446
-
447
- expect(preventDefault).toBeCalled();
448
- expect(onKeyDown).toHaveBeenCalledTimes(1);
449
- expect(onKeyDown).toHaveBeenCalledWith(
450
- expect.objectContaining({
451
- defaultPrevented: true,
452
- key: 'Tab',
453
- type: 'keyboard:keydown',
454
- }),
455
- );
456
- });
457
-
458
- // @gate experimental
459
- test('key config matches (modifier keys)', () => {
460
- const onKeyDown = jest.fn(e => {
461
- if (e.key === 'Tab' && e.shiftKey) {
462
- e.preventDefault();
463
- }
464
- });
465
- const preventDefault = jest.fn();
466
- const ref = render({onKeyDown});
467
-
468
- const target = createEventTarget(ref.current);
469
- target.keydown({key: 'Tab', preventDefault, shiftKey: true});
470
- expect(preventDefault).toBeCalled();
471
- expect(onKeyDown).toHaveBeenCalledTimes(1);
472
- expect(onKeyDown).toHaveBeenCalledWith(
473
- expect.objectContaining({
474
- defaultPrevented: true,
475
- key: 'Tab',
476
- shiftKey: true,
477
- type: 'keyboard:keydown',
478
- }),
479
- );
480
- });
481
-
482
- // @gate experimental
483
- test('key config does not match (modifier keys)', () => {
484
- const onKeyDown = jest.fn(e => {
485
- if (e.key === 'Tab' && e.shiftKey) {
486
- e.preventDefault();
487
- }
488
- });
489
- const preventDefault = jest.fn();
490
- const ref = render({onKeyDown});
491
-
492
- const target = createEventTarget(ref.current);
493
- target.keydown({key: 'Tab', preventDefault, shiftKey: false});
494
- expect(preventDefault).not.toBeCalled();
495
- expect(onKeyDown).toHaveBeenCalledTimes(1);
496
- expect(onKeyDown).toHaveBeenCalledWith(
497
- expect.objectContaining({
498
- defaultPrevented: false,
499
- key: 'Tab',
500
- shiftKey: false,
501
- type: 'keyboard:keydown',
502
- }),
503
- );
504
- });
505
- });
506
-});
packages/react-interactions/events/src/dom/__tests__/Press-test.internal.js
deleted
-832
@@ -1,832 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @emails react-core
8
- */
9
-
10
-'use strict';
11
-
12
-import {
13
- buttonType,
14
- buttonsType,
15
- createEventTarget,
16
- describeWithPointerEvent,
17
- resetActivePointers,
18
- setPointerEvent,
19
-} from 'dom-event-testing-library';
20
-
21
-let React;
22
-let ReactFeatureFlags;
23
-let ReactDOM;
24
-let usePress;
25
-
26
-function initializeModules(hasPointerEvents) {
27
- jest.resetModules();
28
- setPointerEvent(hasPointerEvents);
29
- ReactFeatureFlags = require('shared/ReactFeatureFlags');
30
- ReactFeatureFlags.enableDeprecatedFlareAPI = true;
31
- React = require('react');
32
- ReactDOM = require('react-dom');
33
-
34
- // TODO: This import throws outside of experimental mode. Figure out better
35
- // strategy for gated imports.
36
- if (__EXPERIMENTAL__) {
37
- usePress = require('react-interactions/events/press').usePress;
38
- }
39
-}
40
-
41
-describeWithPointerEvent('Press responder', hasPointerEvents => {
42
- let container;
43
-
44
- beforeEach(() => {
45
- initializeModules(hasPointerEvents);
46
- container = document.createElement('div');
47
- document.body.appendChild(container);
48
- });
49
-
50
- afterEach(() => {
51
- ReactDOM.render(null, container);
52
- document.body.removeChild(container);
53
- container = null;
54
- resetActivePointers();
55
- });
56
-
57
- describe('disabled', () => {
58
- let onPressStart, onPressChange, onPressMove, onPressEnd, onPress, ref;
59
-
60
- const componentInit = () => {
61
- onPressStart = jest.fn();
62
- onPressChange = jest.fn();
63
- onPressMove = jest.fn();
64
- onPressEnd = jest.fn();
65
- onPress = jest.fn();
66
- ref = React.createRef();
67
- const Component = () => {
68
- const listener = usePress({
69
- disabled: true,
70
- onPressStart,
71
- onPressChange,
72
- onPressMove,
73
- onPressEnd,
74
- onPress,
75
- });
76
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
77
- };
78
- ReactDOM.render(<Component />, container);
79
- };
80
-
81
- // @gate experimental
82
- test('does not call callbacks for pointers', () => {
83
- componentInit();
84
- const target = createEventTarget(ref.current);
85
- target.pointerdown();
86
- target.pointerup();
87
- expect(onPressStart).not.toBeCalled();
88
- expect(onPressChange).not.toBeCalled();
89
- expect(onPressMove).not.toBeCalled();
90
- expect(onPressEnd).not.toBeCalled();
91
- expect(onPress).not.toBeCalled();
92
- });
93
-
94
- // @gate experimental
95
- test('does not call callbacks for keyboard', () => {
96
- componentInit();
97
- const target = createEventTarget(ref.current);
98
- target.keydown({key: 'Enter'});
99
- target.keyup({key: 'Enter'});
100
- expect(onPressStart).not.toBeCalled();
101
- expect(onPressChange).not.toBeCalled();
102
- expect(onPressMove).not.toBeCalled();
103
- expect(onPressEnd).not.toBeCalled();
104
- expect(onPress).not.toBeCalled();
105
- });
106
- });
107
-
108
- describe('onPressStart', () => {
109
- let onPressStart, ref;
110
-
111
- const componentInit = () => {
112
- onPressStart = jest.fn();
113
- ref = React.createRef();
114
- const Component = () => {
115
- const listener = usePress({
116
- onPressStart,
117
- });
118
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
119
- };
120
- ReactDOM.render(<Component />, container);
121
- document.elementFromPoint = () => ref.current;
122
- };
123
-
124
- // @gate experimental
125
- it('is called after pointer down: mouse', () => {
126
- componentInit();
127
- const target = createEventTarget(ref.current);
128
- target.pointerdown({pointerType: 'mouse'});
129
- expect(onPressStart).toHaveBeenCalledTimes(1);
130
- expect(onPressStart).toHaveBeenCalledWith(
131
- expect.objectContaining({pointerType: 'mouse', type: 'pressstart'}),
132
- );
133
- });
134
-
135
- // @gate experimental
136
- it('is called after pointer down: mouse', () => {
137
- componentInit();
138
- const target = createEventTarget(ref.current);
139
- target.pointerdown({pointerType: 'touch'});
140
- expect(onPressStart).toHaveBeenCalledTimes(1);
141
- expect(onPressStart).toHaveBeenCalledWith(
142
- expect.objectContaining({pointerType: 'touch', type: 'pressstart'}),
143
- );
144
- });
145
-
146
- // @gate experimental
147
- it('is called after middle-button pointer down', () => {
148
- componentInit();
149
- const target = createEventTarget(ref.current);
150
- const pointerType = 'mouse';
151
- target.pointerdown({
152
- button: buttonType.auxiliary,
153
- buttons: buttonsType.auxiliary,
154
- pointerType,
155
- });
156
- target.pointerup({pointerType});
157
- expect(onPressStart).toHaveBeenCalledTimes(1);
158
- expect(onPressStart).toHaveBeenCalledWith(
159
- expect.objectContaining({
160
- buttons: buttonsType.auxiliary,
161
- pointerType: 'mouse',
162
- type: 'pressstart',
163
- }),
164
- );
165
- });
166
-
167
- // @gate experimental
168
- it('is called after virtual middle-button pointer down', () => {
169
- componentInit();
170
- const target = createEventTarget(ref.current);
171
- const pointerType = 'mouse';
172
- target.pointerdown({
173
- button: buttonType.auxiliary,
174
- buttons: 0,
175
- pointerType,
176
- });
177
- target.pointerup({pointerType});
178
- expect(onPressStart).toHaveBeenCalledTimes(1);
179
- expect(onPressStart).toHaveBeenCalledWith(
180
- expect.objectContaining({
181
- buttons: buttonsType.auxiliary,
182
- pointerType: 'mouse',
183
- type: 'pressstart',
184
- }),
185
- );
186
- });
187
-
188
- // @gate experimental
189
- it('ignores any events not caused by primary/middle-click or touch/pen contact', () => {
190
- componentInit();
191
- const target = createEventTarget(ref.current);
192
- target.pointerdown({buttons: buttonsType.secondary});
193
- target.pointerup({buttons: buttonsType.secondary});
194
- target.pointerdown({buttons: buttonsType.eraser});
195
- target.pointerup({buttons: buttonsType.eraser});
196
- expect(onPressStart).toHaveBeenCalledTimes(0);
197
- });
198
-
199
- // @gate experimental
200
- it('is called once after "keydown" events for Enter', () => {
201
- componentInit();
202
- const target = createEventTarget(ref.current);
203
- target.keydown({key: 'Enter'});
204
- target.keydown({key: 'Enter'});
205
- target.keydown({key: 'Enter'});
206
- expect(onPressStart).toHaveBeenCalledTimes(1);
207
- expect(onPressStart).toHaveBeenCalledWith(
208
- expect.objectContaining({pointerType: 'keyboard', type: 'pressstart'}),
209
- );
210
- });
211
-
212
- // @gate experimental
213
- it('is called once after "keydown" events for Spacebar', () => {
214
- componentInit();
215
- const target = createEventTarget(ref.current);
216
- const preventDefault = jest.fn();
217
- target.keydown({key: ' ', preventDefault});
218
- expect(preventDefault).toBeCalled();
219
- target.keydown({key: ' ', preventDefault});
220
- expect(onPressStart).toHaveBeenCalledTimes(1);
221
- expect(onPressStart).toHaveBeenCalledWith(
222
- expect.objectContaining({
223
- pointerType: 'keyboard',
224
- type: 'pressstart',
225
- }),
226
- );
227
- });
228
-
229
- // @gate experimental
230
- it('is not called after "keydown" for other keys', () => {
231
- componentInit();
232
- const target = createEventTarget(ref.current);
233
- target.keydown({key: 'a'});
234
- expect(onPressStart).not.toBeCalled();
235
- });
236
- });
237
-
238
- describe('onPressEnd', () => {
239
- let onPressEnd, ref;
240
-
241
- const componentInit = () => {
242
- onPressEnd = jest.fn();
243
- ref = React.createRef();
244
- const Component = () => {
245
- const listener = usePress({
246
- onPressEnd,
247
- });
248
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
249
- };
250
- ReactDOM.render(<Component />, container);
251
- document.elementFromPoint = () => ref.current;
252
- };
253
-
254
- // @gate experimental
255
- it('is called after pointer up: mouse', () => {
256
- componentInit();
257
- const target = createEventTarget(ref.current);
258
- target.pointerdown({pointerType: 'mouse'});
259
- target.pointerup({pointerType: 'mouse'});
260
- expect(onPressEnd).toHaveBeenCalledTimes(1);
261
- expect(onPressEnd).toHaveBeenCalledWith(
262
- expect.objectContaining({pointerType: 'mouse', type: 'pressend'}),
263
- );
264
- });
265
-
266
- // @gate experimental
267
- it('is called after pointer up: touch', () => {
268
- componentInit();
269
- const target = createEventTarget(ref.current);
270
- target.pointerdown({pointerType: 'touch'});
271
- target.pointerup({pointerType: 'touch'});
272
- expect(onPressEnd).toHaveBeenCalledTimes(1);
273
- expect(onPressEnd).toHaveBeenCalledWith(
274
- expect.objectContaining({pointerType: 'touch', type: 'pressend'}),
275
- );
276
- });
277
-
278
- // @gate experimental
279
- it('is called after middle-button pointer up', () => {
280
- componentInit();
281
- const target = createEventTarget(ref.current);
282
- target.pointerdown({
283
- button: buttonType.auxiliary,
284
- buttons: buttonsType.auxiliary,
285
- pointerType: 'mouse',
286
- });
287
- target.pointerup({pointerType: 'mouse'});
288
- expect(onPressEnd).toHaveBeenCalledTimes(1);
289
- expect(onPressEnd).toHaveBeenCalledWith(
290
- expect.objectContaining({
291
- buttons: buttonsType.auxiliary,
292
- pointerType: 'mouse',
293
- type: 'pressend',
294
- }),
295
- );
296
- });
297
-
298
- // @gate experimental
299
- it('is called after virtual middle-button pointer up', () => {
300
- componentInit();
301
- const target = createEventTarget(ref.current);
302
- target.pointerdown({
303
- button: buttonType.auxiliary,
304
- buttons: 0,
305
- pointerType: 'mouse',
306
- });
307
- target.pointerup({pointerType: 'mouse'});
308
- expect(onPressEnd).toHaveBeenCalledTimes(1);
309
- expect(onPressEnd).toHaveBeenCalledWith(
310
- expect.objectContaining({
311
- buttons: buttonsType.auxiliary,
312
- pointerType: 'mouse',
313
- type: 'pressend',
314
- }),
315
- );
316
- });
317
-
318
- // @gate experimental
319
- it('is called after "keyup" event for Enter', () => {
320
- componentInit();
321
- const target = createEventTarget(ref.current);
322
- target.keydown({key: 'Enter'});
323
- // click occurs before keyup
324
- target.virtualclick();
325
- target.keyup({key: 'Enter'});
326
- expect(onPressEnd).toHaveBeenCalledTimes(1);
327
- expect(onPressEnd).toHaveBeenCalledWith(
328
- expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}),
329
- );
330
- });
331
-
332
- // @gate experimental
333
- it('is called after "keyup" event for Spacebar', () => {
334
- componentInit();
335
- const target = createEventTarget(ref.current);
336
- target.keydown({key: ' '});
337
- target.keyup({key: ' '});
338
- expect(onPressEnd).toHaveBeenCalledTimes(1);
339
- expect(onPressEnd).toHaveBeenCalledWith(
340
- expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}),
341
- );
342
- });
343
-
344
- // @gate experimental
345
- it('is not called after "keyup" event for other keys', () => {
346
- componentInit();
347
- const target = createEventTarget(ref.current);
348
- target.keydown({key: 'Enter'});
349
- target.keyup({key: 'a'});
350
- expect(onPressEnd).not.toBeCalled();
351
- });
352
-
353
- // @gate experimental
354
- it('is called with keyboard modifiers', () => {
355
- componentInit();
356
- const target = createEventTarget(ref.current);
357
- target.keydown({key: 'Enter'});
358
- target.keyup({
359
- key: 'Enter',
360
- metaKey: true,
361
- ctrlKey: true,
362
- altKey: true,
363
- shiftKey: true,
364
- });
365
- expect(onPressEnd).toHaveBeenCalledWith(
366
- expect.objectContaining({
367
- pointerType: 'keyboard',
368
- type: 'pressend',
369
- metaKey: true,
370
- ctrlKey: true,
371
- altKey: true,
372
- shiftKey: true,
373
- }),
374
- );
375
- });
376
- });
377
-
378
- describe('onPressChange', () => {
379
- let onPressChange, ref;
380
-
381
- const componentInit = () => {
382
- onPressChange = jest.fn();
383
- ref = React.createRef();
384
- const Component = () => {
385
- const listener = usePress({
386
- onPressChange,
387
- });
388
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
389
- };
390
- ReactDOM.render(<Component />, container);
391
- document.elementFromPoint = () => ref.current;
392
- };
393
-
394
- // @gate experimental
395
- it('is called after pointer down and up: %s', () => {
396
- componentInit();
397
- const target = createEventTarget(ref.current);
398
- target.pointerdown({pointerType: 'mouse'});
399
- expect(onPressChange).toHaveBeenCalledTimes(1);
400
- expect(onPressChange).toHaveBeenCalledWith(true);
401
- target.pointerup({pointerType: 'mouse'});
402
- expect(onPressChange).toHaveBeenCalledTimes(2);
403
- expect(onPressChange).toHaveBeenCalledWith(false);
404
- });
405
-
406
- // @gate experimental
407
- it('is called after pointer down and up: touch', () => {
408
- componentInit();
409
- const target = createEventTarget(ref.current);
410
- target.pointerdown({pointerType: 'touch'});
411
- expect(onPressChange).toHaveBeenCalledTimes(1);
412
- expect(onPressChange).toHaveBeenCalledWith(true);
413
- target.pointerup({pointerType: 'touch'});
414
- expect(onPressChange).toHaveBeenCalledTimes(2);
415
- expect(onPressChange).toHaveBeenCalledWith(false);
416
- });
417
-
418
- // @gate experimental
419
- it('is called after valid "keydown" and "keyup" events', () => {
420
- componentInit();
421
- const target = createEventTarget(ref.current);
422
- target.keydown({key: 'Enter'});
423
- expect(onPressChange).toHaveBeenCalledTimes(1);
424
- expect(onPressChange).toHaveBeenCalledWith(true);
425
- target.keyup({key: 'Enter'});
426
- expect(onPressChange).toHaveBeenCalledTimes(2);
427
- expect(onPressChange).toHaveBeenCalledWith(false);
428
- });
429
- });
430
-
431
- describe('onPress', () => {
432
- let onPress, ref;
433
-
434
- const componentInit = () => {
435
- onPress = jest.fn();
436
- ref = React.createRef();
437
- const Component = () => {
438
- const listener = usePress({
439
- onPress,
440
- });
441
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
442
- };
443
- ReactDOM.render(<Component />, container);
444
- ref.current.getBoundingClientRect = () => ({
445
- top: 0,
446
- left: 0,
447
- bottom: 100,
448
- right: 100,
449
- });
450
- document.elementFromPoint = () => ref.current;
451
- };
452
-
453
- // @gate experimental
454
- it('is called after pointer up: %s', () => {
455
- componentInit();
456
- const target = createEventTarget(ref.current);
457
- target.pointerdown({pointerType: 'mouse'});
458
- target.pointerup({pointerType: 'mouse', x: 10, y: 10});
459
- expect(onPress).toHaveBeenCalledTimes(1);
460
- expect(onPress).toHaveBeenCalledWith(
461
- expect.objectContaining({pointerType: 'mouse', type: 'press'}),
462
- );
463
- });
464
-
465
- // @gate experimental
466
- it('is called after pointer up: %s', () => {
467
- componentInit();
468
- const target = createEventTarget(ref.current);
469
- target.pointerdown({pointerType: 'touch'});
470
- target.pointerup({pointerType: 'touch', x: 10, y: 10});
471
- expect(onPress).toHaveBeenCalledTimes(1);
472
- expect(onPress).toHaveBeenCalledWith(
473
- expect.objectContaining({pointerType: 'touch', type: 'press'}),
474
- );
475
- });
476
-
477
- // @gate experimental
478
- it('is not called after middle-button press', () => {
479
- componentInit();
480
- const target = createEventTarget(ref.current);
481
- target.pointerdown({
482
- button: buttonType.auxiliary,
483
- buttons: buttonsType.auxiliary,
484
- pointerType: 'mouse',
485
- });
486
- target.pointerup({pointerType: 'mouse'});
487
- expect(onPress).not.toHaveBeenCalled();
488
- });
489
-
490
- // @gate experimental
491
- it('is not called after virtual middle-button press', () => {
492
- componentInit();
493
- const target = createEventTarget(ref.current);
494
- target.pointerdown({
495
- button: buttonType.auxiliary,
496
- buttons: 0,
497
- pointerType: 'mouse',
498
- });
499
- target.pointerup({pointerType: 'mouse'});
500
- expect(onPress).not.toHaveBeenCalled();
501
- });
502
-
503
- // @gate experimental
504
- it('is called after valid "keyup" event', () => {
505
- componentInit();
506
- const target = createEventTarget(ref.current);
507
- target.keydown({key: 'Enter'});
508
- target.keyup({key: 'Enter'});
509
- expect(onPress).toHaveBeenCalledTimes(1);
510
- expect(onPress).toHaveBeenCalledWith(
511
- expect.objectContaining({pointerType: 'keyboard', type: 'press'}),
512
- );
513
- });
514
-
515
- // @gate experimental
516
- it('is not called after invalid "keyup" event', () => {
517
- componentInit();
518
- const inputRef = React.createRef();
519
- const Component = () => {
520
- const listener = usePress({onPress});
521
- return <input ref={inputRef} DEPRECATED_flareListeners={listener} />;
522
- };
523
- ReactDOM.render(<Component />, container);
524
- const target = createEventTarget(inputRef.current);
525
- target.keydown({key: 'Enter'});
526
- target.keyup({key: 'Enter'});
527
- target.keydown({key: ' '});
528
- target.keyup({key: ' '});
529
- expect(onPress).not.toBeCalled();
530
- });
531
-
532
- // @gate experimental
533
- it('is called with modifier keys', () => {
534
- componentInit();
535
- const target = createEventTarget(ref.current);
536
- target.pointerdown({metaKey: true, pointerType: 'mouse'});
537
- target.pointerup({metaKey: true, pointerType: 'mouse'});
538
- expect(onPress).toHaveBeenCalledWith(
539
- expect.objectContaining({
540
- pointerType: 'mouse',
541
- type: 'press',
542
- metaKey: true,
543
- }),
544
- );
545
- });
546
-
547
- // @gate experimental
548
- it('is called once after virtual screen reader "click" event', () => {
549
- componentInit();
550
- const target = createEventTarget(ref.current);
551
- const preventDefault = jest.fn();
552
- target.virtualclick({preventDefault});
553
- expect(preventDefault).toBeCalled();
554
- expect(onPress).toHaveBeenCalledTimes(1);
555
- expect(onPress).toHaveBeenCalledWith(
556
- expect.objectContaining({
557
- pointerType: 'keyboard',
558
- type: 'press',
559
- }),
560
- );
561
- });
562
- });
563
-
564
- describe('onPressMove', () => {
565
- let onPressMove, ref;
566
-
567
- const componentInit = () => {
568
- onPressMove = jest.fn();
569
- ref = React.createRef();
570
- const Component = () => {
571
- const listener = usePress({
572
- onPressMove,
573
- });
574
- return <div ref={ref} DEPRECATED_flareListeners={listener} />;
575
- };
576
- ReactDOM.render(<Component />, container);
577
- ref.current.getBoundingClientRect = () => ({
578
- top: 0,
579
- left: 0,
580
- bottom: 100,
581
- right: 100,
582
- });
583
- document.elementFromPoint = () => ref.current;
584
- };
585
-
586
- // @gate experimental
587
- it('is called after pointer move: mouse', () => {
588
- componentInit();
589
- const node = ref.current;
590
- const target = createEventTarget(node);
591
- target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
592
- target.pointerdown({pointerType: 'mouse'});
593
- target.pointermove({pointerType: 'mouse', x: 10, y: 10});
594
- target.pointermove({pointerType: 'mouse', x: 20, y: 20});
595
- expect(onPressMove).toHaveBeenCalledTimes(2);
596
- expect(onPressMove).toHaveBeenCalledWith(
597
- expect.objectContaining({pointerType: 'mouse', type: 'pressmove'}),
598
- );
599
- });
600
-
601
- // @gate experimental
602
- it('is called after pointer move: touch', () => {
603
- componentInit();
604
- const node = ref.current;
605
- const target = createEventTarget(node);
606
- target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
607
- target.pointerdown({pointerType: 'touch'});
608
- target.pointermove({pointerType: 'touch', x: 10, y: 10});
609
- target.pointermove({pointerType: 'touch', x: 20, y: 20});
610
- expect(onPressMove).toHaveBeenCalledTimes(2);
611
- expect(onPressMove).toHaveBeenCalledWith(
612
- expect.objectContaining({pointerType: 'touch', type: 'pressmove'}),
613
- );
614
- });
615
-
616
- // @gate experimental
617
- it('is not called if pointer move occurs during keyboard press', () => {
618
- componentInit();
619
- const target = createEventTarget(ref.current);
620
- target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
621
- target.keydown({key: 'Enter'});
622
- target.pointermove({
623
- buttons: buttonsType.none,
624
- pointerType: 'mouse',
625
- x: 10,
626
- y: 10,
627
- });
628
- expect(onPressMove).not.toBeCalled();
629
- });
630
- });
631
-
632
- describe('link components', () => {
633
- // @gate experimental
634
- it('prevents native behavior by default', () => {
635
- const onPress = jest.fn();
636
- const preventDefault = jest.fn();
637
- const ref = React.createRef();
638
-
639
- const Component = () => {
640
- const listener = usePress({onPress});
641
- return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
642
- };
643
- ReactDOM.render(<Component />, container);
644
-
645
- const target = createEventTarget(ref.current);
646
- target.pointerdown();
647
- target.pointerup({preventDefault});
648
- expect(preventDefault).toBeCalled();
649
- expect(onPress).toHaveBeenCalledWith(
650
- expect.objectContaining({defaultPrevented: true}),
651
- );
652
- });
653
-
654
- // @gate experimental
655
- it('prevents native behaviour for keyboard events by default', () => {
656
- const onPress = jest.fn();
657
- const preventDefaultClick = jest.fn();
658
- const preventDefaultKeyDown = jest.fn();
659
- const ref = React.createRef();
660
-
661
- const Component = () => {
662
- const listener = usePress({onPress});
663
- return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
664
- };
665
- ReactDOM.render(<Component />, container);
666
-
667
- const target = createEventTarget(ref.current);
668
- target.keydown({key: 'Enter', preventDefault: preventDefaultKeyDown});
669
- target.virtualclick({preventDefault: preventDefaultClick});
670
- target.keyup({key: 'Enter'});
671
- expect(preventDefaultKeyDown).toBeCalled();
672
- expect(preventDefaultClick).toBeCalled();
673
- expect(onPress).toHaveBeenCalledTimes(1);
674
- expect(onPress).toHaveBeenCalledWith(
675
- expect.objectContaining({defaultPrevented: true}),
676
- );
677
- });
678
-
679
- // @gate experimental
680
- it('deeply prevents native behaviour by default', () => {
681
- const onPress = jest.fn();
682
- const preventDefault = jest.fn();
683
- const buttonRef = React.createRef();
684
-
685
- const Component = () => {
686
- const listener = usePress({onPress});
687
- return (
688
- <a href="#">
689
- <button ref={buttonRef} DEPRECATED_flareListeners={listener} />
690
- </a>
691
- );
692
- };
693
- ReactDOM.render(<Component />, container);
694
-
695
- const target = createEventTarget(buttonRef.current);
696
- target.pointerdown();
697
- target.pointerup({preventDefault});
698
- expect(preventDefault).toBeCalled();
699
- });
700
-
701
- // @gate experimental
702
- it('prevents native behaviour by default with nested elements', () => {
703
- const onPress = jest.fn();
704
- const preventDefault = jest.fn();
705
- const ref = React.createRef();
706
-
707
- const Component = () => {
708
- const listener = usePress({onPress});
709
- return (
710
- <a href="#" DEPRECATED_flareListeners={listener}>
711
- <div ref={ref} />
712
- </a>
713
- );
714
- };
715
- ReactDOM.render(<Component />, container);
716
-
717
- const target = createEventTarget(ref.current);
718
- target.pointerdown();
719
- target.pointerup({preventDefault});
720
- expect(preventDefault).toBeCalled();
721
- expect(onPress).toHaveBeenCalledWith(
722
- expect.objectContaining({defaultPrevented: true}),
723
- );
724
- });
725
-
726
- // @gate experimental
727
- it('uses native behaviour for interactions with modifier keys', () => {
728
- const onPress = jest.fn();
729
- const preventDefault = jest.fn();
730
- const ref = React.createRef();
731
-
732
- const Component = () => {
733
- const listener = usePress({onPress});
734
- return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
735
- };
736
- ReactDOM.render(<Component />, container);
737
-
738
- ['metaKey', 'ctrlKey', 'shiftKey'].forEach(modifierKey => {
739
- const target = createEventTarget(ref.current);
740
- target.pointerdown({[modifierKey]: true});
741
- target.pointerup({[modifierKey]: true, preventDefault});
742
- expect(preventDefault).not.toBeCalled();
743
- expect(onPress).toHaveBeenCalledWith(
744
- expect.objectContaining({defaultPrevented: false}),
745
- );
746
- });
747
- });
748
-
749
- // @gate experimental
750
- it('uses native behaviour for pointer events if preventDefault is false', () => {
751
- const onPress = jest.fn();
752
- const preventDefault = jest.fn();
753
- const ref = React.createRef();
754
-
755
- const Component = () => {
756
- const listener = usePress({onPress, preventDefault: false});
757
- return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
758
- };
759
- ReactDOM.render(<Component />, container);
760
-
761
- const target = createEventTarget(ref.current);
762
- target.pointerdown();
763
- target.pointerup({preventDefault});
764
- expect(preventDefault).not.toBeCalled();
765
- expect(onPress).toHaveBeenCalledWith(
766
- expect.objectContaining({defaultPrevented: false}),
767
- );
768
- });
769
-
770
- // @gate experimental
771
- it('uses native behaviour for keyboard events if preventDefault is false', () => {
772
- const onPress = jest.fn();
773
- const preventDefault = jest.fn();
774
- const ref = React.createRef();
775
-
776
- const Component = () => {
777
- const listener = usePress({onPress, preventDefault: false});
778
- return <a href="#" ref={ref} DEPRECATED_flareListeners={listener} />;
779
- };
780
- ReactDOM.render(<Component />, container);
781
-
782
- const target = createEventTarget(ref.current);
783
- target.keydown({key: 'Enter'});
784
- target.virtualclick({preventDefault});
785
- target.keyup({key: 'Enter'});
786
- expect(preventDefault).not.toBeCalled();
787
- expect(onPress).toHaveBeenCalledTimes(1);
788
- expect(onPress).toHaveBeenCalledWith(
789
- expect.objectContaining({defaultPrevented: false}),
790
- );
791
- });
792
- });
793
-
794
- // @gate experimental
795
- it('should not trigger an invariant in addRootEventTypes()', () => {
796
- const ref = React.createRef();
797
-
798
- const Component = () => {
799
- const listener = usePress();
800
- return <button ref={ref} DEPRECATED_flareListeners={listener} />;
801
- };
802
- ReactDOM.render(<Component />, container);
803
-
804
- const target = createEventTarget(ref.current);
805
- target.pointerdown();
806
- target.pointermove();
807
- target.pointerup();
808
- target.pointerdown();
809
- });
810
-
811
- // @gate experimental
812
- it('when blur occurs on a pressed target, we should disengage press', () => {
813
- const onPress = jest.fn();
814
- const onPressStart = jest.fn();
815
- const onPressEnd = jest.fn();
816
- const buttonRef = React.createRef();
817
-
818
- const Component = () => {
819
- const listener = usePress({onPress, onPressStart, onPressEnd});
820
- return <button ref={buttonRef} DEPRECATED_flareListeners={listener} />;
821
- };
822
- ReactDOM.render(<Component />, container);
823
-
824
- const target = createEventTarget(buttonRef.current);
825
- target.pointerdown();
826
- expect(onPressStart).toBeCalled();
827
- target.blur();
828
- expect(onPressEnd).toBeCalled();
829
- target.pointerup();
830
- expect(onPress).not.toBeCalled();
831
- });
832
-});
packages/react-interactions/npm/keyboard.js
deleted
-7
@@ -1,7 +0,0 @@
1
-'use strict';
2
-
3
-if (process.env.NODE_ENV === 'production') {
4
- module.exports = require('./cjs/react-interactions-events/keyboard.production.min.js');
5
-} else {
6
- module.exports = require('./cjs/react-interactions-events/keyboard.development.js');
7
-}
packages/react-reconciler/src/__tests__/ReactScope-test.internal.js
-45
@@ -9,8 +9,6 @@
9
10
'use strict';
11
12
-import {createEventTarget} from 'dom-event-testing-library';
13
-
12
let React;
13
let ReactFeatureFlags;
14
let ReactDOMServer;
@@ -240,49 +238,6 @@ describe('ReactScope', () => {
238
expect(nodes).toEqual([divRef.current, spanRef.current, aRef.current]);
239
});
240
243
- // @gate experimental
244
- it('event responders can be attached to scopes', () => {
245
- let onKeyDown = jest.fn();
246
- const TestScope = React.unstable_createScope();
247
- const ref = React.createRef();
248
- const useKeyboard = require('react-interactions/events/keyboard')
249
- .useKeyboard;
250
- let Component = () => {
251
- const listener = useKeyboard({
252
- onKeyDown,
253
- });
254
- return (
255
- <TestScope DEPRECATED_flareListeners={listener}>
256
- <div ref={ref} />
257
- </TestScope>
258
- );
259
- };
260
- ReactDOM.render(<Component />, container);
261
-
262
- let target = createEventTarget(ref.current);
263
- target.keydown({key: 'Q'});
264
- expect(onKeyDown).toHaveBeenCalledTimes(1);
265
-
266
- onKeyDown = jest.fn();
267
- Component = () => {
268
- const listener = useKeyboard({
269
- onKeyDown,
270
- });
271
- return (
272
- <div>
273
- <TestScope DEPRECATED_flareListeners={listener}>
274
- <div ref={ref} />
275
- </TestScope>
276
- </div>
277
- );
278
- };
279
- ReactDOM.render(<Component />, container);
280
-
281
- target = createEventTarget(ref.current);
282
- target.keydown({key: 'Q'});
283
- expect(onKeyDown).toHaveBeenCalledTimes(1);
284
- });
285
-
241
// @gate experimental
242
it('getChildContextValues() works as intended', () => {
243
const TestContext = React.createContext();
scripts/rollup/bundles.js
-16
@@ -748,21 +748,6 @@ const bundles = [
748
externals: ['react'],
749
},
750
751
- {
752
- bundleTypes: [
753
- UMD_DEV,
754
- UMD_PROD,
755
- NODE_DEV,
756
- NODE_PROD,
757
- FB_WWW_DEV,
758
- FB_WWW_PROD,
759
- ],
760
- moduleType: NON_FIBER_RENDERER,
761
- entry: 'react-interactions/events/keyboard',
762
- global: 'ReactEventsKeyboard',
763
- externals: ['react'],
764
- },
765
-
751
{
752
bundleTypes: [
753
UMD_DEV,
@@ -781,7 +766,6 @@ const bundles = [
766
767
const fbBundleExternalsMap = {
768
'react-interactions/events/focus': 'ReactEventsFocus',
784
- 'react-interactions/events/keyboard': 'ReactEventsKeyboard',
769
'react-interactions/events/tap': 'ReactEventsTap',
770
};
771
scripts/rollup/modules.js
-1
@@ -24,7 +24,6 @@ const knownGlobals = Object.freeze({
24
react: 'React',
25
'react-dom': 'ReactDOM',
26
'react-dom/server': 'ReactDOMServer',
27
- 'react-interactions/events/keyboard': 'ReactEventsKeyboard',
27
'react-interactions/events/tap': 'ReactEventsTap',
28
scheduler: 'Scheduler',
29
'scheduler/tracing': 'SchedulerTracing',