@samitouri / QOS-React-2 / commits / 63fe08eef5

React Events: allow Tab+Alt on Mac in Focus responder (#15679)

* Fix issue with Tab+alt not being considered as isGlobalFocusVisible candidate on Mac * Add test for Tab+alt on Mac setting pointerType: "keyboard" on a focus event

Mateusz Burzyński committed May 31, 2019 at 23:33 UTC 63fe08eef56f92956c2d785701cad7f743501e35
2 files changed +47 -8
packages/react-events/src/Focus.js
+10 -1
@@ -39,6 +39,11 @@ type FocusEvent = {|
39 timeStamp: number,
40 |};
41
42 +const isMac =
43 + typeof window !== 'undefined' && window.navigator != null
44 + ? /^Mac/.test(window.navigator.platform)
45 + : false;
46 +
47 const targetEventTypes = [
48 {name: 'focus', passive: true},
49 {name: 'blur', passive: true},
@@ -304,7 +309,11 @@ const FocusResponder = {
309 const nativeEvent = event.nativeEvent;
310 if (
311 nativeEvent.key === 'Tab' &&
307 - !(nativeEvent.metaKey || nativeEvent.altKey || nativeEvent.ctrlKey)
312 + !(
313 + nativeEvent.metaKey ||
314 + (!isMac && nativeEvent.altKey) ||
315 + nativeEvent.ctrlKey
316 + )
317 ) {
318 state.pointerType = 'keyboard';
319 isGlobalFocusVisible = true;
packages/react-events/src/__tests__/Focus-test.internal.js
+37 -7
@@ -39,16 +39,20 @@ const createPointerEvent = (type, data) => {
39 return event;
40 };
41
42 +const modulesInit = () => {
43 + ReactFeatureFlags = require('shared/ReactFeatureFlags');
44 + ReactFeatureFlags.enableEventAPI = true;
45 + React = require('react');
46 + ReactDOM = require('react-dom');
47 + Focus = require('react-events/focus');
48 +};
49 +
50 describe('Focus event responder', () => {
51 let container;
52
53 beforeEach(() => {
54 jest.resetModules();
47 - ReactFeatureFlags = require('shared/ReactFeatureFlags');
48 - ReactFeatureFlags.enableEventAPI = true;
49 - React = require('react');
50 - ReactDOM = require('react-dom');
51 - Focus = require('react-events/focus');
55 + modulesInit();
56
57 container = document.createElement('div');
58 document.body.appendChild(container);
@@ -107,7 +111,7 @@ describe('Focus event responder', () => {
111 describe('onFocus', () => {
112 let onFocus, ref, innerRef;
113
110 - beforeEach(() => {
114 + const componentInit = () => {
115 onFocus = jest.fn();
116 ref = React.createRef();
117 innerRef = React.createRef();
@@ -119,7 +123,9 @@ describe('Focus event responder', () => {
123 </Focus>
124 );
125 ReactDOM.render(element, container);
122 - });
126 + };
127 +
128 + beforeEach(componentInit);
129
130 it('is called after "focus" event', () => {
131 ref.current.dispatchEvent(createFocusEvent('focus'));
@@ -204,6 +210,30 @@ describe('Focus event responder', () => {
210 expect.objectContaining({pointerType: 'keyboard'}),
211 );
212 });
213 +
214 + it('is called with the correct pointerType using Tab+altKey on Mac', () => {
215 + jest.resetModules();
216 + const platformGetter = jest.spyOn(global.navigator, 'platform', 'get');
217 + platformGetter.mockReturnValue('MacIntel');
218 + modulesInit();
219 + componentInit();
220 +
221 + ref.current.dispatchEvent(
222 + createPointerEvent('keypress', {
223 + key: 'Tab',
224 + altKey: true,
225 + }),
226 + );
227 + ref.current.dispatchEvent(createFocusEvent('focus'));
228 + expect(onFocus).toHaveBeenCalledTimes(1);
229 + expect(onFocus).toHaveBeenCalledWith(
230 + expect.objectContaining({
231 + pointerType: 'keyboard',
232 + }),
233 + );
234 +
235 + platformGetter.mockClear();
236 + });
237 });
238
239 describe('onFocusChange', () => {