Skip to content

Commit

Permalink
fix attempting to focus disabled textinputs (#30695)
Browse files Browse the repository at this point in the history
Summary:
when we call `focus()` upon a TextInput ref which has prop `editable=false` it marks the textinput as focused in `TextInputState` even though the focus is rejected by textinput itself because it is not editable.

then, when you change `editable` prop to `true` and call `focus` again, [this condition](https://github.com/facebook/react-native/blob/e912c462eb0b7166ca5947bb5a3ee20761d910b6/Libraries/Components/TextInput/TextInputState.js#L46) or rather [this one](https://github.com/facebook/react-native/blob/1b2b2198e1b2383523b4655dc8c220d251b057d6/Libraries/Components/TextInput/TextInputState.js#L89) will evaluate to `false` and focus will not happen even though it can and should happen.

see also https://github.com/facebook/react-native/blob/0.64-stable/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js#L3895

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[General] [Fixed] - `focus()` on TextInput to respect its `editable` state

Pull Request resolved: #30695

Test Plan: Create a `TextInput` with prop `editable=false` and call `ref.current.focus()` upon its ref. TextInput should not be marked as focused in `TextInputState`.

Reviewed By: yungsters

Differential Revision: D34357913

Pulled By: lunaleaps

fbshipit-source-id: 9a2fb819bbb05ef213c9b5d739dec583ae0a3e6f
  • Loading branch information
vonovak authored and facebook-github-bot committed Mar 22, 2022
1 parent 83ab361 commit 8a5460c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
12 changes: 10 additions & 2 deletions Libraries/Components/TextInput/TextInputState.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function blurField(textFieldID: ?number) {
/**
* @param {number} TextInputID id of the text field to focus
* Focuses the specified text field
* noop if the text field was already focused
* noop if the text field was already focused or if the field is not editable
*/
function focusTextInput(textField: ?ComponentRef) {
if (typeof textField === 'number') {
Expand All @@ -86,7 +86,15 @@ function focusTextInput(textField: ?ComponentRef) {
return;
}

if (currentlyFocusedInputRef !== textField && textField != null) {
if (textField != null) {
const fieldCanBeFocused =
currentlyFocusedInputRef !== textField &&
// $FlowFixMe - `currentProps` is missing in `NativeMethods`
textField.currentProps?.editable !== false;

if (!fieldCanBeFocused) {
return;
}
focusInput(textField);
if (Platform.OS === 'ios') {
// This isn't necessarily a single line text input
Expand Down
21 changes: 19 additions & 2 deletions Libraries/Components/TextInput/__tests__/TextInput-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,26 @@ describe('TextInput tests', () => {
});
});

it('should have support being focused and unfocused', () => {
function createTextInput(extraProps) {
const textInputRef = React.createRef(null);
ReactTestRenderer.create(<TextInput ref={textInputRef} value="value1" />);
ReactTestRenderer.create(
<TextInput ref={textInputRef} value="value1" {...extraProps} />,
);
return textInputRef;
}

it('focus() should not do anything if the TextInput is not editable', () => {
const textInputRef = createTextInput({editable: false});
// currentProps is the property actually containing props at runtime
textInputRef.current.currentProps = textInputRef.current.props;
expect(textInputRef.current.isFocused()).toBe(false);

TextInput.State.focusTextInput(textInputRef.current);
expect(textInputRef.current.isFocused()).toBe(false);
});

it('should have support for being focused and blurred', () => {
const textInputRef = createTextInput();

expect(textInputRef.current.isFocused()).toBe(false);
ReactNative.findNodeHandle = jest.fn().mockImplementation(ref => {
Expand Down

0 comments on commit 8a5460c

Please sign in to comment.