mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-31 01:36:11 +00:00
[fix] Disabled pressables should propagate 'click' events
If a pressable is disabled it should not prevent the propagation of native 'click' events, unless the underlying DOM node has an 'aria-role' of 'button'. This emulates the native '<button>' behavior. Fix #1781
This commit is contained in:
@@ -119,6 +119,8 @@ const Transitions = Object.freeze({
|
|||||||
const isActiveSignal = signal =>
|
const isActiveSignal = signal =>
|
||||||
signal === RESPONDER_ACTIVE_PRESS_START || signal === RESPONDER_ACTIVE_LONG_PRESS_START;
|
signal === RESPONDER_ACTIVE_PRESS_START || signal === RESPONDER_ACTIVE_LONG_PRESS_START;
|
||||||
|
|
||||||
|
const isButtonRole = element => element.getAttribute('role') === 'button';
|
||||||
|
|
||||||
const isPressStartSignal = signal =>
|
const isPressStartSignal = signal =>
|
||||||
signal === RESPONDER_INACTIVE_PRESS_START ||
|
signal === RESPONDER_INACTIVE_PRESS_START ||
|
||||||
signal === RESPONDER_ACTIVE_PRESS_START ||
|
signal === RESPONDER_ACTIVE_PRESS_START ||
|
||||||
@@ -306,8 +308,11 @@ export default class PressResponder {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onStartShouldSetResponder: (): boolean => {
|
onStartShouldSetResponder: (event): boolean => {
|
||||||
const { disabled } = this._config;
|
const { disabled } = this._config;
|
||||||
|
if (disabled && isButtonRole(event.currentTarget)) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
if (disabled == null) {
|
if (disabled == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -383,23 +388,33 @@ export default class PressResponder {
|
|||||||
// If long press dispatched, cancel default click behavior.
|
// If long press dispatched, cancel default click behavior.
|
||||||
// If the responder terminated because text was selected during the gesture,
|
// If the responder terminated because text was selected during the gesture,
|
||||||
// cancel the default click behavior.
|
// cancel the default click behavior.
|
||||||
|
event.stopPropagation();
|
||||||
if (this._longPressDispatched || this._selectionTerminated) {
|
if (this._longPressDispatched || this._selectionTerminated) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
} else if (onPress != null && event.ctrlKey === false && event.altKey === false) {
|
} else if (onPress != null && event.ctrlKey === false && event.altKey === false) {
|
||||||
onPress(event);
|
onPress(event);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (isButtonRole(event.currentTarget)) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// If `onLongPress` is provided and a touch pointer is being used, prevent the
|
// If `onLongPress` is provided and a touch pointer is being used, prevent the
|
||||||
// default context menu from opening.
|
// default context menu from opening.
|
||||||
onContextMenu: (event: any): void => {
|
onContextMenu: (event: any): void => {
|
||||||
const { disabled, onLongPress } = this._config;
|
const { disabled, onLongPress } = this._config;
|
||||||
if (!disabled && onLongPress != null && this._isPointerTouch && !event.defaultPrevented) {
|
if (!disabled) {
|
||||||
event.preventDefault();
|
if (onLongPress != null && this._isPointerTouch && !event.defaultPrevented) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isButtonRole(event.currentTarget)) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user