Design
llms.txt digitalcrew.tech

Forms

PhoneInput

An international phone field: react-phone-number-input with Max's Input and a searchable country picker that shows flags.

MaxFormsDigitalCrew.PhoneInput
PhoneInput · liveOpen

Guidelines#

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 is flex.

smartCaret is off. The booking form uses international, defaultCountry and countryCallingCodeEditable={false}.

Anatomy:

  • The country button is an outline Button joined to the input: rounded-s-lg rounded-e-none border-r-0 px-3, with a flag in an h-4 w-6 rounded-sm bg-foreground/20 frame and a ChevronsUpDown icon.
  • The input is Max's Input with rounded-e-lg rounded-s-none.
  • The picker is a 300px-wide popover holding a Command list: search reads "Search country...", the list is an h-72 scroll area, and each row shows the flag, the country name, the calling code in text-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#

GroupForms
ProductMax
Globalwindow.DigitalCrew.PhoneInput
Sourcemax-agent: src/components/ui/phone-input.tsx
Import in the appimport { PhoneInput } from "@/components/ui/phone-input";

API#

TypeScript declarations emitted from src/components/ui/phone-input.tsx.

declare const PhoneInput: any;
export { PhoneInput };

Example#

The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.

<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>