[Native] Migrate focus/blur to call TextInputState with the host component (#18068)
Eli White committed
Feb 19, 2020 at 11:33 UTC
085d02133e9e3b24ae548d89e4003899bf85022c
5 files changed
+82
-5
packages/react-native-renderer/src/ReactFabricHostConfig.js
+2
-2
@@ -104,11 +104,11 @@ class ReactFabricHostComponent {
104
}
105
106
blur() {
107
- TextInputState.blurTextInput(this._nativeTag);
107
+ TextInputState.blurTextInput(this);
108
}
109
110
focus() {
111
- TextInputState.focusTextInput(this._nativeTag);
111
+ TextInputState.focusTextInput(this);
112
}
113
114
measure(callback: MeasureOnSuccessCallback) {
packages/react-native-renderer/src/ReactNativeFiberHostComponent.js
+2
-2
@@ -40,11 +40,11 @@ class ReactNativeFiberHostComponent {
40
}
41
42
blur() {
43
- TextInputState.blurTextInput(this._nativeTag);
43
+ TextInputState.blurTextInput(this);
44
}
45
46
focus() {
47
- TextInputState.focusTextInput(this._nativeTag);
47
+ TextInputState.focusTextInput(this);
48
}
49
50
measure(callback: MeasureOnSuccessCallback) {
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/TextInputState.js
+4
-1
@@ -10,6 +10,9 @@
10
// Mock of the Native Hooks
11
// TODO: Should this move into the components themselves? E.g. focusable
12
13
-const TextInputState = {};
13
+const TextInputState = {
14
+ blurTextInput: jest.fn(),
15
+ focusTextInput: jest.fn(),
16
+};
17
18
module.exports = TextInputState;
packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js
+37
@@ -16,6 +16,7 @@ let ReactFeatureFlags;
16
let createReactNativeComponentClass;
17
let UIManager;
18
let StrictMode;
19
+let TextInputState;
20
21
const SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE =
22
'Warning: setNativeProps is not currently supported in Fabric';
@@ -42,6 +43,8 @@ describe('ReactFabric', () => {
43
.UIManager;
44
createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
45
.ReactNativeViewConfigRegistry.register;
46
+ TextInputState = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
47
+ .TextInputState;
48
});
49
50
it('should be able to create and render a native component', () => {
@@ -991,4 +994,38 @@ describe('ReactFabric', () => {
994
]);
995
expect(match).toBe(child._nativeTag);
996
});
997
+
998
+ it('blur on host component calls TextInputState', () => {
999
+ const View = createReactNativeComponentClass('RCTView', () => ({
1000
+ validAttributes: {foo: true},
1001
+ uiViewClassName: 'RCTView',
1002
+ }));
1003
+
1004
+ let viewRef = React.createRef();
1005
+ ReactFabric.render(<View ref={viewRef} />, 11);
1006
+
1007
+ expect(TextInputState.blurTextInput).not.toBeCalled();
1008
+
1009
+ viewRef.current.blur();
1010
+
1011
+ expect(TextInputState.blurTextInput).toHaveBeenCalledTimes(1);
1012
+ expect(TextInputState.blurTextInput).toHaveBeenCalledWith(viewRef.current);
1013
+ });
1014
+
1015
+ it('focus on host component calls TextInputState', () => {
1016
+ const View = createReactNativeComponentClass('RCTView', () => ({
1017
+ validAttributes: {foo: true},
1018
+ uiViewClassName: 'RCTView',
1019
+ }));
1020
+
1021
+ let viewRef = React.createRef();
1022
+ ReactFabric.render(<View ref={viewRef} />, 11);
1023
+
1024
+ expect(TextInputState.focusTextInput).not.toBeCalled();
1025
+
1026
+ viewRef.current.focus();
1027
+
1028
+ expect(TextInputState.focusTextInput).toHaveBeenCalledTimes(1);
1029
+ expect(TextInputState.focusTextInput).toHaveBeenCalledWith(viewRef.current);
1030
+ });
1031
});
packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js
+37
@@ -15,6 +15,7 @@ let StrictMode;
15
let ReactNative;
16
let createReactNativeComponentClass;
17
let UIManager;
18
+let TextInputState;
19
20
const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT =
21
"Warning: dispatchCommand was called with a ref that isn't a " +
@@ -31,6 +32,8 @@ describe('ReactNative', () => {
32
.UIManager;
33
createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
34
.ReactNativeViewConfigRegistry.register;
35
+ TextInputState = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
36
+ .TextInputState;
37
});
38
39
it('should be able to create and render a native component', () => {
@@ -594,4 +597,38 @@ describe('ReactNative', () => {
597
]);
598
expect(match).toBe(child._nativeTag);
599
});
600
+
601
+ it('blur on host component calls TextInputState', () => {
602
+ const View = createReactNativeComponentClass('RCTView', () => ({
603
+ validAttributes: {foo: true},
604
+ uiViewClassName: 'RCTView',
605
+ }));
606
+
607
+ let viewRef = React.createRef();
608
+ ReactNative.render(<View ref={viewRef} />, 11);
609
+
610
+ expect(TextInputState.blurTextInput).not.toBeCalled();
611
+
612
+ viewRef.current.blur();
613
+
614
+ expect(TextInputState.blurTextInput).toHaveBeenCalledTimes(1);
615
+ expect(TextInputState.blurTextInput).toHaveBeenCalledWith(viewRef.current);
616
+ });
617
+
618
+ it('focus on host component calls TextInputState', () => {
619
+ const View = createReactNativeComponentClass('RCTView', () => ({
620
+ validAttributes: {foo: true},
621
+ uiViewClassName: 'RCTView',
622
+ }));
623
+
624
+ let viewRef = React.createRef();
625
+ ReactNative.render(<View ref={viewRef} />, 11);
626
+
627
+ expect(TextInputState.focusTextInput).not.toBeCalled();
628
+
629
+ viewRef.current.focus();
630
+
631
+ expect(TextInputState.focusTextInput).toHaveBeenCalledTimes(1);
632
+ expect(TextInputState.focusTextInput).toHaveBeenCalledWith(viewRef.current);
633
+ });
634
});