89 lines
2.2 KiB
Vue
89 lines
2.2 KiB
Vue
<script setup>
|
|
import { watch, onMounted } from "vue";
|
|
import { useCurrencyInput } from "vue-currency-input";
|
|
|
|
const props = defineProps({
|
|
modelValue: { type: [Number, String, null], default: null },
|
|
id: String,
|
|
name: String,
|
|
placeholder: { type: String, default: "0,00" },
|
|
disabled: Boolean,
|
|
required: Boolean,
|
|
currency: { type: String, default: "EUR" },
|
|
locale: { type: String, default: "sl-SI" },
|
|
precision: { type: [Number, Object], default: 2 },
|
|
allowNegative: { type: Boolean, default: false },
|
|
useGrouping: { type: Boolean, default: true },
|
|
});
|
|
|
|
const emit = defineEmits(["update:modelValue", "change"]);
|
|
|
|
const { inputRef, numberValue, setValue, setOptions } = useCurrencyInput({
|
|
currency: props.currency,
|
|
locale: props.locale,
|
|
precision: props.precision,
|
|
useGrouping: props.useGrouping,
|
|
valueRange: props.allowNegative ? {} : { min: 0 },
|
|
});
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(val) => {
|
|
const numeric = typeof val === "string" ? parseFloat(val) : val;
|
|
if (numeric !== numberValue.value) {
|
|
setValue(isNaN(numeric) ? null : numeric);
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
watch(numberValue, (val) => {
|
|
emit("update:modelValue", val);
|
|
});
|
|
|
|
watch(
|
|
() => [
|
|
props.currency,
|
|
props.locale,
|
|
props.precision,
|
|
props.useGrouping,
|
|
props.allowNegative,
|
|
],
|
|
() => {
|
|
setOptions({
|
|
currency: props.currency,
|
|
locale: props.locale,
|
|
precision: props.precision,
|
|
useGrouping: props.useGrouping,
|
|
valueRange: props.allowNegative ? {} : { min: 0 },
|
|
});
|
|
}
|
|
);
|
|
|
|
onMounted(() => {
|
|
if (props.modelValue != null) {
|
|
const numeric =
|
|
typeof props.modelValue === "string"
|
|
? parseFloat(props.modelValue)
|
|
: props.modelValue;
|
|
setValue(isNaN(numeric) ? null : numeric);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<input
|
|
ref="inputRef"
|
|
:id="id"
|
|
:name="name"
|
|
type="text"
|
|
inputmode="decimal"
|
|
:placeholder="placeholder"
|
|
:disabled="disabled"
|
|
:required="required"
|
|
class="mt-1 block w-full rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-800 dark:border-gray-600"
|
|
autocomplete="off"
|
|
@change="$emit('change', numberValue)"
|
|
/>
|
|
</template>
|