Forms
PhoneInput
An international phone field: react-phone-number-input with Max's Input and a searchable country picker that shows flags.
Usage#
Use it for phone numbers people type themselves, such as the phone field on a public booking page.
What you provide: any react-phone-number-input prop, for example defaultCountry, international, countryCallingCodeEditable, placeholder, disabled or id. Also:
value: an E.164 string such as+33612345678.onChange(value): called with an empty string when the field is cleared.className: applied to the root, which isflex.
smartCaret is off. The booking form uses international, defaultCountry and countryCallingCodeEditable={false}.
Anatomy:
- The country button is an outline
Buttonjoined to the input:rounded-s-lg rounded-e-none border-r-0 px-3, with a flag in anh-4 w-6 rounded-sm bg-foreground/20frame and aChevronsUpDownicon. - The input is Max's
Inputwithrounded-e-lg rounded-s-none. - The picker is a 300px-wide popover holding a
Commandlist: search reads "Search country...", the list is anh-72scroll area, and each row shows the flag, the country name, the calling code intext-foreground/50, and a check on the selected country.
Behaviour: the popover is modal and closes when a country is picked. The number is formatted as you type.
Don't store the formatted display string. Store the E.164 value from onChange.
Facts#
window.DigitalCrew.PhoneInputmax-agent: src/components/ui/phone-input.tsximport { PhoneInput } from "@/components/ui/phone-input";API#
TypeScript declarations emitted from src/components/ui/phone-input.tsx.
declare const PhoneInput: any;
export { PhoneInput };Code#
The preview above, as plain React.createElement against window.DigitalCrew with realistic data. Copy it into a page that loads the bundle.
<div id="root" class="p-6"></div>
<script>
(function () {
var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
function App() {
var a = React.useState("+33612345678"), phone = a[0], setPhone = a[1];
var b = React.useState(""), phone2 = b[0], setPhone2 = b[1];
return h("div", { className: "grid max-w-sm gap-4" },
h("div", { className: "space-y-1.5" },
h(DC.Label, { htmlFor: "booking-phone" }, "Phone"),
h(DC.PhoneInput, { id: "booking-phone", international: true, defaultCountry: "FR", countryCallingCodeEditable: false, value: phone, onChange: setPhone })),
h("div", { className: "space-y-1.5" },
h(DC.Label, { htmlFor: "booking-phone-2" }, "Mobile (optional)"),
h(DC.PhoneInput, { id: "booking-phone-2", defaultCountry: "DE", placeholder: "Enter a phone number", value: phone2, onChange: setPhone2 }),
h("p", { className: "text-xs text-muted-foreground" }, "Value is stored as E.164, for example +4915112345678.")));
}
ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>