core/app/components/PriceDisplay.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>