Component reference
PhoneInput
Choose a calling code and enter a contact number.
Preview
Live previewOptional six-digit hex. Clear to restore the preset. Check contrast with your brand color.
Changes apply to this preview only.
Security contact
The country selector and the national field share one E.164 value. FormError is wired through aria-describedby.
Width adapts to the available space
"use client";
import { useState } from "react";
import {
useForm,
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
Form,
Input,
FormError,
PhoneInput,
FormSubmit
} from "@pimolu/react";
interface ContactValues {
name: string;
phone: string;
}
function ContactForm() {
const [saved, setSaved] = useState(false);
const form = useForm<ContactValues>({
defaultValues: {
name: "",
phone: "",
},
validate: (values) => {
const errors: Partial<Record<keyof ContactValues, string>> = {};
if(!values.name.trim()) {
errors.name = "Add a contact name.";
}
if(values.phone.replace(/\D/g, "").length < 8) {
errors.phone = "Enter a complete phone number.";
}
return errors;
},
onSubmit: async () => {
await new Promise((resolve) => setTimeout(resolve, 600));
setSaved(true);
},
});
return (
<Card>
<CardHeader>
<CardTitle>Security contact</CardTitle>
<CardDescription>
The country selector and the national field share one E.164
value. FormError is wired through aria-describedby.
</CardDescription>
</CardHeader>
<CardContent>
<Form form={form} className="grid gap-5 min-w-0">
<Input label="Contact name" required fullWidth {...form.register("name")} />
<FormError name="name" />
<PhoneInput
label="Mobile number"
defaultCountry="US"
required
fullWidth
value={form.values.phone}
onValueChange={(value) => form.setValue(
"phone",
value
)}
invalid={Boolean(form.errors.phone)}
aria-describedby={form.errors.phone
? `${form.formId}-phone-error`
: undefined}
helperText="Used for sign-in codes only."
/>
<FormError name="phone" />
<FormSubmit>Save contact</FormSubmit>
{
saved && (<p role="status">
Security contact saved for{" "}
{form.values.name}.
</p>)
}
</Form>
</CardContent>
</Card>
);
}
export function DemoExample() {
return (<ContactForm />);
}More examples
Different configurations and compositions using the real Pimolu API. Each preview runs independently and follows the site appearance.
Countries and formatting
The country drives the dial prefix and the national pattern. An international value is matched to its country automatically.
Sizes
sm, md and lg match the other text controls.
Controlled value and country
Both the number and the country can be controlled. Selecting another country immediately re-emits the same national digits with the new dial code.
Usage
Country selection and formatting do not prove that a phone number exists or is reachable.
API reference
Generated from the public TypeScript declarations. Native HTML attributes are inherited where the component extends them; this reference includes Pimolu props and selected common native attributes.
PimoluPhoneCountry
Type source| Name | Type | Default | Description |
|---|---|---|---|
codeRequired | string | — | ISO 3166-1 alpha-2 code, used as the option value. |
nameRequired | string | — | Human-readable country name. |
dialCodeRequired | string | — | International dialling code, without the leading "+". |
pattern | string | undefined | — | Optional national pattern. `9` is a digit, every other character is a literal. Longer numbers keep their extra digits after the pattern. |
codeRequiredstringNo default extracted.
ISO 3166-1 alpha-2 code, used as the option value.
nameRequiredstringNo default extracted.
Human-readable country name.
dialCodeRequiredstringNo default extracted.
International dialling code, without the leading "+".
patternstring | undefinedNo default extracted.
Optional national pattern. `9` is a digit, every other character is a literal. Longer numbers keep their extra digits after the pattern.
PimoluPhoneInputProps
Type source| Name | Type | Default | Description |
|---|---|---|---|
value | string | undefined | — | Controlled phone number, preferably E.164 (`+14155551234`). A national number is also accepted and read with the selected country. |
defaultValue | string | undefined | — | Initial phone number when uncontrolled. |
onValueChange | ((value: string) => void) | undefined | — | Called with the next E.164 value, or "" when the field is empty. |
country | string | undefined | — | Controlled ISO country code (for example "FR"). |
defaultCountry | string | undefined | "US" | Initial country when uncontrolled. Defaults to "US". |
onCountryChange | ((country: PimoluPhoneCountry) => void) | undefined | — | Called when the country selector changes. |
countries | PimoluPhoneCountry[] | undefined | — | Replace the built-in country list. |
countryLabel | string | undefined | "Country" | Accessible name of the country selector. Defaults to "Country". |
label | ReactNode | — | Visible label, associated with the national number input. |
helperText | ReactNode | — | Supporting text below the field. |
errorMessage | ReactNode | — | Error text, replacing the helper text. |
invalid | boolean | undefined | false | Invalid state without an error message. |
size | PimoluPhoneInputSize | undefined | "md" | Visual size. Defaults to "md". |
fullWidth | boolean | undefined | false | Stretch to the parent width. |
containerClassName | string | undefined | — | Class applied to the outer field. |
className | string | undefined | — | Standard React/HTML attribute. |
style | CSSProperties | undefined | — | Standard React/HTML attribute. |
aria-label | string | undefined | — | Defines a string value that labels the current element. |
children | ReactNode | — | Standard React/HTML attribute. |
onClick | MouseEventHandler<HTMLInputElement> | undefined | — | Standard React/HTML attribute. |
disabled | boolean | undefined | false | Standard React/HTML attribute. |
name | string | undefined | — | Standard React/HTML attribute. |
required | boolean | undefined | false | Standard React/HTML attribute. |
valuestring | undefinedNo default extracted.
Controlled phone number, preferably E.164 (`+14155551234`). A national number is also accepted and read with the selected country.
defaultValuestring | undefinedNo default extracted.
Initial phone number when uncontrolled.
onValueChange((value: string) => void) | undefinedNo default extracted.
Called with the next E.164 value, or "" when the field is empty.
countrystring | undefinedNo default extracted.
Controlled ISO country code (for example "FR").
defaultCountrystring | undefinedDefault: "US"
Initial country when uncontrolled. Defaults to "US".
onCountryChange((country: PimoluPhoneCountry) => void) | undefinedNo default extracted.
Called when the country selector changes.
countriesPimoluPhoneCountry[] | undefinedNo default extracted.
Replace the built-in country list.
countryLabelstring | undefinedDefault: "Country"
Accessible name of the country selector. Defaults to "Country".
labelReactNodeNo default extracted.
Visible label, associated with the national number input.
helperTextReactNodeNo default extracted.
Supporting text below the field.
errorMessageReactNodeNo default extracted.
Error text, replacing the helper text.
invalidboolean | undefinedDefault: false
Invalid state without an error message.
sizePimoluPhoneInputSize | undefinedDefault: "md"
Visual size. Defaults to "md".
fullWidthboolean | undefinedDefault: false
Stretch to the parent width.
containerClassNamestring | undefinedNo default extracted.
Class applied to the outer field.
classNamestring | undefinedNo default extracted.
Standard React/HTML attribute.
styleCSSProperties | undefinedNo default extracted.
Standard React/HTML attribute.
aria-labelstring | undefinedNo default extracted.
Defines a string value that labels the current element.
childrenReactNodeNo default extracted.
Standard React/HTML attribute.
onClickMouseEventHandler<HTMLInputElement> | undefinedNo default extracted.
Standard React/HTML attribute.
disabledboolean | undefinedDefault: false
Standard React/HTML attribute.
namestring | undefinedNo default extracted.
Standard React/HTML attribute.
requiredboolean | undefinedDefault: false
Standard React/HTML attribute.
Accessibility
- Label the country selector and number separately, and preserve telephone autocomplete.