core/app/components/ui/phone-input/PhoneInput.vue

47 lines
1.5 KiB
Vue

<script setup lang="ts">
import { cn } from '@/lib/utils'
const props = defineProps<{
modelValue?: string
disabled?: boolean
class?: any
id?: string
placeholder?: string
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
function formatPhone(val: string): string {
const digits = val.replace(/\D/g, '').slice(0, 13)
const parts: string[] = []
if (digits.length > 0) parts.push(digits.slice(0, 4))
if (digits.length > 4) parts.push(digits.slice(4, 8))
if (digits.length > 8) parts.push(digits.slice(8, 13))
return parts.join(' ')
}
function onInput(e: Event) {
const raw = (e.target as HTMLInputElement).value
const formatted = formatPhone(raw)
emit('update:modelValue', formatted)
}
</script>
<template>
<input
:id="id"
:value="modelValue"
:disabled="disabled"
:placeholder="placeholder ?? 'Contoh: 0821 1234 5678'"
maxlength="14"
data-slot="input"
:class="cn(
'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3',
props.class,
)"
@input="onInput"
/>
</template>