> ## Documentation Index
> Fetch the complete documentation index at: https://api.fanvue.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PhoneField

> A phone number input with a country selector (flag + chevron), a fixed dial code prefix, and a `tel` input.

```tsx theme={null}
import { PhoneField } from "@fanvue/ui";
import type { PhoneFieldProps, PhoneFieldSize } from "@fanvue/ui";
```

## Examples

## Default

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-phonefield--default&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="240" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="PhoneField — Default" />
</Frame>

```tsx theme={null}
import { PhoneField } from "@fanvue/ui";

const ItalyFlag = () => (
  <span aria-hidden="true" className="text-base leading-none">
    🇮🇹
  </span>
);

<PhoneField
  label="Phone number"
  dialCode="+39"
  flag={<ItalyFlag />}
  placeholder="Input Content"
/>
```

## Filled

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-phonefield--filled&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="240" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="PhoneField — Filled" />
</Frame>

```tsx theme={null}
import { PhoneField } from "@fanvue/ui";

const ItalyFlag = () => (
  <span aria-hidden="true" className="text-base leading-none">
    🇮🇹
  </span>
);

<PhoneField
  label="Phone number"
  dialCode="+39"
  flag={<ItalyFlag />}
  placeholder="Input Content"
  defaultValue="3381020300"
/>
```

## Error State

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-phonefield--error-state&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="240" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="PhoneField — Error State" />
</Frame>

```tsx theme={null}
import { PhoneField } from "@fanvue/ui";

const ItalyFlag = () => (
  <span aria-hidden="true" className="text-base leading-none">
    🇮🇹
  </span>
);

<PhoneField
  label="Phone number"
  dialCode="+39"
  flag={<ItalyFlag />}
  placeholder="Input Content"
  error
  errorMessage="Enter a valid phone number"
  defaultValue="33810"
/>
```

## With Helper Text

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-phonefield--with-helper-text&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="240" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="PhoneField — With Helper Text" />
</Frame>

```tsx theme={null}
import { PhoneField } from "@fanvue/ui";

const ItalyFlag = () => (
  <span aria-hidden="true" className="text-base leading-none">
    🇮🇹
  </span>
);

<PhoneField
  label="Phone number"
  dialCode="+39"
  flag={<ItalyFlag />}
  placeholder="Input Content"
  helperText="We'll send a verification code to this number"
/>
```

## All sizes

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-phonefield--all-sizes&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="240" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="PhoneField — All sizes" />
</Frame>

```tsx theme={null}
import { PhoneField } from "@fanvue/ui";

const ItalyFlag = () => (
  <span aria-hidden="true" className="text-base leading-none">
    🇮🇹
  </span>
);

<div className="flex w-[375px] flex-col gap-4">
  <PhoneField
    size="48"
    label="Size 48"
    flag={<ItalyFlag />}
    dialCode="+39"
    defaultValue="3381020300"
  />
  <PhoneField
    size="40"
    label="Size 40"
    flag={<ItalyFlag />}
    dialCode="+39"
    defaultValue="3381020300"
  />
  <PhoneField
    size="32"
    label="Size 32"
    flag={<ItalyFlag />}
    dialCode="+39"
    defaultValue="3381020300"
  />
</div>
```

## Props

## PhoneField

A phone number input with a country selector (flag + chevron), a fixed dial code prefix, and a `tel` input. The country picker itself is owned by the consumer: pass the selected country's `flag` and `dialCode`, and open your picker from `onCountrySelect`.

Provide at least one of `label`, `aria-label`, or `aria-labelledby` for accessibility — a console warning is emitted in development if none are set.

<ParamField path="countryButtonLabel" type="string" default="Select country">
  Accessible name for the country selector button.
</ParamField>

<ParamField path="dialCode" type="ReactNode">
  Dial code of the selected country, shown before the number (e.g. `"+39"`).
</ParamField>

<ParamField path="error" type="boolean" default="false">
  Whether the field is in an error state.
</ParamField>

<ParamField path="errorMessage" type="string">
  Error message displayed below the input. Shown instead of `helperText` when `error` is `true`.
</ParamField>

<ParamField path="flag" type="ReactNode">
  Flag of the selected country, rendered in the country selector (e.g. an image or flag icon).
</ParamField>

<ParamField path="fullWidth" type="boolean" default="false">
  Whether the field stretches to fill its container width.
</ParamField>

<ParamField path="helperText" type="string">
  Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`.
</ParamField>

<ParamField path="label" type="string">
  Label text displayed above the input. Also used as the accessible name.
</ParamField>

<ParamField path="onCountrySelect" type="(() => void)">
  Fired when the country selector (flag + chevron) is activated. Open the country picker here.
</ParamField>

<ParamField path="size" type="&#x22;32&#x22; | &#x22;40&#x22; | &#x22;48&#x22;" default="48">
  Height of the phone field in pixels.
</ParamField>

## Exported types

Also exported from `@fanvue/ui`: `PhoneFieldProps`, `PhoneFieldSize`.

***

**Setup:** [Installation](/docs/ui/installation) · [Theming](/docs/ui/theming)
