siakad-itm/resources/js/components/ui/phone-input.tsx

51 lines
1.5 KiB
TypeScript

import { forwardRef, useState, useEffect, useCallback } from 'react';
import { Input } from '@/components/ui/input';
function formatPhone(value: string): string {
const digits = value.replace(/\D/g, '').slice(0, 20);
return digits.replace(/(\d{4})(?=\d)/g, '$1 ').trim();
}
function unformatPhone(value: string): string {
return value.replace(/\s/g, '');
}
const PhoneInput = forwardRef<HTMLInputElement, Omit<React.ComponentProps<'input'>, 'value' | 'onChange'> & {
value?: string;
onChange?: (value: string) => void;
}>(({ value, onChange, name, ...props }, ref) => {
const [displayValue, setDisplayValue] = useState(() => formatPhone(value ?? ''));
useEffect(() => {
setDisplayValue(formatPhone(value ?? ''));
}, [value]);
const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const raw = unformatPhone(e.target.value);
const formatted = formatPhone(raw);
setDisplayValue(formatted);
onChange?.(raw);
},
[onChange],
);
return (
<>
<Input
ref={ref}
type="text"
inputMode="numeric"
value={displayValue}
onChange={handleChange}
{...props}
/>
{name && <input type="hidden" name={name} value={unformatPhone(displayValue)} />}
</>
);
});
PhoneInput.displayName = 'PhoneInput';
export { PhoneInput };