67 lines
1.5 KiB
Vue
67 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
import {
|
|
InputGroup,
|
|
InputGroupAddon,
|
|
InputGroupInput,
|
|
InputGroupText,
|
|
} from '@/components/ui/input-group'
|
|
|
|
const props = withDefaults(defineProps<{
|
|
value?: number | string
|
|
modelValue?: string
|
|
placeholder?: string
|
|
readonly?: boolean
|
|
disabled?: boolean
|
|
}>(), {
|
|
placeholder: '0',
|
|
readonly: false,
|
|
disabled: false,
|
|
})
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [value: string]
|
|
}>()
|
|
|
|
function formatIdr(n: number | string): string {
|
|
const num = typeof n === 'string' ? parseInt(n.replace(/\D/g, ''), 10) : n
|
|
if (isNaN(num)) return ''
|
|
return num.toLocaleString('id-ID')
|
|
}
|
|
|
|
const displayValue = computed(() => {
|
|
if (props.modelValue !== undefined) return formatIdr(props.modelValue)
|
|
if (props.value == null) return ''
|
|
return formatIdr(props.value)
|
|
})
|
|
|
|
function onInput(e: Event) {
|
|
const raw = (e.target as HTMLInputElement).value.replace(/\D/g, '')
|
|
emit('update:modelValue', raw)
|
|
}
|
|
|
|
function onFocus(e: FocusEvent) {
|
|
const el = e.target as HTMLInputElement
|
|
const pos = el.value.length
|
|
el.setSelectionRange(pos, pos)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<InputGroup>
|
|
<InputGroupAddon>
|
|
<InputGroupText>Rp</InputGroupText>
|
|
</InputGroupAddon>
|
|
<InputGroupInput
|
|
:model-value="displayValue"
|
|
:placeholder="placeholder"
|
|
:readonly="readonly"
|
|
:disabled="disabled"
|
|
type="text"
|
|
inputmode="numeric"
|
|
class="font-medium"
|
|
@input="onInput"
|
|
@focus="onFocus"
|
|
/>
|
|
</InputGroup>
|
|
</template>
|