8454031669
Input Phone
A component for inputting and validating international phone numbers with country code selection
Basic Usage
html
<template>
<HLInputPhone v-model:countryCode="countryCode" v-model:value="phone" />
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const phone = ref('+91845403166')
const countryCode = ref('IN')
</script>With Icon
html
<HLInputPhone v-model:countryCode="countryCode" v-model:value="phone">
<template #suffix>
<HLIcon>
<MessageQuestionCircleIcon class="w-4" />
</HLIcon>
</template>
</HLInputPhone>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const phone = ref('+91845403166')
const countryCode = ref('IN')
</script>Sizes
html
<template>
<HLInputPhone size="lg" placeholder="Large size" />
<HLInputPhone size="md" placeholder="Medium size" />
<HLInputPhone size="sm" placeholder="Small size" />
<HLInputPhone size="xs" placeholder="Extra small size" />
<HLInputPhone size="2xs" placeholder="2x Extra small size" />
<HLInputPhone size="3xs" placeholder="3x Extra small size" />
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const phone = ref('+91845403166')
const countryCode = ref('IN')
</script>Disabled State
(201) 555-0123
html
<template>
<HLInputPhone id="input-phone-disabled" disabled />
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
</script>With Disabled Country Picker
html
<template>
<HLInputPhone id="input-phone-no-country" disableCountryPicker v-model:value="phone" />
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const phone = ref('+91845403166')
</script>Inline Mode
Basic Inline
html
<template>
<HLInputPhone id="input-phone-inline" inline v-model:countryCode="countryCode" v-model:value="phone" />
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const phone = ref('+91845403166')
const countryCode = ref('IN')
</script>Inline with Edit Actions and CTA
8454031669
html
<template>
<HLInputPhone
inline
:showInlineCTA="true"
:showSavedIcon="showSavedIcon"
v-model:countryCode="countryCode"
v-model:value="phone"
@confirm="handleConfirm"
@cancel="handleCancel"
>
<!-- Always visible suffix icons -->
<template #suffix>
<HLIcon>
<MessageQuestionCircleIcon />
</HLIcon>
</template>
<!-- Hover-only edit actions -->
<template #edit-actions>
<HLIcon @click="handleEdit">
<Edit02Icon />
</HLIcon>
<HLIcon>
<PhoneIcon />
</HLIcon>
<HLIcon @click="handleMail">
<Mail01Icon />
</HLIcon>
</template>
</HLInputPhone>
</template>ts
import { HLInputPhone, HLIcon } from '@platform-ui/highrise'
import { Edit02Icon, PhoneIcon, Mail01Icon, MessageDotsCircleIcon } from '@gohighlevel/ghl-icons/24/outline'
import { ref } from 'vue'
const phone = ref('+1 555-123-4567')
const countryCode = ref('US')
const showSavedIcon = ref(false)
const handleConfirm = value => {
// Show saved icon for 2 seconds after confirming
showSavedIcon.value = true
setTimeout(() => {
showSavedIcon.value = false
}, 2000)
console.log('Phone confirmed:', value)
}
const handleCancel = originalValue => {
console.log('Phone edit cancelled, reverted to:', originalValue)
}
const handleEdit = () => {
console.log('Edit action clicked')
}
const handleMail = () => {
console.log('Mail action clicked')
}Format Types
National format: (415) 555-2671
Try typing: 4155552671
International format: +1 415 555 2671
Try typing: 4155552671
html
<template>
<HLInputPhone
v-model:countryCode="nationalCountryCode"
v-model:value="nationalPhone"
format="national"
placeholder="Try typing: 4155552671"
@nationalFormat="handleNationalFormat"
/>
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const nationalPhone = ref('')
const nationalCountryCode = ref('US')
</script>html
<template>
<HLInputPhone
v-model:countryCode="internationalCountryCode"
v-model:value="internationalPhone"
format="international"
placeholder="Try typing: 4155552671"
@internationalFormat="handleInternationalFormat"
/>
</template>
<script setup lang="ts">
import { HLInputPhone } from '@platform-ui/highrise'
import { ref } from 'vue'
const internationalPhone = ref('')
const internationalCountryCode = ref('US')
</script>With Form Validation
html
<HLForm ref="formRef" :rules="rules">
<HLFormItem path="phone">
<HLInputPhone v-model:countryCode="countryCode" v-model:value="phone" @isValid="isFormPhoneValid = $event" />
</HLFormItem>
</HLForm>ts
const formRef = ref(null)
const phone = ref('+91845403166')
const countryCode = ref('IN')
const isFormPhoneValid = ref(true)
const rules = {
phone: {
required: true,
validator(_, updatedPhone) {
console.log('updatedPhone: ', updatedPhone)
if (isFormPhoneValid.value) return true
if (!updatedPhone) {
return new Error('Phone number is required')
}
if (/[a-zA-Z]/g.test(updatedPhone)) {
return new Error('Phone number can only contain numbers')
}
if (!isFormPhoneValid.value) {
return new Error('Please enter a valid phone number')
}
},
trigger: ['input', 'blur', 'change', 'focus'],
},
}Event Testing
This example shows how to test various input events. Try the following:
- Type a number and click the clear icon (×) to test the
@clearevent - Select text in the input to test the
@selectevent - Type a long number to make the input scrollable and scroll to test the
@scroll-toevent
Event Log:
No events logged yet. Try the actions above.
html
<script setup>
const eventLog = ref([])
const addEventLog = event => {
eventLog.value.unshift({ event, timestamp: new Date().toLocaleTimeString() })
// Keep only last 5 events
if (eventLog.value.length > 5) {
eventLog.value.pop()
}
}
</script>
<template>
<HLInputPhone
v-model:countryCode="countryCode"
v-model:value="phone"
placeholder="Test events here..."
@clear="addEventLog('Clear event triggered')"
@select="addEventLog('Select event triggered')"
@scroll-to="addEventLog('Scroll event triggered')"
/>
<div class="text-sm">
<p class="font-bold mb-2">Event Log:</p>
<div v-if="eventLog.length === 0" class="text-gray-500">No events logged yet. Try the actions above.</div>
<div v-for="(log, index) in eventLog" :key="index" class="text-gray-700">{{ log.timestamp }}: {{ log.event }}</div>
</div>
</template>Imports
ts
import { HLInputPhone, HLForm, HLFormItem } from '@platform-ui/highrise'Props
| Name | Type | Default | Description |
|---|---|---|---|
| id * | string | undefined | undefined | Unique identifier for the input |
| countryCode | string | undefined | undefined | Two-letter country code (ISO 3166-1 alpha-2). |
| value | string | undefined | undefined | Phone number value |
| disabled | boolean | false | Whether the input is disabled |
| disableCountryPicker | boolean | false | Whether to disable the country selection dropdown |
| autocomplete | boolean | false | Enable/disable browser autocomplete |
| size | 'lg' | 'md' | 'sm' | 'xs' | '2xs' | '3xs' | 'sm' | Size of the input |
| format | 'national' | 'international' | 'nationalFormat' | Phone number format |
| inline | boolean | false | Whether the input is inline |
| showInlineCTA | boolean | false | Shows confirm/cancel buttons during inline editing |
| showInlineBottomBorder | boolean | true | Controls bottom border visibility in inline mode |
| showSavedIcon | boolean | false | Shows a checkmark icon to indicate saved state |
Emits
| Name | Parameters | Description |
|---|---|---|
@internationalFormat | (phone: string) | Emitted when phone number is formatted internationally |
@nationalFormat | (phone: string) | Emitted when phone number is formatted nationally |
@isValid | (valid: boolean) | Emitted when phone number validation status changes |
@update:countryCode | (code: string) | Emitted when country code changes |
@update:value | (value: string) | Emitted when phone number value changes |
@confirm | (value: string) | Emitted when user confirms the input in inline mode |
@cancel | (originalValue: string) | Emitted when user cancels the input in inline mode |
@focus | (event: FocusEvent) | Emitted when the input receives focus |
@blur | (event: FocusEvent) | Emitted when the input loses focus |
@scrollTo | (event: Event) | Emitted when scrolling occurs in the input |
Slots
| Name | Description |
|---|---|
| suffix | Content to show after the input (always visible) |
| edit-actions | Content to show on hover in inline mode |
Methods
| Name | Parameters | Returns | Description |
|---|---|---|---|
focus | () => void | void | Focus the input number element |
blur | () => void | void | Blur the input number element |
clear | () => void | void | Clear the input number element |
select | () => void | void | Select the input number element |
scrollTo | () => void | void | Scroll to the input number element |