mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-25 23:48:54 +00:00
Adjust keyboard onClick shim
This commit is contained in:
@@ -153,7 +153,6 @@ function Pressable(props: Props, forwardedRef): React.Node {
|
||||
<View
|
||||
{...rest}
|
||||
{...pressEventHandlers}
|
||||
accessibilityRole={props.accessibilityRole ?? 'button'}
|
||||
accessibilityState={accessibilityState}
|
||||
accessible={accessible !== false}
|
||||
focusable={focusable !== false}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
'use strict';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import isLink from '../../modules/isLink';
|
||||
import isSelectionValid from '../../modules/isSelectionValid';
|
||||
|
||||
type ClickEvent = any;
|
||||
@@ -131,9 +130,12 @@ const isPressStartSignal = signal =>
|
||||
|
||||
const isTerminalSignal = signal => signal === RESPONDER_TERMINATED || signal === RESPONDER_RELEASE;
|
||||
|
||||
const isKeyPress = event => {
|
||||
const isValidKeyPress = event => {
|
||||
const key = event.key;
|
||||
const target = event.currentTarget;
|
||||
return (!isLink(target) && event.key === ' ') || event.key === 'Enter';
|
||||
const role = target.getAttribute('role');
|
||||
const isSpacebar = key === ' ' || key === 'Spacebar';
|
||||
return key === 'Enter' || (isSpacebar && (role === 'button' || role === 'menuitem'));
|
||||
};
|
||||
|
||||
const DEFAULT_LONG_PRESS_DELAY_MS = 450; // 500 - 50
|
||||
@@ -306,7 +308,7 @@ export default class PressResponder {
|
||||
},
|
||||
|
||||
onKeyDown: event => {
|
||||
if (isKeyPress(event)) {
|
||||
if (isValidKeyPress(event)) {
|
||||
if (this._touchState === NOT_RESPONDER) {
|
||||
start(event, false);
|
||||
}
|
||||
@@ -315,7 +317,7 @@ export default class PressResponder {
|
||||
},
|
||||
|
||||
onKeyUp: event => {
|
||||
if (isKeyPress(event)) {
|
||||
if (isValidKeyPress(event)) {
|
||||
end(event);
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
+25
-16
@@ -86,6 +86,14 @@ const createDOMProps = (component, props, styleResolver) => {
|
||||
const disabled =
|
||||
(accessibilityState != null && accessibilityState.disabled === true) || providedDisabled;
|
||||
const role = AccessibilityUtil.propsToAriaRole(props);
|
||||
const isNativeInteractiveElement =
|
||||
role === 'link' ||
|
||||
component === 'a' ||
|
||||
component === 'button' ||
|
||||
component === 'input' ||
|
||||
component === 'select' ||
|
||||
component === 'textarea' ||
|
||||
domProps.contentEditable != null;
|
||||
|
||||
// unstable_ariaSet
|
||||
if (unstable_ariaSet != null) {
|
||||
@@ -176,24 +184,17 @@ const createDOMProps = (component, props, styleResolver) => {
|
||||
// FOCUS
|
||||
// Assume that 'link' is focusable by default (uses <a>).
|
||||
// Assume that 'button' is not (uses <div role='button'>) but must be treated as such.
|
||||
const isInteractiveElement =
|
||||
role === 'link' ||
|
||||
component === 'a' ||
|
||||
component === 'button' ||
|
||||
component === 'input' ||
|
||||
component === 'select' ||
|
||||
component === 'textarea';
|
||||
const focusable =
|
||||
!disabled &&
|
||||
importantForAccessibility !== 'no' &&
|
||||
importantForAccessibility !== 'no-hide-descendants';
|
||||
if (isInteractiveElement) {
|
||||
if (isNativeInteractiveElement) {
|
||||
if (accessible === false || !focusable) {
|
||||
domProps.tabIndex = '-1';
|
||||
} else {
|
||||
domProps['data-focusable'] = true;
|
||||
}
|
||||
} else if (AccessibilityUtil.buttonLikeRoles[role] || role === 'textbox') {
|
||||
} else if (role === 'button' || role === 'menuitem' || role === 'textbox') {
|
||||
if (accessible !== false && focusable) {
|
||||
domProps['data-focusable'] = true;
|
||||
domProps.tabIndex = '0';
|
||||
@@ -252,22 +253,30 @@ const createDOMProps = (component, props, styleResolver) => {
|
||||
}
|
||||
|
||||
// Keyboard accessibility
|
||||
// Button-like roles should trigger 'onClick' if SPACE or ENTER keys are pressed.
|
||||
// Button-like roles should trigger 'onClick' if SPACE key is pressed.
|
||||
// Button-like roles should not trigger 'onClick' if they are disabled.
|
||||
if (domProps['data-focusable']) {
|
||||
const onClick = domProps.onClick;
|
||||
if (onClick != null) {
|
||||
if (disabled) {
|
||||
domProps.onClick = undefined;
|
||||
} else if (!isInteractiveElement) {
|
||||
} else if (!isNativeInteractiveElement) {
|
||||
// For native elements that are focusable but don't dispatch 'click' events
|
||||
// for keyboards.
|
||||
const onKeyDown = domProps.onKeyDown;
|
||||
domProps.onKeyDown = function(e) {
|
||||
if (!e.isDefaultPrevented() && (e.key === 'Enter' || e.key === ' ')) {
|
||||
e.preventDefault();
|
||||
if (onKeyDown != null) {
|
||||
onKeyDown(e);
|
||||
}
|
||||
const key = e.key;
|
||||
const isSpacebarKey = key === ' ' || key === 'Spacebar';
|
||||
const isButtonRole = role === 'button' || role === 'menuitem';
|
||||
if (onKeyDown != null) {
|
||||
onKeyDown(e);
|
||||
}
|
||||
if (key === 'Enter') {
|
||||
onClick(e);
|
||||
} else if (isSpacebarKey && isButtonRole) {
|
||||
onClick(e);
|
||||
// Prevent spacebar scrolling the window
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,15 +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
|
||||
*/
|
||||
|
||||
export default function isLink(node: HTMLElement) {
|
||||
return (
|
||||
(node.nodeName === 'A' && node.getAttribute('href') != null) ||
|
||||
node.getAttribute('role') === 'link'
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user