Files
web/src/components/MoneyInput.vue
T
2026-08-08 14:12:30 +03:30

77 lines
1.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed } from 'vue'
import {
fromGroupedInput,
rialToToman,
toGroupedDisplay,
tomanToRial,
} from '@/utils/money'
/**
* Money field bound to **rial** storage values (API/DB).
* User types and sees **toman** (÷10 / ×10 at the edges).
* With `nullable`, empty input emits `null` (for optional thresholds).
*/
const props = withDefaults(
defineProps<{
value: number | null | undefined
size?: 'large' | 'middle' | 'small'
placeholder?: string
allowNegative?: boolean
disabled?: boolean
nullable?: boolean
}>(),
{
size: 'large',
placeholder: '',
allowNegative: false,
disabled: false,
nullable: false,
},
)
const emit = defineEmits<{
(e: 'update:value', value: number | null): void
}>()
const display = computed(() => {
if (props.nullable && (props.value == null || props.value === undefined)) return ''
return toGroupedDisplay(rialToToman(props.value ?? 0))
})
function onInput(raw: string | number) {
const text = String(raw ?? '').trim()
if (props.nullable && !text) {
emit('update:value', null)
return
}
const toman = fromGroupedInput(text, props.allowNegative)
emit('update:value', tomanToRial(toman))
}
</script>
<template>
<a-input
class="money-input"
dir="ltr"
:size="size"
:placeholder="placeholder"
:disabled="disabled"
:value="display"
allow-clear
@update:value="onInput"
/>
</template>
<style scoped>
.money-input {
width: 100%;
}
.money-input :deep(input) {
font-variant-numeric: tabular-nums;
text-align: left;
direction: ltr;
}
</style>