Anchor Design System

Phone3.0

The Phone Input is meant to let the user input their phone number, and letting them chose a dial code by the name of their country or flag.

Installation

npm i @tryg/vue-ui-library

Usage

Install the component library as a Vue plugin. This globally registers all Anchor components.

main.js
import { createApp } from 'vue';
import { ComponentLibrary } from '@tryg/vue-ui-library';
import App from './App.vue';

const app = createApp(App);
app.use(ComponentLibrary);
app.mount('#app');
YourComponent.vue
<template>
  <anchor-phone label="Your phone number"></anchor-phone>
</template>

Import only the components you need for optimal bundle size.

YourComponent.vue
<script setup>
import { AnchorPhone } from '@tryg/vue-ui-library';
</script>
<template>
  <anchor-phone label="Your phone number"></anchor-phone>
</template>

With value

Denmark first

Norway first

Disabled

Filled

Placeholder

Pattern

With error

Help text

Country list details

Introduction

To populate the Phone component with a list of countries to choose from, you need to provide the component with an array containing an object for each country. Remember to stringify the array.

You can also use the default list of countries and their data that Anchor provides.

<script setup>
import { defaultCountriesForPhone } from '@tryg/vue-ui-library';

const options = JSON.stringify(defaultCountriesForPhone);
</script>
<template>
  <anchor-phone :options="options" label="Your phone number"></anchor-phone>
</template>

The array of countries needs to follow this format:

[
  {
    "name": string,
    "iso2": string,
    "dialCode": number,
    "priority": number,
    "areaCodes": [number]
  }
]

Manipulate country list

If you want to make sure that a certain country is the first choice without writing your own array of countries, you can do something like this:

function rearrangeArrayByCountrycode(array, country) {
  const newArray = [...array];
  const foundIndex = newArray.findIndex(obj => obj.iso2 === country);

  if (foundIndex > -1) {
    const removedArray = newArray.splice(foundIndex, 1)[0];
    newArray.unshift(removedArray);
  }

  return newArray;
}

The array in this example is the defaultCountriesForPhone array. The country is the iso2 code for a given country.

Pass the re-arranged array in as options for the Phone component like this:

<script setup>
import { AnchorPhone, defaultCountriesForPhone } from '@tryg/vue-ui-library';

function rearrangeArrayByCountrycode(array, country) {
  const newArray = [...array];
  const foundIndex = newArray.findIndex(obj => obj.iso2 === country);
  if (foundIndex > -1) {
    const removedArray = newArray.splice(foundIndex, 1)[0];
    newArray.unshift(removedArray);
  }
  return newArray;
}

const options = JSON.stringify(rearrangeArrayByCountrycode(defaultCountriesForPhone, 'dk'));
</script>
<template>
  <anchor-phone :options="options"></anchor-phone>
</template>

Accessibility

  • Built on a native input element, providing standard keyboard navigation and form control behavior out of the box.
  • The country select uses role="combobox" with aria-haspopup="listbox" and aria-expanded to communicate the dropdown state to assistive technology.
  • Error state is communicated using aria-invalid, ensuring screen readers announce validation errors.
  • The label prop provides an accessible label for the input, and aria-country-select-label customizes the country selector label.
  • Screen reader-only text support via the sr-only utility class ensures assistive context without visual clutter.

API

anchor-phone

Properties

PropertyAttributeDescriptionTypeDefault
ariaCountrySelectLabelaria-country-select-labelText to be displayed if when value is missing an native form validation is usedstring'Select country'
disableddisabledDisable the number fieldbooleanfalse
errorerrorShow an error messagestring''
filledfilledShow a checkmark icon when the input field has been succesfully filledbooleanfalse
helpTexthelp-textShow a help textstring''
labellabelShow the label (you can't currently disable the label)booleantrue
labelPlacementlabel-placementPlacement of the label"left" | "top"'top'
maxLengthmax-lengthSet a max width in characters for the number field.numberundefined
namenameThe name of the number fieldstring''
optionsoptionsPass an array of countries to the phone fieldCountry[] | stringundefined
patternpatternstringnull
placeholderplaceholderPlaceholder text is shown until the user interacts with the number fieldstring''
readonlyreadonlySet the field to be read onlybooleanfalse
requiredrequiredMark the field as requiredbooleanfalse
selectedCountryselected-countrynumber0
sizesizeSet a fixed width in characters for the number field.numbernull
spinnersspinners"big" | "none" | "small"'none'
tooltipTexttooltip-textAdd an info icon with a tooltip to the right of the labelstring''
uuiduuidGive this instance of phone a custom ID, or keep the default.stringuuidv4()
validityMissingValueTextvalidity-missing-value-textText to be displayed if when value is missing an native form validation is usedstringundefined
valuevalueThe value in the number field. Use this to set a valuestring''
warningwarningShow a warning messagestring''

Events

EventDescriptionType
blureventEvent emitted when the user blurs the input fieldCustomEvent<any>
cleareventEvent emitted when the user clears the input fieldCustomEvent<any>
countrySelectedEvent emitted when a country is selectedCustomEvent<any>
focuseventEvent emitted when the user is focusing the input fieldCustomEvent<any>
inputChangeEvent emitted when user inputs something into the fieldCustomEvent<EventDetail>
inputeventEvent emitted when the user is inputting something into the input fieldCustomEvent<EventDetail>
phoneNumberInvalidEvent emitted when the input does not match the patternCustomEvent<any>
phoneNumberValidEvent emitted when the input matches the patternCustomEvent<boolean>

Methods

checkValidPhoneNumber(value: any) => Promise<CustomEvent<any>>

Parameters

NameTypeDescription
valueany

Returns

Type: Promise<CustomEvent<any>>

CSS Custom Properties

NameDescription
--phone-input-border-colorSet the border color of the phone input.
--phone-input-border-color-errorSet the border color of the phone input for error states.
--phone-input-border-color-hoverSet the border color of the phone input on hover.
--phone-input-border-widthSet the border width of the phone input.
--phone-input-line-heightSet the line height of the phone input.
--phone-input-list-countries-lengthSet the number of countries shown in the list when it is open.
--phone-input-list-heightSet the height of the list in the phone input.
--phone-input-margin-bottomSet the bottom margin of the phone input.
--phone-input-margin-leftSet the left margin of the phone input.
--phone-input-margin-rightSet the right margin of the phone input.
--phone-input-margin-topSet the top margin of the phone input.
--phone-input-max-widthSet the max width of the phone input.
--phone-input-padding-bottomSet the bottom padding of the phone input.
--phone-input-padding-leftSet the left padding of the phone input.
--phone-input-padding-rightSet the right padding of the phone input.
--phone-input-padding-topSet the top padding of the phone input.
--phone-input-widthSet the width of the phone input.
--room-for-selectGive the Input extra padding to make room for the Select.

Dependencies

Depends on

Graph

graph TD;
  anchor-phone --> anchor-input
  anchor-phone --> anchor-icon
  anchor-phone --> anchor-select-item
  anchor-phone --> anchor-country-code
  anchor-input --> anchor-form-field
  anchor-input --> anchor-icon
  anchor-input --> anchor-tooltip
  anchor-form-field --> anchor-icon
  anchor-select-item --> anchor-icon
  style anchor-phone fill:#f9f,stroke:#333,stroke-width:4px

Built with StencilJS

On this page