Skip to content

lbgm/phone-number-input

Repository files navigation

Phone number input

Simple Phone Number Input for VueJs

Screenshot

install

npm i @lbgm/phone-number-input

Props & Types

interface PhoneDATA {
  country?: string;
  dialCode?: string | number;
  nationalNumber?: string | number;
  number?: string | number;
  isValid?: boolean;
}

interface Props {
  value?: string;
  label?: string;
  hasError?: boolean;
  hasSuccess?: boolean;
  successMessage?: string;
  errorMessage?: string;
  placeholder?: string;
  name?: string;
  required?: boolean;
  defaultCountry?: string;
  arrow?: boolean;
  listHeight?: number;
  allowed?: string[];
}

// default props values

{
  value: "", // like '22997000000',
  label: "",
  hasError: false,
  hasSuccess: false,
  successMessage: "",
  errorMessage: "",
  placeholder: "",
  name: "",
  required: false,
  defaultCountry: "BJ",
  arrow: true, // show or hide arrow
  listHeight: 150,
  allowed: () => [],
}
  • pass value on this format: ${dialCode}${nationalNumber}
  • allowed is an array of country iso2 (string).

Slots

arrow

<!-- to change arrow icon-->
<phone-input>
 <template #arrow><icon /><template>
</phone-input>

use global slot to append content at the end of the component.

<phone-input>
  <div>Hello</div>
</phone-input>

Use

main.ts :

 import { PhoneInput } from '@lbgm/phone-number-input';

 // register as global component
 app.component('PhoneInput', PhoneInput);

App.vue :

// import component style
import '@lbgm/phone-number-input/style';

use component:

   <phone-input
     @phone="phone = $event"
     @country="country = $event"
     @phoneData="phoneData = $event"
     name="phone-number-input"
     label="Enter your phone"
     required
     :value="'22997788842'"
   />
  • phone is string
  • country is string
  • phoneData is type PhoneDATA

Use it with Vee-validate

Sample wrapper code:

<template>
 <phone-input
   :has-error="hasError"
   :errorMessage="errorMessage"
   @phoneData="validatePhone"
   ref="phoneInput"
 />
</template>
<script setup lang="ts">
import { useField } from 'vee-validate';
import { computed, onMounted, useAttrs, getCurrentInstance, type ComponentInternalInstance } from 'vue';
import { PhoneInput, type PhoneDATA } from '@lbgm/phone-number-input';

type T_PhoneInput = typeof PhoneInput;

const that: ComponentInternalInstance | null = getCurrentInstance();
const attrs = useAttrs();
const emit = defineEmits(['inputData']);

const {
  value: inputValue,
  errorMessage,
  handleBlur,
  handleChange,
  meta,
} = useField(attrs.name, undefined, {
  initialValue: attrs.value ? attrs.value : '',
  validateOnValueUpdate: false,
});

// compute error from vee-validate
const hasError = computed((): boolean => {
  return errorMessage.value !== undefined;
});

const validatePhone = (data: PhoneDATA) => {
  handleChange(data.nationalNumber, false);
  emit('inputData', data);
};

onMounted(() => {
  if ((that?.refs?.phoneInput as T_PhoneInput).phone) {
    handleChange((that?.refs.phoneInput as T_PhoneInput).phone);
  }
});
</script>