ComponentsForm
Phone Input
An international phone number input with country code selection, geo-IP detection, format-as-you-type, and validation.
Default
With onChange
Sizes
Disabled
Installation
npx visor add phone-inputThis copies three files into your project:
components/ui/phone-input/phone-input.tsx— the componentcomponents/ui/phone-input/phone-input.css— global theme overrides for intl-tel-inputcomponents/ui/phone-input/phone-input.module.css— wrapper styles
It also installs intl-tel-input as a dependency.
Important: Import the global CSS file in your app layout or entry point:
import '@/components/ui/phone-input/phone-input.css';Usage
import { PhoneInput } from '@/components/ui/phone-input/phone-input';
function MyForm() {
const [phone, setPhone] = useState('');
const [isValid, setIsValid] = useState(false);
return (
<PhoneInput
name="phone"
onChange={(value, valid) => {
setPhone(value);
setIsValid(valid);
}}
/>
);
}API Reference
PhoneInputProps
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | HTML id attribute for the input element. |
name | string | — | HTML name attribute for the input element. |
value | string | — | Initial phone number value (e.g. "+14155551234"). |
placeholder | string | — | Placeholder text for the input. |
required | boolean | false | Whether the field is required. |
disabled | boolean | false | Whether the field is disabled. |
className | string | — | Additional CSS classes applied to the wrapper. |
onChange | (value: string, isValid: boolean) => void | — | Called with the full international number and validation status on every change. |
onBlur | () => void | — | Called when the input loses focus. |
Features
- Country code selection — searchable dropdown with all countries and dial codes
- Geo-IP detection — auto-detects user's country on mount with US fallback
- Format-as-you-type — applies per-country formatting rules as users type
- Validation — powered by libphonenumber, returns validation status via
onChange - SSR-safe — renders a basic
<input type="tel">during server render, hydrates with full functionality on mount
CSS Import
The component requires a global CSS import for the intl-tel-input dropdown theming. This file overrides the library's default styles with Visor design tokens:
// In your layout.tsx or _app.tsx
import '@/components/ui/phone-input/phone-input.css';The CSS is global (not a CSS Module) because intl-tel-input renders its dropdown via document.body, outside React's component tree.
Accessibility
- Renders a native
<input>withtype="tel"andautocomplete="tel"for appropriate mobile keyboard and autofill - Always pair with a
<Label>usinghtmlFor/id, or providearia-labeldirectly - The country dropdown supports keyboard navigation and search
- Focus is maintained during parent re-renders (callback refs pattern)