Skip to content

[Masterclass] Derive autocapitalization from the keyboard type, and add an autocapitalize override - #47

Merged
shanerbaner82 merged 1 commit into
mainfrom
fix/masterclass-304-autocapitalize
Aug 11, 2026
Merged

[Masterclass] Derive autocapitalization from the keyboard type, and add an autocapitalize override#47
shanerbaner82 merged 1 commit into
mainfrom
fix/masterclass-304-autocapitalize

Conversation

@shanerbaner82

Copy link
Copy Markdown
Contributor

Fixes NativePHP/mobile-air#304. cc @shrutibalasawebdev

Lives here rather than in mobile-air: the text input renderer is a plugin component. The issue is filed on mobile-air, so the cross-repo Fixes reference won't auto-close it — worth closing by hand on merge.

Demo: /masterclass/autocapitalize in the super-native demo app, under the Masterclass Fixes group.


Cause

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.

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 autocapitalize attribute — 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 wanting words, a booking reference wanting characters. It overrides the derived value, and unknown values fall back to the derived behaviour rather than erroring (same policy as resolveKeyboardType).

Available as an attribute (autocapitalize / autoCapitalize) and as a fluent setter.

Android

Android never had the bug — Compose's KeyboardOptions defaults to no capitalization — but it got the right answer by accident, and autocapitalize had 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.

resolveCapitalization returns null for that case rather than Sentences, 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 autocapitalize, or uses a keyboard type that already implied None. It's the one ⚠️ section in the demo.

Testing

  • Full suite green: 217 passed, Pint clean
  • 4 new tests, including one asserting the prop is omitted entirely when unset — an empty string must not read as an explicit choice, or the derivation in both native resolvers is bypassed
  • Covers both attribute spellings and the lower-casing normalisation

⚠️ The Swift and Kotlin changes are compile-unverified — no iOS or Android build has been run against this yet.

🤖 Generated with Claude Code

`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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Masterclass] Text input autocapitalizes first letter on iOS even with keyboard="email"

1 participant