add react-input-mask

This commit is contained in:
smanylov
2025-12-29 18:47:50 +07:00
parent bd0169bd61
commit 1032c5420b
3 changed files with 54 additions and 91 deletions
+7 -89
View File
@@ -1,6 +1,7 @@
'use client'
import { useState, ChangeEvent, useEffect, useRef, KeyboardEvent } from 'react';
import { useState, ChangeEvent } from 'react';
import { InputMask } from '@react-input/mask';
import styles from '@/app/styles/module/login.module.scss';
interface PhoneInputProps {
@@ -10,104 +11,21 @@ interface PhoneInputProps {
export default function PhoneInput({ phoneState, validateHandler }: PhoneInputProps) {
const [phone, setPhone] = useState(phoneState ? phoneState : '');
const inputRef = useRef<HTMLInputElement>(null);
const formatPhoneNumber = (value: string, isBackspace: boolean): string => {
if (value === '+') {
return value;
}
const digitsOnly = value.replace(/\D/g, '');
if (!digitsOnly) {
return '';
}
const limitedDigits = digitsOnly.slice(0, 11);
const countryCode = 7;
const phoneNumber = limitedDigits.startsWith('7')
? limitedDigits.slice(1)
: limitedDigits;
let formatted = `+${countryCode}`;
if (phoneNumber.length > 0) {
formatted += ` (${phoneNumber.slice(0, 3)}`;
}
if (phoneNumber.length >= 3) {
formatted += `) ${phoneNumber.slice(3, 6)}`;
}
if (phoneNumber.length >= 6) {
formatted += `-${phoneNumber.slice(6, 8)}`;
}
if (phoneNumber.length >= 8) {
formatted += `-${phoneNumber.slice(8, 10)}`;
}
if (isBackspace) {
const lastChar = formatted[formatted.length - 1];
const specialChars = ['-', '(', ')', ' '];
if (specialChars.includes(lastChar)) {
if (lastChar === ' ' && formatted[formatted.length - 2] === ')') {
return formatted.slice(0, -2);
}
return formatted.slice(0, -1);
}
}
return formatted;
};
const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
const input = e.target.value;
const nativeEvent = e.nativeEvent as InputEvent;
const isBackspace = nativeEvent.inputType === 'deleteContentBackward';
const formatted = formatPhoneNumber(input, isBackspace);
setPhone(formatted);
};
const range = useRef<{
start: number | null,
key: string;
} | null>(null);
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {
const input = e.currentTarget;
range.current = {
start: input.selectionStart,
key: e.key
};
};
useEffect(() => {
console.log('use');
if (range.current?.key === 'Backspace' && inputRef.current) {
const startPos = range.current.start ?? 0;
const newPosition = Math.max(0, startPos - 1);
inputRef.current.setSelectionRange(newPosition, newPosition);
} else if (range.current?.key === 'Delete' && inputRef.current) {
inputRef.current.setSelectionRange(range.current.start, range.current.start);
}
}, [phone]);
return (
<input
<InputMask
type="phone"
id="phone"
name="phone"
ref={inputRef}
className={`${styles['form-input']}`}
placeholder="+7 (999) 123-45-67"
mask="+7 (___) ___-__-__"
replacement={{ _: /\d/ }}
value={phone}
onChange={(e) => {
handleChange(e);
setPhone(e.target.value);
validateHandler(e);
}}
onKeyDown={(e) => {
handleKeyDown(e);
}}
placeholder="+7 (999) 123-45-67"
/>
)
}