[otp field] Avoid password manager bubbles after first input (#4868)

This commit is contained in:
atomiks authored and GitHub committed 2026-05-20 22:44:50 +10:00
1 parent cc921885fb
commit be57166cea
2 files changed
+15 -2

No files matched your search

@@ -101,8 +101,8 @@ export const OTPFieldInput = React.forwardRef(function OTPFieldInput(
autoCorrect: 'off',
spellCheck: 'false',
enterKeyHint: index === length - 1 ? 'done' : 'next',
// Allow the first slot to accept a full code so browser paste/autofill can target it directly.
maxLength: index === 0 ? length : 1,
// Only the first slot has a max length to avoid password manager bubbles appearing after later inputs.
maxLength: index === 0 ? length : undefined,
tabIndex: activeIndex === index ? 0 : -1,
disabled,
form,
@@ -71,6 +71,9 @@ describe('<OTPFieldPreview />', () => {
expect(inputs.map((input) => input.value)).toEqual(['1', '2', '3', '4', '5', '6']);
expect(inputs[0]).toHaveAttribute('maxlength', '6');
inputs.slice(1).forEach((input) => {
expect(input).not.toHaveAttribute('maxlength');
});
expect(hiddenInput).toHaveValue('123456');
});
@@ -804,6 +807,16 @@ describe('<OTPFieldPreview />', () => {
expect(getValues()).toBe('123456');
});
it('replaces consecutive slots when typing multiple characters into a later input', async () => {
await render(<OTPField defaultValue="123456" />);
const inputs = screen.getAllByRole<HTMLInputElement>('textbox');
fireEvent.change(inputs[2], { target: { value: '99' } });
expect(getValues()).toBe('129956');
});
});
describe('pasting', () => {