Repository navigation
Compose Android keyboardType and secureTextEntry into one input type - #59014
YevheniiKotyrlo wants to merge 1 commit into
Conversation
2ed43b6 to
37c74f0
Compare
keyboardType and secureTextEntry both write the class and variation of the
staged input type, each with bit edits applied in the order the props
arrive. A variation is a value within its class, not a set of flags: 0x10
is TYPE_TEXT_VARIATION_URI in the text class and
TYPE_NUMBER_VARIATION_PASSWORD in the number class. Depending on that
order:
- secureTextEntry={false} clears the url and visible-password variations.
- email-address with secureTextEntry commits
TYPE_TEXT_VARIATION_WEB_EDIT_TEXT, which is not masked.
- secureTextEntry set after autoCapitalize="words" or "characters" commits
text + URI, which is not masked, because checkPasswordType reads the
capitalization flags as the number flags they share bits with.
- Changing keyboardType keeps the previous variation (url then
email-address commits EMAIL_SUBJECT) and the previous number flags.
- phone-pad with secureTextEntry commits a variation the phone class does
not define.
Both setters now only stage their value, and onAfterUpdateTransaction
resolves the class and variation once, before reconcileAutoCapitalize
reads the class, the way autoCapitalize is already deferred. A secure field
takes the password variation of its class, and a class without one keeps
its keyboard.
37c74f0 to
51fe758
Compare
Device evidence — before / afterUNFIXED — On FIXED — With this PR, both stay masked, like field 1 (
Galaxy S23, Android 14 (API 34), RNTester release builds (New Architecture, Hermes) with #59691's reproducer screen as the root component, each frame taken after Show, then Hide. With each field focused, |


Summary:
Fixes #59691.
keyboardTypeandsecureTextEntryboth write the class and variation of the staged input type, each with bit edits applied in the order the props arrive. A variation is a value within its class rather than a set of flags (0x10isTYPE_TEXT_VARIATION_URIin the text class andTYPE_NUMBER_VARIATION_PASSWORDin the number class), so the committed input type depends on that order:secureTextEntry={false}clears theurlandvisible-passwordvariations.email-addresswithsecureTextEntrycommitsTYPE_TEXT_VARIATION_WEB_EDIT_TEXT, whichTextViewdoes not mask.secureTextEntryset afterautoCapitalize="words"or"characters"commits text + URI, whichTextViewdoes not mask either:checkPasswordTypereads the capitalization flags as the number flags they share bits with (🐛 [Android][TextInput] when combine secureTextEntry + autoCapitalize props #28709).keyboardTypekeeps the previous variation and number flags:urlthenemail-addresscommitsTYPE_TEXT_VARIATION_EMAIL_SUBJECT(Changing TextInput keyboardType from visible-password does not unset the underlying flags (Android) #17248), andnumericthennumber-padkeeps the signed decimal keys.phone-padwithsecureTextEntrycommits a variation the phone class does not define.Both setters now only stage their value, and
onAfterUpdateTransactionresolves the class and variation once, beforereconcileAutoCapitalizereads the class, the same deferralautoCapitalizealready uses. A secure field takes its class's password variation; a class without one keeps its keyboard, sophone-padstays unmasked as before.Changelog:
[ANDROID] [FIXED] - Fix keyboardType and secureTextEntry overwriting each other's input type
Test Plan:
Seven cases in
ReactTextInputPropertyTest; the order-dependent ones apply the two setters in both orders within one transaction. Onmain, six fail (first failure of each):testSecureTextEntryFalseKeepsTheKeyboardVariationInEitherPropOrder(url, keyboard first)0x110x01testSecureTextEntryMasksEveryTextKeyboardInEitherPropOrder(email-address)0x810xA1testSecureTextEntryStaysMaskedWithWordCapitalization0x810x11testChangingTheKeyboardTypeReplacesItsVariationAndNumberFlags0x210x31testRevealingAPasswordRestoresTheKeyboardVariation0x110x01testSecureTextEntryLeavesAKeyboardWithNoPasswordVariationAsItIs0x030x13testSecureTextEntryUsesTheNumberPasswordForNumberKeyboardspasses before and after; giving number keyboards the text password makes it fail alone../gradlew :packages:react-native:ReactAndroid:testDebugUnitTest -PenableWarningsAsErrors=trueforReactTextInputPropertyTest,ReactEditTextKeyEventTestandReactEditTextOutlineTest: 44 tests, 0 failures.scripts/format-kotlin.jsruns it, leaves the three files unchanged.secureTextEntry={false}: on a Galaxy S23 (Android 14) the focused editor'sEditorInforeadsTYPE_CLASS_TEXTwithTYPE_TEXT_VARIATION_URIforkeyboardType="url"and withTYPE_TEXT_VARIATION_VISIBLE_PASSWORDforkeyboardType="visible-password"; without it,visible-passwordreadTYPE_NULLwith no variation.mainand keeps them masked with this PR, in RNTester release builds: before/after.build_android).