242 countries, SVG flags drawn by a 2 KB engine, as-you-type formatting, E.164 out. Zero dependencies — every card below is live.
<script src="https://cdn.jsdelivr.net/gh/vanilla-ui-kit/components/phone/phone.js"></script>
new PhoneInput('#phone', { country: 'ae' })
Type a number — the parsed value updates on every keystroke.
new PhoneInput('#basic', {
country: 'us',
onChange: v => show(v) // {e164, national, country, valid}
})
Pin the markets you serve to the top of the dropdown.
new PhoneInput('#preferred', {
country: 'ae',
preferredCountries: ['ae','sa','kw','qa','bh','om']
})
Paste (or click to paste) an international number — the flag follows the dial code.
// typing '+9715…' switches the flag to 🇦🇪 // longest-prefix match, +1/+7/+44 area-aware
validate: 'blur' (default) waits until you leave the field;
'live' judges every keystroke.
new PhoneInput('#a', { validate: 'blur' }) // Maz-style
new PhoneInput('#b', { validate: 'live',
onValidityChange: ok => … })
Container mode builds the control and a hidden named input
carrying the E.164 value.
<div id="form-phone"></div>
new PhoneInput('#form-phone', { name: 'phone' })
// <input type="hidden" name="phone" value="+9715…">
Same value, two displays — output is always E.164 either way.
new PhoneInput('#a', { nationalMode: true })
// shows 050 123 4567
new PhoneInput('#b', { nationalMode: false })
// shows +971 50 123 4567