Repository navigation
fix: allow iOS one-time-code AutoFill in OTP input - #293
Conversation
Mark the digit fields with autocomplete="one-time-code" so iOS offers the code from Mail, and accept a full code inserted into a single field instead of rejecting it via maxLength=1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
🚅 Deployed to the boop-pr-293 environment in Friends
|
There was a problem hiding this comment.
ℹ️ No critical issues. One rough edge, noted inline.
Reviewed changes
I reviewed the change that lets the 6-box OtpInput accept iOS/Android one-time-code AutoFill.
- AutoFill hint: every digit input now has
autoComplete="one-time-code", andmaxLength={1}is gone, so the OS can insert the whole code. - Full-code distribution:
handleChangestrips non-digits. When 6 or more digits arrive in one field, it takes the last 6, fills all boxes and focuses the last one. The existingdigitseffect then auto-submits. - Overwrite on type: typing into a filled box keeps
value.slice(-1)as the new digit, so the user doesn't have to delete the old one first.
The digit-by-digit typing path that tests/smoke-upgrade-journey.e2e.ts uses still works the same way.
claude-opus-5-5 | 𝕏
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
ℹ️ The earlier caret issue is fixed. One small iOS-specific suggestion inline.
Reviewed changes
I reviewed the one commit pushed since the last review.
- Select digit on focus: Each OTP box now selects its contents on focus. That way, typing or AutoFill replaces the existing digit no matter where the caret was. This resolves the
slice(-1)/slice(-OTP_LENGTH)caret-before-digit thread from the previous review.
claude-opus-5-5 | 𝕏
| onChange={(e) => handleChange(index, e)} | ||
| onKeyDown={(e) => handleKeyDown(index, e)} | ||
| // Select existing digit so typing or AutoFill replaces it regardless of caret position | ||
| onFocus={(e) => e.target.select()} |
There was a problem hiding this comment.
There are reports that select() doesn't take effect in iOS Safari, and iOS is the platform this PR targets (example). If it doesn't work, a tap on a filled box falls back to the old caret behavior. The usual workaround is setSelectionRange. Worth confirming during the on-device test in the test plan.
| onFocus={(e) => e.target.select()} | |
| onFocus={(e) => e.target.setSelectionRange(0, e.target.value.length)} |

Summary
autoComplete="one-time-code"to the OTP digit inputs so iOS offers the emailed code from Mail above the keyboard.maxLength={1}and handle a full code inserted into a single field (AutoFill inserts via input, not paste) by distributing digits across all boxes.Test plan
tscandeslintpass🤖 Generated with Claude Code