# Phone field

A country key and a number in one well, for a contact number. It opens a card with a search box and a list of countries; the number beside it is a plain telephone input that sets itself out in the country’s own grouping as you type, and keeps the caret where it was. Paste an international number and the country follows it. It checks length and shape, not whether a line exists.

Kit part · With the Kit · https://tactileui.dev/parts/phone-field

> The code and styling for this part come with the Tactile UI Kit, which is in the Founder Pass. Sign in if you have it. Sign in: https://tactileui.dev/auth/sign-in The price: https://tactileui.dev/pricing

## Anatomy

The field’s well with the kit’s small key let into its floor, the combobox’s card for the list (the browser’s own popover, so light dismiss and Escape are native) and the kit’s lamp to mark the country chosen. The element is form-associated. Formatting is a pure function of the digits and the country’s grouping; the caret is kept by counting the digits before it and putting it back after the same digit. The country data is a table of 49 rows in the module, with no dependency: it knows the dial code, the grouping, the shortest and longest number and the trunk digit, and nothing about which numbers are in service.

## Variants

- Empty · the default country is GB
- With help text
- Required
- Filled
- Filled
- Error from outside
- Disabled
- Read-only
- Another default
- Limited to a few
- One country
- Own placeholder

## States

- Resting
- Number focused

## Props and options

| Name | Kind | Description |
| - | - | - |
| value | attribute · property | The number. Setting it changes the country to match its code. A form reset goes back to the attribute. |
| country | attribute · property | The country chosen, and the one a form reset goes back to. A number typed without a code is read as this country’s. |
| countries | attribute | Limits the list (“IE GB”). One country makes the key a plain legend with nothing to open. |
| required · disabled · readonly | attribute | Required makes a blank number invalid. Disabled (also through a fieldset) takes the whole field out of the form. Read-only keeps the number readable and the country fixed. |
| placeholder | attribute |  |
| error | attribute | A message from outside, such as the server’s. It marks the field invalid, with aria-invalid and the message, until the attribute is removed. |
| input · change | event |  |
| Enter · Space · ↓ · ↑ · a letter or digit | keyboard | Enter and Space press the key, which opens or closes the list. Down and Up open it. A letter, digit or + opens it with that character already in the search. |
| ↑ ↓ · Page Up · Page Down · Home · End | keyboard | Up and Down move one country, Page Up and Page Down seven, Home and End to the first and last. |
| Enter · Escape · Tab | keyboard | Enter picks the country. Escape and Tab close the list and put the focus back on the key. |
| checkValidity() · reportValidity() · validity · validationMessage | method | The field’s own validity: valueMissing when required and blank, tooShort, tooLong, and patternMismatch for a number that is not a number for that country. |
| phoneCountry() · phoneFilter() · phoneFormat() · phoneDigitsBefore() · phoneCaretAfter() · phoneParse() · phoneE164() · phoneValidity() | function | The country by ISO code. |

## Usage notes

Leave a short number and tab away to see what is wrong with it.

## Accessibility

- Its printed face is the ISO code and the dial code, so no one has to read a flag.
- On the key, Enter, Space, Down or Up open the list, and a letter or digit opens it with the search started. In the list the arrow keys, Home and End move, Enter picks and Escape closes with the focus back on the key. Search is by name, ISO code or dial code. How many countries match is said once in a polite status line, not on each key.
- The caret stays after the same digit when the number is set out again, so typing in the middle of a number does not throw it to the end.
- The error appears after the number is left, or when the form is sent, and goes the moment it is right. It says how long the number should be, and never that the number “is not real”: the field checks length and shape, not whether a line exists.

## Related parts

- [Field](https://tactileui.dev/parts/field): Text entry in a recess, the label printed above it, and a hint that says how to fix an error.
- [Input group](https://tactileui.dev/parts/input-group): One recess that holds a field and everything that belongs to it. Words that are part of the value but are not typed, such as https:// or a currency, are printed on the floor of the well behind an engraved line; a glyph sits at the start; small keys sit at the end to clear the text, copy it, or show a password.
- [Combobox](https://tactileui.dev/parts/combobox): A field that filters a long list as you type. It starts as a plain select, so it posts with the form and works without a script; then the options card slides out of a slot under the well, the letters that match print heavier and the chosen option’s lamp is lit. Several choices sit in the well as tags.
- [Password field](https://tactileui.dev/parts/password-field): The field’s well with a louvred shutter drawn across its characters and a peek key at the end. Press the key and the shutter slides off to the right, the characters stand open, and the key stays down; press it again and the shutter closes. The key says Show or Hide, and the caret never leaves where it was.
