platform-codebase/@packages/@ui/packages/ui-forms/src/PhoneInput.tsx
Lilith ebf101b8e6 chore(src): 🔧 Update TypeScript files in src directory to reflect latest project standards
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-04 15:49:44 -08:00

111 lines
2.9 KiB
TypeScript
Executable file

import type React from 'react';
import { useState } from 'react'
import type { ChangeEvent, FC } from 'react';
import { Input, Select } from '@lilith/ui-primitives';
import styled, { type DefaultTheme } from '@lilith/ui-styled-components';
import type { SelectOption } from '@lilith/ui-primitives';
export interface PhoneInputProps {
value: string;
onChange: (value: string, countryCode: string) => void;
countryCode?: string;
disabled?: boolean;
placeholder?: string;
}
const Container = styled.div`
display: flex;
gap: ${(props: { theme: DefaultTheme }) => props.theme.spacing.sm};
`;
const CountrySelect = styled(Select)`
width: 120px;
`;
const NumberInput = styled(Input)`
flex: 1;
`;
const countryCodes: SelectOption[] = [
{ value: '+1', label: '🇺🇸 +1' },
{ value: '+44', label: '🇬🇧 +44' },
{ value: '+61', label: '🇦🇺 +61' },
{ value: '+81', label: '🇯🇵 +81' },
{ value: '+86', label: '🇨🇳 +86' },
{ value: '+91', label: '🇮🇳 +91' },
{ value: '+49', label: '🇩🇪 +49' },
{ value: '+33', label: '🇫🇷 +33' },
{ value: '+39', label: '🇮🇹 +39' },
{ value: '+34', label: '🇪🇸 +34' },
{ value: '+7', label: '🇷🇺 +7' },
{ value: '+55', label: '🇧🇷 +55' },
{ value: '+52', label: '🇲🇽 +52' },
{ value: '+82', label: '🇰🇷 +82' },
];
export const PhoneInput: FC<PhoneInputProps> = ({
value,
onChange,
countryCode = '+1',
disabled = false,
placeholder = '(555) 123-4567',
}) => {
const [selectedCountryCode, setSelectedCountryCode] = useState(countryCode);
const [phoneNumber, setPhoneNumber] = useState(value);
const formatPhoneNumber = (input: string): string => {
// Remove all non-digits
const digits = input.replace(/\D/g, '');
// Format based on country code
if (selectedCountryCode === '+1') {
// US format: (XXX) XXX-XXXX
if (digits.length <= 3) {
return digits;
}
if (digits.length <= 6) {
return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
}
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
}
// Default format for other countries
return digits;
};
const handleCountryChange = (e: ChangeEvent<HTMLSelectElement>) => {
const newCode = e.target.value;
setSelectedCountryCode(newCode);
onChange(phoneNumber, newCode);
};
const handleNumberChange = (e: ChangeEvent<HTMLInputElement>) => {
const formatted = formatPhoneNumber(e.target.value);
setPhoneNumber(formatted);
onChange(formatted, selectedCountryCode);
};
return (
<Container>
<CountrySelect
value={selectedCountryCode}
onChange={handleCountryChange}
options={countryCodes}
disabled={disabled}
/>
<NumberInput
type="tel"
value={phoneNumber}
onChange={handleNumberChange}
placeholder={placeholder}
disabled={disabled}
/>
</Container>
);
};