Skip to content

Import

import { Field } from '@dnb/eufemia/extensions/forms'
render(<Field.PhoneNumber />)

Description

Field.PhoneNumber is a wrapper component for the input of strings, with user experience tailored for phone number values.

There is a corresponding Value.PhoneNumber component.

Relevant links

Value

This component behaves as "one single component". It combines the country code and the number to a single string during an event callback.

Also, the value property should be a string with the country code, separated from the main number by a space.

The component returns the emptyValue when no number is set, which defaults to undefined.

It uses the HTML autocomplete attribute (tel-country-code and tel-national) in their respective fields(country code and phone number) to provide automated assistance in filling out form field values, as well as guidance to the browser as to the type of information expected in the field..

Default country code

The default country code is set to +47.

Structure and format of phone numbers

Creating a list of all possible phone numbers would be impractical due to the vast number of combinations, especially considering the various country codes, area codes, and local numbers. Additionally, new numbers are constantly being allocated, and existing numbers may be reassigned over time.

Therefore, the structure and format is only used when +47 is selected.

Support for locales like sv-SE and da-DK

In addition to the default support for nb-NO and en-GB, you can also use sv-SE and da-DK locales to display country names in Swedish or Danish.

Learn more about importing additional locales.

Filter or prioritize country listing

You can filter countries with the countries property's values Scandinavia, Nordic or Europe.

Countries are sorted in alphabetically order, with the following prioritized countries on top of the list:

  • Norway
  • Sweden
  • Denmark
  • Finland

Validation

By default it has no validation. But you can enable it by giving a required, pattern, schema, onChangeValidator or onBlurValidator property with the needed validation. More about validation in the Getting Started section.

Norwegian mobile numbers

E.g. the following pattern will strictly match Norwegian mobile numbers, which are defined as having a "+47" country code, followed by a number starting with 4 or 9, and exactly 7 more digits. If the country code is set to any other two-digit code, the pattern will match any 6 digits after the country code.

<Field.PhoneNumber pattern="((?=\+47)^\+47 [49]\d{7}$)|((?!\+47)^\+\d{2} \d{6})" />

Demos

Empty

Code Editor
<Field.PhoneNumber
  onFocus={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onFocus', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  onBlur={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onBlur', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  onCountryCodeChange={(countryCode) =>
    console.log('onCountryCodeChange', countryCode)
  }
  onNumberChange={(phoneNumber) =>
    console.log('onNumberChange', phoneNumber)
  }
/>

Placeholder

Code Editor
<Field.PhoneNumber
  placeholder="Call this number"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
/>

Label

Code Editor
<Field.PhoneNumber
  label="Label text"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
/>

Label and value

Code Editor
<Field.PhoneNumber
  label="Label text"
  value="+47 98765432"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
/>

Show only Scandinavian countries

Code Editor
<Field.PhoneNumber
  label="Label text"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  countries="Scandinavia"
/>

With help

Code Editor
<Field.PhoneNumber
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  help={{
    title: 'Help is available',
    content:
      'Helping others, encouraging others, are often acts of being kind that have more meaning that you may realize.',
  }}
/>

Used in Card

Code Editor
<Form.Card>
  <Field.PhoneNumber />
</Form.Card>

Disabled

Code Editor
<Field.PhoneNumber
  value="+47 12345678"
  label="Label text"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  disabled
/>

Error

This is what is wrong...
Code Editor
<Field.PhoneNumber
  value="007"
  label="Label text"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  error={new Error('This is what is wrong...')}
/>

Validation - Required

Code Editor
<Field.PhoneNumber
  value="+47 888"
  label="Label text"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  required
/>

Validation - Pattern

Code Editor
<Field.PhoneNumber
  value="+41 123"
  label="Label text"
  onChange={(value, { countryCode, phoneNumber, iso }) =>
    console.log('onChange', value, {
      countryCode,
      phoneNumber,
      iso,
    })
  }
  pattern="^\+41 [1]\d{2}$"
/>

Filter countries

This example demonstrates how to filter specific countries. Use the countries property to define a set of countries and/or the filterCountries property to apply custom filtering logic.

Code Editor
<Field.PhoneNumber
  countries="Scandinavia"
  filterCountries={({ iso }) => iso !== 'DK'}
/>

Transform in and out

This example demonstrates how to transform data when it enters and leaves the form field.

You can use the transformIn property to modify the incoming data before it is displayed in the field, and the transformOut property to adjust the data before it is submitted or processed. When transformIn one can either return a simple value "+47 98765432" or an object { countryCode:"+47", phoneNumber:"98765432" }.

{
  "myField": {
    "countryCode": "GB",
    "phoneNumber": "9123457",
    "countryCodePrefix": "+44"
  }
} 
Code Editor
const transformOut = (internal, additionalArgs) => {
  return {
    countryCode: additionalArgs?.iso,
    phoneNumber: additionalArgs?.phoneNumber,
    countryCodePrefix: additionalArgs?.countryCode,
  }
}
const transformIn = (external) => {
  return {
    countryCode: external?.countryCodePrefix,
    phoneNumber: external?.phoneNumber,
  }
}
render(
  <Form.Handler
    defaultData={{
      myField: {
        countryCode: 'GB',
        phoneNumber: '9123457',
        countryCodePrefix: '+44',
      },
    }}
  >
    <Form.Card>
      <Field.PhoneNumber
        path="/myField"
        transformOut={transformOut}
        transformIn={transformIn}
        label="Transform in and out"
      />
      <Tools.Log />
    </Form.Card>
  </Form.Handler>,
)

Here is how you can deal with TypeScript types for the transform functions:

import { AdditionalArgs } from '@dnb/eufemia/src/extensions/forms/Field/PhoneNumber'
type MyFieldShape = {
countryCode: string
phoneNumber: string
countryCodePrefix: string
}
const transformOut = (internal, additionalArgs = {}) => {
const {
countryCode: countryCodePrefix,
phoneNumber,
iso: countryCode,
} = additionalArgs as AdditionalArgs
return {
countryCode,
phoneNumber,
countryCodePrefix,
} satisfies MyFieldShape
}
const transformIn = (
{
countryCode: iso,
phoneNumber,
countryCodePrefix: countryCode,
}: MyFieldShape = {} as MyFieldShape | undefined,
) => {
return {
countryCode,
phoneNumber,
iso,
} satisfies AdditionalArgs
}