Skip to content

Commit f2e9166

Browse files
committed
fix(input-otp): properly handle autofill and remove outdated code
1 parent 7de81ee commit f2e9166

File tree

2 files changed

+25
-31
lines changed

2 files changed

+25
-31
lines changed

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

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -617,54 +617,36 @@ export class InputOTP implements ComponentInterface {
617617
};
618618

619619
private onInput = (index: number) => (event: InputEvent) => {
620-
const { validKeyPattern } = this;
621-
620+
const { length, validKeyPattern } = this;
622621
const value = (event.target as HTMLInputElement).value;
623622

624-
// If the value is longer than 1 character, it's likely from
625-
// autofill, so we need to split the value up
623+
// If the value is longer than 1 character (autofill), split it into
624+
// characters and filter out invalid ones
626625
if (value.length > 1) {
627-
const chars = value.split('').slice(0, this.length);
628-
chars.forEach((char, index) => {
629-
if (this.validKeyPattern.test(char)) {
630-
this.inputRefs[index].value = char;
631-
this.inputValues[index] = char;
632-
}
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;
633630
});
634631
this.value = chars.join('');
635632
this.updateValue(event);
636633
return;
637634
}
638635

639-
// Only allow input if it's a single character and matches the pattern
640-
if (value.length > 1 || (value.length > 0 && !validKeyPattern.test(value))) {
641-
// Reset the input value if not valid
636+
// Only allow input if it matches the pattern
637+
if (value.length > 0 && !validKeyPattern.test(value)) {
642638
this.inputRefs[index].value = '';
643639
this.inputValues[index] = '';
644640
return;
645641
}
646642

647-
// Find the first empty box before or at the current index
648-
let targetIndex = index;
649-
for (let i = 0; i < index; i++) {
650-
if (!this.inputValues[i] || this.inputValues[i] === '') {
651-
targetIndex = i;
652-
break;
653-
}
654-
}
655-
656-
// Set the value at the target index
657-
this.inputValues[targetIndex] = value;
658-
659-
// If the value was entered in a later box, clear the current box
660-
if (targetIndex !== index) {
661-
this.inputRefs[index].value = '';
662-
}
643+
// For single character input, fill the current box
644+
this.inputValues[index] = value;
645+
this.updateValue(event);
663646

664647
if (value.length > 0) {
665-
this.focusNext(targetIndex);
648+
this.focusNext(index);
666649
}
667-
this.updateValue(event);
668650
};
669651

670652
/**

core/src/components/input-otp/test/basic/input-otp.e2e.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,18 @@ configs({ modes: ['ios'] }).forEach(({ title, config }) => {
668668

669669
await verifyInputValues(inputOtp, ['1', '2', '3', '4']);
670670
});
671+
672+
test('should paste mixed language text into all input boxes', async ({ page }) => {
673+
await page.setContent(`<ion-input-otp type="text" length="6">Description</ion-input-otp>`, config);
674+
675+
const firstInput = page.locator('ion-input-otp input').first();
676+
await firstInput.focus();
677+
await simulatePaste(firstInput, 'أبجد123');
678+
679+
const inputOtp = page.locator('ion-input-otp');
680+
681+
await verifyInputValues(inputOtp, ['أ', 'ب', 'ج', 'د', '1', '2']);
682+
});
671683
});
672684
});
673685

0 commit comments

Comments
 (0)