From 7775b3ab19216d4ca5e4fdfdd4206f2cfb4cf0cc Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Thu, 22 Apr 2021 12:47:10 -0700 Subject: [PATCH] [change] Remove special treatment of accessibilityRole="menuitem" This role is not meant to be in the tab flow unless the element type demands it. Users will now have to manage `onClick` and `onKeyDown` callbacks to apply the desired interaction behavior. Fix #1968 --- .../src/pages/docs/components/text-input.md | 2 +- .../AccessibilityUtil/buttonLikeRoles.js | 19 ------------------- .../src/modules/AccessibilityUtil/index.js | 2 -- .../createDOMProps/__tests__/index-test.js | 9 --------- .../src/modules/createDOMProps/index.js | 10 ++-------- .../modules/usePressEvents/PressResponder.js | 4 +--- 6 files changed, 4 insertions(+), 42 deletions(-) delete mode 100644 packages/react-native-web/src/modules/AccessibilityUtil/buttonLikeRoles.js diff --git a/packages/docs/src/pages/docs/components/text-input.md b/packages/docs/src/pages/docs/components/text-input.md index 1effd659..8eae1383 100644 --- a/packages/docs/src/pages/docs/components/text-input.md +++ b/packages/docs/src/pages/docs/components/text-input.md @@ -84,7 +84,7 @@ Equivalent to [HTMLElement.readonly](https://developer.mozilla.org/en-US/docs/We {% endcall %} {% call macro.prop('keyboardType', '?string') %} -Hints at the type of data that might be entered by the user while editing the element or its contents. Equivalent to [HTMLElement.inputMode](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode). Safari iOS requires an ancestral
element to display the search keyboard. (Not available when multiline is true.) +Hints at the type of data that might be entered by the user while editing the element or its contents. Equivalent to [HTMLElement.inputMode](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode). Safari iOS requires an ancestral `` element to display the search keyboard. (Not available when multiline is true.) {% endcall %} {% call macro.prop('lang', '?string') %} diff --git a/packages/react-native-web/src/modules/AccessibilityUtil/buttonLikeRoles.js b/packages/react-native-web/src/modules/AccessibilityUtil/buttonLikeRoles.js deleted file mode 100644 index 72e14007..00000000 --- a/packages/react-native-web/src/modules/AccessibilityUtil/buttonLikeRoles.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) Nicolas Gallagher. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -const buttonLikeRoles: { [string]: boolean } = { - // ARIA button behaves like native 'button' element - button: true, - // ARIA menuitem responds to Enter/Space like a button. Spec requires AT to - // ignore ARIA roles of any children. - // https://www.w3.org/WAI/GL/wiki/Using_ARIA_menus - menuitem: true -}; - -export default buttonLikeRoles; diff --git a/packages/react-native-web/src/modules/AccessibilityUtil/index.js b/packages/react-native-web/src/modules/AccessibilityUtil/index.js index 649ddf4d..cff742fe 100644 --- a/packages/react-native-web/src/modules/AccessibilityUtil/index.js +++ b/packages/react-native-web/src/modules/AccessibilityUtil/index.js @@ -7,13 +7,11 @@ * @flow */ -import buttonLikeRoles from './buttonLikeRoles'; import isDisabled from './isDisabled'; import propsToAccessibilityComponent from './propsToAccessibilityComponent'; import propsToAriaRole from './propsToAriaRole'; const AccessibilityUtil = { - buttonLikeRoles, isDisabled, propsToAccessibilityComponent, propsToAriaRole diff --git a/packages/react-native-web/src/modules/createDOMProps/__tests__/index-test.js b/packages/react-native-web/src/modules/createDOMProps/__tests__/index-test.js index 2055f0a8..3e35d718 100644 --- a/packages/react-native-web/src/modules/createDOMProps/__tests__/index-test.js +++ b/packages/react-native-web/src/modules/createDOMProps/__tests__/index-test.js @@ -80,10 +80,6 @@ describe('modules/createDOMProps', () => { testFocusableRole('button'); }); - describe('"accessibilityRole" of "menuitem"', () => { - testFocusableRole('menuitem'); - }); - describe('with unfocusable accessibilityRole', () => { test('when "focusable" is true', () => { expect(createProps({ focusable: true })).toEqual( @@ -116,7 +112,6 @@ describe('modules/createDOMProps', () => { expect(callsOnClick('div', 'link')).toBe(true); expect(callsOnClick('div', 'button')).toBe(true); expect(callsOnClick('div', 'textbox')).toBe(true); - expect(callsOnClick('div', 'menuitem')).toBe(true); expect(callsOnClick('div', 'bogus')).toBe(true); expect(callsOnClick('a')).toBe(true); expect(callsOnClick('button')).toBe(true); @@ -129,7 +124,6 @@ describe('modules/createDOMProps', () => { test('is not called when disabled is true', () => { expect(callsOnClick('div', 'link', true)).toBe(false); expect(callsOnClick('div', 'button', true)).toBe(false); - expect(callsOnClick('div', 'menuitem', true)).toBe(false); expect(callsOnClick('a', undefined, true)).toBe(false); expect(callsOnClick('button', undefined, true)).toBe(false); expect(callsOnClick('input', undefined, true)).toBe(false); @@ -166,7 +160,6 @@ describe('modules/createDOMProps', () => { expect(respondsToEnter('div', 'link', true)).toBe(false); expect(respondsToEnter('div', 'button', true)).toBe(false); expect(respondsToEnter('div', 'textbox', true)).toBe(false); - expect(respondsToEnter('div', 'menuitem', true)).toBe(false); expect(respondsToEnter('div', 'bogus', true)).toBe(false); }); @@ -190,7 +183,6 @@ describe('modules/createDOMProps', () => { test('emulates "onClick" for "Enter" for certain roles', () => { expect(respondsToEnter('div', 'button')).toBe(true); - expect(respondsToEnter('div', 'menuitem')).toBe(true); expect(respondsToEnter('div', 'textbox')).toBe(false); expect(respondsToEnter('div', 'bogus')).toBe(false); }); @@ -209,7 +201,6 @@ describe('modules/createDOMProps', () => { test('emulates "onClick" for "Space" for certain roles', () => { expect(respondsToSpace('div', 'button')).toBe(true); - expect(respondsToSpace('div', 'menuitem')).toBe(true); expect(respondsToSpace('div', 'textbox')).toBe(false); expect(respondsToSpace('div', 'bogus')).toBe(false); }); diff --git a/packages/react-native-web/src/modules/createDOMProps/index.js b/packages/react-native-web/src/modules/createDOMProps/index.js index 98e11c9e..d96636f4 100644 --- a/packages/react-native-web/src/modules/createDOMProps/index.js +++ b/packages/react-native-web/src/modules/createDOMProps/index.js @@ -365,7 +365,6 @@ const createDOMProps = (elementType, props) => { role === 'button' || role === 'checkbox' || role === 'link' || - role === 'menuitem' || role === 'radio' || role === 'textbox' || role === 'switch' @@ -421,12 +420,7 @@ const createDOMProps = (elementType, props) => { // Keyboard accessibility // Button-like roles should trigger 'onClick' if SPACE key is pressed. // Button-like roles should not trigger 'onClick' if they are disabled. - if ( - isNativeInteractiveElement || - role === 'button' || - role === 'menuitem' || - (_focusable === true && !disabled) - ) { + if (isNativeInteractiveElement || role === 'button' || (_focusable === true && !disabled)) { const onClick = domProps.onClick; if (onClick != null) { if (disabled) { @@ -441,7 +435,7 @@ const createDOMProps = (elementType, props) => { domProps.onKeyDown = function (e) { const { key, repeat } = e; const isSpacebarKey = key === ' ' || key === 'Spacebar'; - const isButtonRole = role === 'button' || role === 'menuitem'; + const isButtonRole = role === 'button'; if (onKeyDown != null) { onKeyDown(e); } diff --git a/packages/react-native-web/src/modules/usePressEvents/PressResponder.js b/packages/react-native-web/src/modules/usePressEvents/PressResponder.js index 9d42aa1b..e4fcfc18 100644 --- a/packages/react-native-web/src/modules/usePressEvents/PressResponder.js +++ b/packages/react-native-web/src/modules/usePressEvents/PressResponder.js @@ -134,9 +134,7 @@ const isValidKeyPress = (event) => { const target = event.currentTarget; const role = target.getAttribute('role'); const isSpacebar = key === ' ' || key === 'Spacebar'; - return ( - !event.repeat && (key === 'Enter' || (isSpacebar && (role === 'button' || role === 'menuitem'))) - ); + return !event.repeat && (key === 'Enter' || (isSpacebar && role === 'button')); }; const DEFAULT_LONG_PRESS_DELAY_MS = 450; // 500 - 50