Skip to content

Commit 2a337e4

Browse files
committed
fix(input-otp): handle invalid patterns with autofill and moving focus
1 parent 2f38c47 commit 2a337e4

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

core/src/components/input-otp/input-otp.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -623,13 +623,34 @@ export class InputOTP implements ComponentInterface {
623623
// If the value is longer than 1 character (autofill), split it into
624624
// characters and filter out invalid ones
625625
if (value.length > 1) {
626-
const chars = value.split('').filter((char) => validKeyPattern.test(char)).slice(0, length);
627-
chars.forEach((char, i) => {
628-
this.inputRefs[i].value = char;
629-
this.inputValues[i] = char;
630-
});
631-
this.value = chars.join('');
626+
const validChars = value
627+
.split('')
628+
.filter((char) => validKeyPattern.test(char))
629+
.slice(0, length);
630+
631+
// If there are no valid characters coming from the
632+
// autofill, all input refs have to be cleared after the
633+
// browser has finished the autofill behavior
634+
if (validChars.length === 0) {
635+
requestAnimationFrame(() => {
636+
this.inputRefs.forEach((input) => {
637+
input.value = '';
638+
});
639+
});
640+
}
641+
642+
// Update the value of the input group and emit the input change event
643+
this.value = validChars.join('');
632644
this.updateValue(event);
645+
646+
// Focus the first empty input box or the last input box if all boxes
647+
// are filled after a small delay to ensure the input boxes have been
648+
// updated before moving the focus
649+
setTimeout(() => {
650+
const nextIndex = validChars.length < length ? validChars.length : length - 1;
651+
this.inputRefs[nextIndex]?.focus();
652+
}, 20);
653+
633654
return;
634655
}
635656

0 commit comments

Comments
 (0)