fix: show number keyboard in mobile in otp forms

This commit is contained in:
Koosha Lahouti
2025-10-06 15:46:31 +03:30
parent 18634cbf49
commit 9e42f036e4

View File

@@ -25,6 +25,10 @@ const DigitInput: React.FC<DigitInputProps> = ({
const { i18n } = useTranslation();
const inputRefs = useRef<Array<HTMLInputElement | null>>([]);
const isMobile =
typeof navigator !== 'undefined' &&
/Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
useEffect(() => {
inputRefs.current[0]?.focus();
}, []);
@@ -44,7 +48,7 @@ const DigitInput: React.FC<DigitInputProps> = ({
setCode(newCode);
handleDigitInputValueChange(newCode);
if (value && index < 4 - 1) {
if (value && index < newCode.length - 1) {
inputRefs.current[index + 1]?.focus();
}
};
@@ -53,37 +57,33 @@ const DigitInput: React.FC<DigitInputProps> = ({
event: KeyboardEvent<HTMLDivElement>,
index: number,
) => {
event.preventDefault();
if (index >= 0) {
if (event.key === 'Backspace' && code[index]) {
event.preventDefault();
handleChange('', index);
inputRefs.current[index - 1]?.focus();
if (index > 0) inputRefs.current[index - 1]?.focus();
}
};
const handlePaste = (event: React.ClipboardEvent) => {
event.preventDefault();
const pastedData = event.clipboardData.getData('text').replace(/\D/g, ''); // Remove non-digit characters
const pastedData = event.clipboardData.getData('text').replace(/\D/g, '');
const newCode = [...code];
pastedData.split('').forEach((digit, i) => {
if (i < code.length) {
newCode[i] = digit;
}
if (i < newCode.length) newCode[i] = digit;
});
setCode(newCode);
handleDigitInputValueChange(newCode);
// Focus the next empty input after the last pasted character
const lastIndex = Math.min(pastedData.length, code.length) - 1;
if (lastIndex >= 0 && inputRefs.current[lastIndex]) {
inputRefs.current[lastIndex]?.focus();
}
const nextEmpty = newCode.findIndex((d) => d === '');
const focusIndex = nextEmpty === -1 ? newCode.length - 1 : nextEmpty;
inputRefs.current[focusIndex]?.focus();
};
return (
<Stack
direction={i18n.dir() == 'ltr' ? 'row' : 'row-reverse'}
direction={i18n.dir() === 'ltr' ? 'row' : 'row-reverse'}
alignItems="center"
sx={{ gap: 2, width: '100%', my: 4 }}
justifyContent="center"
@@ -97,11 +97,18 @@ const DigitInput: React.FC<DigitInputProps> = ({
autoFocus={index === 0}
value={digit}
onChange={(e) => handleChange(e.target.value, index)}
onKeyDown={(e) => e.key === 'Backspace' && handleBackspace(e, index)}
onPaste={(e) => handlePaste(e)}
onKeyDown={(e) => handleBackspace(e, index)}
onPaste={handlePaste}
type={isMobile ? 'tel' : 'text'}
slotProps={{
htmlInput: {
maxLength: 1,
inputMode: isMobile ? 'numeric' : undefined,
pattern: isMobile ? '[0-9]*' : undefined,
autoComplete: 'one-time-code',
name: 'one-time-code',
enterKeyHint: 'done',
dir: 'ltr',
sx: {
height: '72px',
color: error