47 lines
1.5 KiB
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>
|