diff --git a/packages/react-events/src/Focus.js b/packages/react-events/src/Focus.js
index a5532a0667165..b45a0459afac4 100644
--- a/packages/react-events/src/Focus.js
+++ b/packages/react-events/src/Focus.js
@@ -116,10 +116,20 @@ const FocusResponder = {
const shouldStopPropagation =
props.stopPropagation === undefined ? true : props.stopPropagation;
+ if (props.disabled) {
+ if (state.isFocused) {
+ dispatchFocusOutEvents(context, props, state);
+ state.isFocused = false;
+ state.focusTarget = null;
+ }
+ return false;
+ }
+
// Focus doesn't handle capture target events at this point
if (phase === CAPTURE_PHASE) {
return false;
}
+
switch (type) {
case 'focus': {
if (!state.isFocused) {
diff --git a/packages/react-events/src/Hover.js b/packages/react-events/src/Hover.js
index 4893adfd5319d..b8144a9ec288b 100644
--- a/packages/react-events/src/Hover.js
+++ b/packages/react-events/src/Hover.js
@@ -253,6 +253,17 @@ const HoverResponder = {
): boolean {
const {type} = event;
+ if (props.disabled) {
+ if (state.isHovered) {
+ dispatchHoverEndEvents(event, context, props, state);
+ state.ignoreEmulatedMouseEvents = false;
+ }
+ if (state.isTouched) {
+ state.isTouched = false;
+ }
+ return false;
+ }
+
// Hover doesn't handle capture target events at this point
if (event.phase === CAPTURE_PHASE) {
return false;
diff --git a/packages/react-events/src/Press.js b/packages/react-events/src/Press.js
index 457d92e0840ed..eb83f6fb68023 100644
--- a/packages/react-events/src/Press.js
+++ b/packages/react-events/src/Press.js
@@ -408,6 +408,13 @@ const PressResponder = {
): boolean {
const {phase, target, type} = event;
+ if (props.disabled) {
+ dispatchPressEndEvents(context, props, state);
+ context.removeRootEventTypes(rootEventTypes);
+ state.ignoreEmulatedMouseEvents = false;
+ return false;
+ }
+
// Press doesn't handle capture target events at this point
if (phase === CAPTURE_PHASE) {
return false;
diff --git a/packages/react-events/src/__tests__/Focus-test.internal.js b/packages/react-events/src/__tests__/Focus-test.internal.js
index 9e7131f7b6b2b..6c575e1add49f 100644
--- a/packages/react-events/src/__tests__/Focus-test.internal.js
+++ b/packages/react-events/src/__tests__/Focus-test.internal.js
@@ -40,6 +40,29 @@ describe('Focus event responder', () => {
container = null;
});
+ describe('disabled', () => {
+ let onBlur, onFocus, ref;
+
+ beforeEach(() => {
+ onBlur = jest.fn();
+ onFocus = jest.fn();
+ ref = React.createRef();
+ const element = (
+
+
+
+ );
+ ReactDOM.render(element, container);
+ });
+
+ it('prevents custom events being dispatched', () => {
+ ref.current.dispatchEvent(createFocusEvent('focus'));
+ ref.current.dispatchEvent(createFocusEvent('blur'));
+ expect(onFocus).not.toBeCalled();
+ expect(onBlur).not.toBeCalled();
+ });
+ });
+
describe('onBlur', () => {
let onBlur, ref;
diff --git a/packages/react-events/src/__tests__/Hover-test.internal.js b/packages/react-events/src/__tests__/Hover-test.internal.js
index 6076807575bd6..dc29723b65917 100644
--- a/packages/react-events/src/__tests__/Hover-test.internal.js
+++ b/packages/react-events/src/__tests__/Hover-test.internal.js
@@ -45,6 +45,32 @@ describe('Hover event responder', () => {
container = null;
});
+ describe('disabled', () => {
+ let onHoverStart, onHoverEnd, ref;
+
+ beforeEach(() => {
+ onHoverStart = jest.fn();
+ onHoverEnd = jest.fn();
+ ref = React.createRef();
+ const element = (
+
+
+
+ );
+ ReactDOM.render(element, container);
+ });
+
+ it('prevents custom events being dispatched', () => {
+ ref.current.dispatchEvent(createPointerEvent('pointerover'));
+ ref.current.dispatchEvent(createPointerEvent('pointerout'));
+ expect(onHoverStart).not.toBeCalled();
+ expect(onHoverEnd).not.toBeCalled();
+ });
+ });
+
describe('onHoverStart', () => {
let onHoverStart, ref;
diff --git a/packages/react-events/src/__tests__/Press-test.internal.js b/packages/react-events/src/__tests__/Press-test.internal.js
index 5f1684ad33adc..550ad95eee0fe 100644
--- a/packages/react-events/src/__tests__/Press-test.internal.js
+++ b/packages/react-events/src/__tests__/Press-test.internal.js
@@ -55,6 +55,35 @@ describe('Event responder: Press', () => {
container = null;
});
+ describe('disabled', () => {
+ let onPressStart, onPress, onPressEnd, ref;
+
+ beforeEach(() => {
+ onPressStart = jest.fn();
+ onPress = jest.fn();
+ onPressEnd = jest.fn();
+ ref = React.createRef();
+ const element = (
+
+
+
+ );
+ ReactDOM.render(element, container);
+ });
+
+ it('prevents custom events being dispatched', () => {
+ ref.current.dispatchEvent(createPointerEvent('pointerdown'));
+ ref.current.dispatchEvent(createPointerEvent('pointerup'));
+ expect(onPressStart).not.toBeCalled();
+ expect(onPress).not.toBeCalled();
+ expect(onPressEnd).not.toBeCalled();
+ });
+ });
+
describe('onPressStart', () => {
let onPressStart, ref;