React events: initial implementation of disabled prop (#15458)
Nicolas Gallagher committed
Apr 21, 2019 at 18:17 UTC
587676900f5575868b2e4c2bc67755536e231c4f
6 files changed
+105
packages/react-events/src/Focus.js
+9
@@ -117,6 +117,15 @@ const FocusResponder = {
117
const shouldStopPropagation =
118
props.stopPropagation === undefined ? true : props.stopPropagation;
119
120
+ if (props.disabled) {
121
+ if (state.isFocused) {
122
+ dispatchFocusOutEvents(context, props, state);
123
+ state.isFocused = false;
124
+ state.focusTarget = null;
125
+ }
126
+ return false;
127
+ }
128
+
129
// Focus doesn't handle capture target events at this point
130
if (phase === CAPTURE_PHASE) {
131
return false;
packages/react-events/src/Hover.js
+11
@@ -253,6 +253,17 @@ const HoverResponder = {
253
): boolean {
254
const {type} = event;
255
256
+ if (props.disabled) {
257
+ if (state.isHovered) {
258
+ dispatchHoverEndEvents(event, context, props, state);
259
+ state.ignoreEmulatedMouseEvents = false;
260
+ }
261
+ if (state.isTouched) {
262
+ state.isTouched = false;
263
+ }
264
+ return false;
265
+ }
266
+
267
// Hover doesn't handle capture target events at this point
268
if (event.phase === CAPTURE_PHASE) {
269
return false;
packages/react-events/src/Press.js
+7
@@ -408,6 +408,13 @@ const PressResponder = {
408
): boolean {
409
const {phase, target, type} = event;
410
411
+ if (props.disabled) {
412
+ dispatchPressEndEvents(context, props, state);
413
+ context.removeRootEventTypes(rootEventTypes);
414
+ state.ignoreEmulatedMouseEvents = false;
415
+ return false;
416
+ }
417
+
418
// Press doesn't handle capture target events at this point
419
if (phase === CAPTURE_PHASE) {
420
return false;
packages/react-events/src/__tests__/Focus-test.internal.js
+23
@@ -40,6 +40,29 @@ describe('Focus event responder', () => {
40
container = null;
41
});
42
43
+ describe('disabled', () => {
44
+ let onBlur, onFocus, ref;
45
+
46
+ beforeEach(() => {
47
+ onBlur = jest.fn();
48
+ onFocus = jest.fn();
49
+ ref = React.createRef();
50
+ const element = (
51
+ <Focus disabled={true} onBlur={onBlur} onFocus={onFocus}>
52
+ <div ref={ref} />
53
+ </Focus>
54
+ );
55
+ ReactDOM.render(element, container);
56
+ });
57
+
58
+ it('prevents custom events being dispatched', () => {
59
+ ref.current.dispatchEvent(createFocusEvent('focus'));
60
+ ref.current.dispatchEvent(createFocusEvent('blur'));
61
+ expect(onFocus).not.toBeCalled();
62
+ expect(onBlur).not.toBeCalled();
63
+ });
64
+ });
65
+
66
describe('onBlur', () => {
67
let onBlur, ref;
68
packages/react-events/src/__tests__/Hover-test.internal.js
+26
@@ -45,6 +45,32 @@ describe('Hover event responder', () => {
45
container = null;
46
});
47
48
+ describe('disabled', () => {
49
+ let onHoverStart, onHoverEnd, ref;
50
+
51
+ beforeEach(() => {
52
+ onHoverStart = jest.fn();
53
+ onHoverEnd = jest.fn();
54
+ ref = React.createRef();
55
+ const element = (
56
+ <Hover
57
+ disabled={true}
58
+ onHoverStart={onHoverStart}
59
+ onHoverEnd={onHoverEnd}>
60
+ <div ref={ref} />
61
+ </Hover>
62
+ );
63
+ ReactDOM.render(element, container);
64
+ });
65
+
66
+ it('prevents custom events being dispatched', () => {
67
+ ref.current.dispatchEvent(createPointerEvent('pointerover'));
68
+ ref.current.dispatchEvent(createPointerEvent('pointerout'));
69
+ expect(onHoverStart).not.toBeCalled();
70
+ expect(onHoverEnd).not.toBeCalled();
71
+ });
72
+ });
73
+
74
describe('onHoverStart', () => {
75
let onHoverStart, ref;
76
packages/react-events/src/__tests__/Press-test.internal.js
+29
@@ -55,6 +55,35 @@ describe('Event responder: Press', () => {
55
container = null;
56
});
57
58
+ describe('disabled', () => {
59
+ let onPressStart, onPress, onPressEnd, ref;
60
+
61
+ beforeEach(() => {
62
+ onPressStart = jest.fn();
63
+ onPress = jest.fn();
64
+ onPressEnd = jest.fn();
65
+ ref = React.createRef();
66
+ const element = (
67
+ <Press
68
+ disabled={true}
69
+ onPressStart={onPressStart}
70
+ onPress={onPress}
71
+ onPressEnd={onPressEnd}>
72
+ <div ref={ref} />
73
+ </Press>
74
+ );
75
+ ReactDOM.render(element, container);
76
+ });
77
+
78
+ it('prevents custom events being dispatched', () => {
79
+ ref.current.dispatchEvent(createPointerEvent('pointerdown'));
80
+ ref.current.dispatchEvent(createPointerEvent('pointerup'));
81
+ expect(onPressStart).not.toBeCalled();
82
+ expect(onPress).not.toBeCalled();
83
+ expect(onPressEnd).not.toBeCalled();
84
+ });
85
+ });
86
+
87
describe('onPressStart', () => {
88
let onPressStart, ref;
89