From 67219ec72af60d48aeb041d7f0491fc4b1b180ae Mon Sep 17 00:00:00 2001 From: Jason Zheng Date: Tue, 27 Oct 2026 23:24:27 -0700 Subject: [PATCH 1/2] Add auto-expanding multiline TextInput example to RNTester (#59416) Summary: Add a new RNTester example in TextInputSharedExamples to reproduce iOS and Android issues with auto-expanding multiline text fields. There is already an existing example, but an empty, uncontrolled variant is needed to reproduce certain issues. An existing iOS-only auto-expanding example is removed as well since it duplicates functionality. Changelog: [Internal] Differential Revision: D127048669 --- .../examples/TextInput/TextInputExample.ios.js | 17 ----------------- .../TextInput/TextInputSharedExamples.js | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js b/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js index a6bcda4ec182..b768aff875ed 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js @@ -778,23 +778,6 @@ const textInputExamples: Array = [ ); }, }, - { - title: 'Auto-expanding', - render: function (): React.Node { - return ( - - - - ); - }, - }, { title: 'TextInput maxLength', render: function (): React.Node { diff --git a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js index 795ea66911ea..60df3a252499 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js @@ -1192,6 +1192,20 @@ module.exports = [ ); }, }, + { + title: 'Auto-expanding (uncontrolled)', + render: function (): React.Node { + return ( + + + + ); + }, + }, { title: 'Drag and drop', render: function (): React.Node { From ea42d2b0b8c66b773fa3ec3fb2e2adb1965bf832 Mon Sep 17 00:00:00 2001 From: Jason Zheng Date: Tue, 27 Oct 2026 23:24:27 -0700 Subject: [PATCH 2/2] Fix uncontrolled multiline TextInput not expanding on iOS (#59417) Summary: Fixes an issue where on iOS, multiline expanding TextInputs do not expand if the input starts off as empty and uncontrolled. ### Root Cause When a multiline TextInput on iOS is provided a `value` and `onChange()` prop, as shown in the [React Native docs](https://reactnative.dev/docs/textinput), the input grows as expected. However, uncontrolled inputs do not grow past the first initial line. On mount, `BaseTextInputShadowNode::updateStateIfNeeded()` writes state only if the text changes, so the first state write is skipped for empty, uncontrolled inputs. As a result, `TextAttributes` keeps the default `fontSizeMultiplier = NaN` which is carried over since iOS copies the previous state for subsequent keystrokes. During measurement, `attributedStringBoxToMeasure()` sees that the current multiplier doesn't match the stored multiplier of NaN and falls back to `props.text` which is empty for uncontrolled inputs. This causes the input to stay one-line tall. ### This PR Modify `BaseTextInputShadowNode::updateStateIfNeeded()` to update the state if base text attributes differ. On mount, the default font multiplier of NaN now differs from the real multiplier, so a state update occurs and the text field grows normally. Changelog: [iOS][Fixed] - Fix multiline TextInput not growing with its content when uncontrolled and initially empty Reviewed By: vzaidman Differential Revision: D127048714 --- .../renderer/components/textinput/BaseTextInputShadowNode.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputShadowNode.h index 42cf11b0695f..fe0caaec6097 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputShadowNode.h @@ -157,7 +157,9 @@ class BaseTextInputShadowNode const auto &stateData = BaseShadowNode::getStateData(); const auto &reactTreeAttributedString = getAttributedString(layoutContext); - if (stateData.reactTreeAttributedString.isContentEqual(reactTreeAttributedString)) { + if (stateData.reactTreeAttributedString.isContentEqual(reactTreeAttributedString) && + stateData.reactTreeAttributedString.getBaseTextAttributes() == + reactTreeAttributedString.getBaseTextAttributes()) { return; }