[Masterclass] Derive autocapitalization from the keyboard type, and add an autocapitalize override - #47
Merged
Conversation
`NativeUITextInputCore` applied `.keyboardType(keyboard)` and nothing else. On iOS `keyboardType` sets the KEY LAYOUT only — it says nothing about capitalization, and an untouched SwiftUI TextField defaults to `.sentences`. So a `keyboard="email"` field showed the email keyboard (which is why the report correctly ruled out the class being ignored) and still capitalized the first letter. Nothing was broken; the behaviour was simply never wired. Two halves, matching what the issue asked for: 1. The field type carries its typing behaviour. Every keyboard kind whose content is case-sensitive or non-alphabetic — email, url, number, decimal, phone, password — resolves to `.never`. Autocorrect is disabled for the same set: iOS will otherwise "correct" an email local part into a dictionary word, which is the same bug wearing a different hat. 2. A new `autocapitalize` attribute — "none" | "sentences" | "words" | "characters", HTML's vocabulary — for what a keyboard type cannot imply (a name field wanting words, a reference code wanting characters). It overrides the derived value. Unknown values fall back to the derived behaviour rather than erroring, matching `resolveKeyboardType`. Android never had the bug — Compose's KeyboardOptions defaults to no capitalization — but it got there by accident, and `autocapitalize` had nowhere to land. It now resolves the same prop through the same rules. One deliberate asymmetry: for a plain text field with nothing specified, iOS capitalizes sentences and Android does not. `resolveCapitalization` returns NULL for that case rather than `Sentences`, leaving Compose's default alone — matching iOS there would silently start capitalizing every unclassified text field in every existing Android app, and that default is a separate decision. Android behaviour therefore changes only when the author sets `autocapitalize`, or uses a keyboard type that already implied None. Fixes NativePHP/mobile-air#304. Native changes are compile-unverified. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes NativePHP/mobile-air#304. cc @shrutibalasawebdev
Demo:
/masterclass/autocapitalizein the super-native demo app, under the Masterclass Fixes group.Cause
NativeUITextInputCoreapplied.keyboardType(keyboard)and nothing else.On iOS,
keyboardTypesets the key layout only — it says nothing about capitalization, and an untouched SwiftUITextFielddefaults to.sentences.That's exactly why @shrutibalasawebdev's report was so precise: the email keyboard did appear, so
keyboard="email"was demonstrably being applied — it just doesn't carry capitalization with it. Nothing was broken here; the behaviour was simply never wired.Fix — the two halves the issue asked for
1. The field type carries its typing behaviour.
Every keyboard kind whose content is case-sensitive or non-alphabetic —
email,url,number,decimal,phone,password— now resolves to.never.Autocorrect is disabled for the same set. A slight extension of the report, but it's the identical bug wearing a different hat: iOS will otherwise happily "correct" an email local part into a dictionary word, and the issue's own framing was that "declaring the field type should carry the capitalization behaviour with it, the same way it carries the keyboard layout."
2. A new
autocapitalizeattribute — the issue noted "there does not appear to be a separate attribute to turn autocapitalization off."none|sentences|words|characters— HTML's vocabulary. It covers what a keyboard type can't imply: a name field wantingwords, a booking reference wantingcharacters. It overrides the derived value, and unknown values fall back to the derived behaviour rather than erroring (same policy asresolveKeyboardType).Available as an attribute (
autocapitalize/autoCapitalize) and as a fluent setter.Android
Android never had the bug — Compose's
KeyboardOptionsdefaults to no capitalization — but it got the right answer by accident, andautocapitalizehad nowhere to land at all. It now resolves the same prop through the same rules, so the platforms agree by construction rather than coincidence.One deliberate asymmetry
For a plain text field with nothing specified, iOS capitalizes sentences and Android does not.
resolveCapitalizationreturns null for that case rather thanSentences, leaving Compose's default alone. Matching iOS would unify the platforms, but it would also silently start capitalizing every unclassified text field in every existing Android app — that default deserves its own decision, not a side effect of this fix.So Android behaviour changes only when the author sets⚠️ section in the demo.
autocapitalize, or uses a keyboard type that already impliedNone. It's the oneTesting
🤖 Generated with Claude Code