🎮 Live Playground

Adjust props in real-time and see the results instantly

<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')
</script>

<template>
  <PhoneInput
    v-model="phone"
    detect
  />
</template>

1. Basic Usage

Simple phone input with country selector

Phone: —
<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')
</script>

<template>
  <PhoneInput v-model="phone" />
</template>

2. Phone Validation

Real-time validation state tracking

Enter a phone number
<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')
const isValid = ref(false)

function onValidation(valid: boolean) {
  isValid.value = valid
}
</script>

<template>
  <PhoneInput
    v-model="phone"
    @validation-change="onValidation"
  />
  <p v-if="!isValid && phone" class="error">
    Please enter a complete phone number
  </p>
</template>

3. Auto Country Detection

Automatically detect country from IP or browser locale

Detected Country: Auto-detecting...
<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')
const countryName = ref('')

function onCountry(country: PMaskFull) {
  countryName.value = country.name
}
</script>

<template>
  <PhoneInput
    v-model="phone"
    detect
    @country-change="onCountry"
  />
  <p>Detected: {{ countryName }}</p>
</template>

4. Size Variants

Three size options: compact, normal, and large

<template>
  <!-- Compact -->
  <PhoneInput v-model="phone" size="compact" />

  <!-- Normal (default) -->
  <PhoneInput v-model="phone" size="normal" />

  <!-- Large -->
  <PhoneInput v-model="phone" size="large" />
</template>

5. Theme Modes

Auto, light, and dark themes

<template>
  <!-- Auto (system preference) -->
  <PhoneInput v-model="phone" theme="auto" />

  <!-- Light -->
  <PhoneInput v-model="phone" theme="light" />

  <!-- Dark -->
  <PhoneInput v-model="phone" theme="dark" />
</template>

6. Copy & Clear Actions

Built-in copy and clear button functionality

<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')

function handleCopy(value: string) {
  console.log('Copied:', value)
}

function handleClear() {
  console.log('Input cleared')
}
</script>

<template>
  <PhoneInput
    v-model="phone"
    show-copy
    show-clear
    @copy="handleCopy"
    @clear="handleClear"
  />
</template>

7. Disabled & Readonly States

Control input interaction modes

<script setup lang="ts">
import { ref } from 'vue'
const disabledPhone = ref('1234567890')
const readonlyPhone = ref('9876543210')
</script>

<template>
  <PhoneInput v-model="disabledPhone" disabled />
  <PhoneInput v-model="readonlyPhone" readonly />
</template>

8. Form Integration

Use in forms with validation

{
  "name": "",
  "email": "",
  "phone": ""
}
<script setup lang="ts">
import { ref } from 'vue'

const formData = ref({
  name: '',
  email: '',
  phone: ''
})

const formErrors = ref({ phone: '' })

function onValidation(isValid: boolean) {
  formErrors.value.phone = isValid
    ? ''
    : 'Invalid phone'
}

function handleSubmit() {
  if (!formErrors.value.phone) {
    console.log(formData.value)
  }
}
</script>

<template>
  <form @submit.prevent="handleSubmit">
    <input
      v-model="formData.name"
      placeholder="Name"
    />
    <input
      v-model="formData.email"
      type="email"
    />
    <PhoneInput
      v-model="formData.phone"
      @validation-change="onValidation"
    />
    <span v-if="formErrors.phone" class="error">
      {{ formErrors.phone }}
    </span>

    <button type="submit">Submit</button>
  </form>
</template>

🎯 Vue Directive Examples

Use v-phone-mask directive for custom inputs

9. Basic Directive Usage

Apply phone masking to any input element

Value: —
<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')
</script>

<template>
  <input v-model="phone" v-phone-mask />
</template>

10. Directive with Options

Configure country and handle change events

Full: —Formatted: —Digits: —
<script setup lang="ts">
import { ref } from 'vue'

const country = ref('GB')
const phoneData = ref<PMaskPhoneNumber>({
  full: '',
  formatted: '',
  digits: ''
})

function onChange(data: PMaskPhoneNumber) {
  phoneData.value = data
}
</script>

<template>
  <input
    v-phone-mask="{
      country: country,
      onChange
    }"
  />
  <p>Full: {{ phoneData.full }}</p>
  <p>Formatted: {{ phoneData.formatted }}</p>
  <p>Digits: {{ phoneData.digits }}</p>
</template>

11. Directive with Auto-detect

Automatically detect country from IP/locale

Detected Country: Detecting...
<script setup lang="ts">
import { ref } from 'vue'

const phone = ref('')
const detected = ref('')

function onCountryChange(country: PMaskFull) {
  detected.value = country.name
}
</script>

<template>
  <input
    v-model="phone"
    v-phone-mask="{
      detect: true,
      onCountryChange,
    }"
  />
  <p v-if="detected">Country: {{ detected }}</p>
</template>