Skip to content

Commit 03897d3

Browse files
committed
[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
1 parent b8fddcf commit 03897d3

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

packages/react-native-web/src/modules/usePressEvents/PressResponder.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ const Transitions = Object.freeze({
119119
const isActiveSignal = signal =>
120120
signal === RESPONDER_ACTIVE_PRESS_START || signal === RESPONDER_ACTIVE_LONG_PRESS_START;
121121

122+
const isButtonRole = element => element.getAttribute('role') === 'button';
123+
122124
const isPressStartSignal = signal =>
123125
signal === RESPONDER_INACTIVE_PRESS_START ||
124126
signal === RESPONDER_ACTIVE_PRESS_START ||
@@ -306,8 +308,11 @@ export default class PressResponder {
306308
};
307309

308310
return {
309-
onStartShouldSetResponder: (): boolean => {
311+
onStartShouldSetResponder: (event): boolean => {
310312
const { disabled } = this._config;
313+
if (disabled && isButtonRole(event.currentTarget)) {
314+
event.stopPropagation();
315+
}
311316
if (disabled == null) {
312317
return true;
313318
}
@@ -383,23 +388,33 @@ export default class PressResponder {
383388
// If long press dispatched, cancel default click behavior.
384389
// If the responder terminated because text was selected during the gesture,
385390
// cancel the default click behavior.
391+
event.stopPropagation();
386392
if (this._longPressDispatched || this._selectionTerminated) {
387393
event.preventDefault();
388394
} else if (onPress != null && event.ctrlKey === false && event.altKey === false) {
389395
onPress(event);
390396
}
397+
} else {
398+
if (isButtonRole(event.currentTarget)) {
399+
event.stopPropagation();
400+
}
391401
}
392-
event.stopPropagation();
393402
},
394403

395404
// If `onLongPress` is provided and a touch pointer is being used, prevent the
396405
// default context menu from opening.
397406
onContextMenu: (event: any): void => {
398407
const { disabled, onLongPress } = this._config;
399-
if (!disabled && onLongPress != null && this._isPointerTouch && !event.defaultPrevented) {
400-
event.preventDefault();
408+
if (!disabled) {
409+
if (onLongPress != null && this._isPointerTouch && !event.defaultPrevented) {
410+
event.preventDefault();
411+
event.stopPropagation();
412+
}
413+
} else {
414+
if (isButtonRole(event.currentTarget)) {
415+
event.stopPropagation();
416+
}
401417
}
402-
event.stopPropagation();
403418
}
404419
};
405420
}

0 commit comments

Comments
 (0)