mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-22 22:44:52 +00:00
Reorganize usePressEvents and PressResponder
This commit is contained in:
@@ -10,13 +10,13 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import type { PressResponderConfig } from '../../modules/PressResponder';
|
||||
import type { PressResponderConfig } from '../../hooks/usePressEvents/PressResponder';
|
||||
import type { ViewProps } from '../View';
|
||||
|
||||
import * as React from 'react';
|
||||
import { forwardRef, memo, useMemo, useState, useRef } from 'react';
|
||||
import setAndForwardRef from '../../modules/setAndForwardRef';
|
||||
import usePressEvents from '../../modules/PressResponder/usePressEvents';
|
||||
import usePressEvents from '../../hooks/usePressEvents';
|
||||
import View from '../View';
|
||||
|
||||
export type StateCallbackType = $ReadOnly<{|
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { ViewProps } from '../View';
|
||||
|
||||
import * as React from 'react';
|
||||
import { useCallback, useMemo, useState, useRef } from 'react';
|
||||
import usePressEvents from '../../modules/PressResponder/usePressEvents';
|
||||
import usePressEvents from '../../hooks/usePressEvents';
|
||||
import setAndForwardRef from '../../modules/setAndForwardRef';
|
||||
import StyleSheet from '../StyleSheet';
|
||||
import View from '../View';
|
||||
|
||||
@@ -15,7 +15,7 @@ import type { ViewProps } from '../View';
|
||||
|
||||
import * as React from 'react';
|
||||
import { useCallback, useMemo, useState, useRef } from 'react';
|
||||
import usePressEvents from '../../modules/PressResponder/usePressEvents';
|
||||
import usePressEvents from '../../hooks/usePressEvents';
|
||||
import setAndForwardRef from '../../modules/setAndForwardRef';
|
||||
import StyleSheet from '../StyleSheet';
|
||||
import View from '../View';
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import type { PressResponderConfig } from '../../modules/PressResponder';
|
||||
import type { PressResponderConfig } from '../../hooks/usePressEvents/PressResponder';
|
||||
import type { ViewProps } from '../View';
|
||||
|
||||
import * as React from 'react';
|
||||
import { useMemo, useRef } from 'react';
|
||||
import pick from '../../modules/pick';
|
||||
import setAndForwardRef from '../../modules/setAndForwardRef';
|
||||
import usePressEvents from '../../modules/PressResponder/usePressEvents';
|
||||
import usePressEvents from '../../hooks/usePressEvents';
|
||||
|
||||
export type Props = $ReadOnly<{|
|
||||
accessibilityLabel?: $PropertyType<ViewProps, 'accessibilityLabel'>,
|
||||
|
||||
+23
-15
@@ -11,6 +11,8 @@
|
||||
'use strict';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import isLink from '../../modules/isLink';
|
||||
import isSelectionValid from '../../modules/isSelectionValid';
|
||||
|
||||
type ClickEvent = any;
|
||||
type KeyboardEvent = any;
|
||||
@@ -129,6 +131,11 @@ const isPressStartSignal = signal =>
|
||||
|
||||
const isTerminalSignal = signal => signal === RESPONDER_TERMINATED || signal === RESPONDER_RELEASE;
|
||||
|
||||
const isKeyPress = event => {
|
||||
const target = event.currentTarget;
|
||||
return (!isLink(target) && event.key === ' ') || event.key === 'Enter';
|
||||
};
|
||||
|
||||
const DEFAULT_LONG_PRESS_DELAY_MS = 450; // 500 - 50
|
||||
const DEFAULT_PRESS_DELAY_MS = 50;
|
||||
|
||||
@@ -299,21 +306,19 @@ export default class PressResponder {
|
||||
},
|
||||
|
||||
onKeyDown: event => {
|
||||
if (this._touchState === NOT_RESPONDER) {
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
if (isKeyPress(event)) {
|
||||
if (this._touchState === NOT_RESPONDER) {
|
||||
start(event, false);
|
||||
}
|
||||
}
|
||||
if (this._responderID) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
onKeyUp: event => {
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
if (isKeyPress(event)) {
|
||||
end(event);
|
||||
event.stopPropagation();
|
||||
}
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
onResponderGrant: event => start(event),
|
||||
@@ -356,7 +361,7 @@ export default class PressResponder {
|
||||
return cancelable;
|
||||
},
|
||||
|
||||
// NOTE: this diverges from react-native@0.62 in 2 significant ways
|
||||
// NOTE: this diverges from react-native in 3 significant ways:
|
||||
// * The `onPress` callback is not connected to the responder system (the native
|
||||
// `click` event must be used but is dispatched in many scenarios where no pointers
|
||||
// are on the screen.) Therefore, it's possible for `onPress` to be called without
|
||||
@@ -367,14 +372,15 @@ export default class PressResponder {
|
||||
onClick: (event: any): void => {
|
||||
const { disabled, onPress } = this._config;
|
||||
if (!disabled) {
|
||||
if (event.nativeEvent.__responderStoppedPropagation !== true) {
|
||||
if (this._longPressDispatched) {
|
||||
event.preventDefault();
|
||||
} else if (event.ctrlKey === false && event.altKey === false && onPress != null) {
|
||||
onPress(event);
|
||||
}
|
||||
event.nativeEvent.__responderStoppedPropagation = true;
|
||||
// If long press dispatched, cancel default click behavior.
|
||||
// If text is selected it means the user selected text during the gesture,
|
||||
// cancel default click behavior.
|
||||
if (this._longPressDispatched || isSelectionValid()) {
|
||||
event.preventDefault();
|
||||
} else if (onPress != null && event.ctrlKey === false && event.altKey === false) {
|
||||
onPress(event);
|
||||
}
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -433,7 +439,9 @@ export default class PressResponder {
|
||||
|
||||
if (isPressStartSignal(prevState) && signal === LONG_PRESS_DETECTED) {
|
||||
const { onLongPress } = this._config;
|
||||
if (onLongPress != null) {
|
||||
// Long press is not supported for keyboards because 'click' can be dispatched
|
||||
// immediately (and multiple times) after 'keydown'.
|
||||
if (onLongPress != null && event.nativeEvent.key == null) {
|
||||
onLongPress(event);
|
||||
this._longPressDispatched = true;
|
||||
}
|
||||
+6
-2
@@ -10,8 +10,10 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import PressResponder, { type EventHandlers, type PressResponderConfig } from './index';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import type { EventHandlers, PressResponderConfig } from './PressResponder';
|
||||
|
||||
import PressResponder from './PressResponder';
|
||||
import { useDebugValue, useEffect, useRef } from 'react';
|
||||
|
||||
export default function usePressEvents(hostRef: any, config: PressResponderConfig): EventHandlers {
|
||||
const pressResponderRef = useRef<?PressResponder>(null);
|
||||
@@ -33,5 +35,7 @@ export default function usePressEvents(hostRef: any, config: PressResponderConfi
|
||||
};
|
||||
}, [pressResponder]);
|
||||
|
||||
useDebugValue(config);
|
||||
|
||||
return pressResponder.getEventHandlers();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 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