fix: show number keyboard in mobile in otp forms
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user