Conversation
…inputs No input in any of the three UI packages set an autocomplete hint, so browsers and password managers had nothing to work with and Edge reported autofill issues on the sign-in and sign-up forms. React and shadcn already spread arbitrary input props, so those only needed the attribute at each call site. Angular's FormInputComponent hardcoded its input bindings with no passthrough, so it now takes an `autocomplete` input and binds it as an attribute, absent rather than empty when unset. Values follow web.dev, which splits its guidance by form: `username` and `current-password` on sign-in, `email` and `new-password` on sign-up, `email` on the email-link and forgot-password forms, `name` on the sign-up display name, `tel` on phone fields, and `one-time-code` on verification codes. The MFA enrollment display name is the second factor's nickname rather than the person's name, so it gets `off` to stop browsers filling a real name into a factor label. The shadcn OTP fields are untouched because input-otp already defaults to `one-time-code`. Also fixes an angular parity bug on the same lines: the email-link and forgot-password forms never passed `type`, so they rendered as plain text inputs while their react counterparts rendered `type="email"`.
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces standard HTML autocomplete attributes (such as 'email', 'username', 'current-password', 'new-password', 'tel', 'one-time-code', and 'off') to various authentication form inputs across the Angular, React, and Shadcn packages. These changes improve accessibility, user experience, and integration with browser autofill features and password managers. Corresponding unit tests have been updated to verify the presence of these attributes. There are no review comments, and the changes look solid, so I have no additional feedback to provide.
FormInputComponent declared no inputs for placeholder or maxlength, so the `placeholder="123456"` and `maxlength="6"` on the TOTP assertion form landed on the fui-form-input host element and never reached the `<input>`. React's equivalent form rendered both, so angular users got neither the hint nor the length cap. The existing spec hid this. `getByPlaceholderText` matched the host element and passed while the inner input had no placeholder at all, so the assertion now reads the attributes off the input itself. Both attributes are bound with `[attr.*]`, so they stay absent when unset. Also extends the autocomplete attributes to the shadcn example app, which keeps its own copies of the forms with no sync script back to the registry.
The sign-up identifier was `email` and the sign-in identifier was `username`, so the same field carried two different tokens in one library. `email` is not a token credential managers key on to identify the account-name field, which left the account-name half of the `new-password` pairing to heuristics: where they miss, the credential saves with no account name and is then not offered back on sign-in. Apple's Password AutoFill docs cover this case directly, saying to set `autocomplete="username"` with `type="email"` when the site uses email addresses as user names, and Chromium's form-styles document uses `username` on the identifier for sign-in and sign-up alike. Forgot-password follows for the same reason, since the user is naming an existing account there. The email-link form keeps `email`. No password credential exists in a passwordless flow, so there is nothing for a manager to pair.
The new `autocomplete`, `placeholder` and `maxlength` inputs are bound with `[attr.*]`, so an unset input drops the attribute instead of rendering a literal "undefined". Nothing pinned that, and it is the one way the binding could regress silently. Verified the assertion is not vacuous: swapping `[attr.autocomplete]` for interpolation fails it.
demolaf
marked this pull request as ready for review
September 21, 2026 15:56
The email-link identifier was the last one left on `email`, which contradicted the reasoning behind the other three. It names the same account as sign-in, so a credential saved at sign-up was keyed on `username` while this form asked the browser for an address-book email, and the saved account was not offered back. The earlier justification, that no password credential exists in a passwordless flow, was about the absent password field rather than the identifier, so it did not apply.
russellwheatley
approved these changes
Sep 22, 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.
Closes #1493.
Adds
autocompleteattributes to every email, password, phone and verification-code input across the React, Angular and shadcn packages, plus the shadcn example app, which keeps its own copies of the forms. None of them set the attribute before, so browsers and password managers had nothing to identify the fields with and Edge flagged autofill problems on the sign-in and sign-up forms.Changes
usernameon every email identifier field,current-passwordon sign-in,new-passwordon sign-up,nameon the sign-up display name,telon phone fields,one-time-codeon verification codes, andoffon MFA enrollment display names, which are factor nicknames rather than the person's nameFormInputComponenttakes internalautocomplete,placeholderandmaxlengthinputs, since unlike React and shadcn it does not spread arbitrary input props; this also fixes the TOTP assertion form, whoseplaceholder="123456"andmaxlength="6"previously landed on the host element and never reached the inputtype="email"to match React and shadcn, so native constraint validation fires on submit there and the browser's untranslated bubble pre-empts the library's localisedinvalidEmailmessageWhy username and not email
usernameis the token credential managers key on to identify the account-name field andemailis not, so marking an identifieremailleaves the account-name half of thenew-passwordpairing to browser heuristics; where those miss, the credential is saved with no account name and is never offered back on sign-in. Every form naming an account uses it, so the token stays consistent wherever a credential is saved or looked up.Apple's Password AutoFill guidance says to set
autocomplete="username"withtype="email"when a site uses email addresses as user names, and Chromium's form-styles document usesusernameon the identifier for sign-in and sign-up alike. This issue asked foremailon sign-up, so these values deviate from the request.