adrema/resources/js/components/form/Text.vue

167 lines
4.2 KiB
Vue
Raw Normal View History

2021-04-10 19:45:11 +02:00
<template>
2024-06-28 10:23:42 +02:00
<label class="flex flex-col group" :for="id" :class="sizes[size]">
<span v-if="label" class="font-semibold leading-none text-gray-400 group-[.field-base]:text-sm group-[.field-sm]:text-xs">
2021-08-22 16:15:16 +02:00
{{ label }}
<span v-show="required" class="text-red-800">&nbsp;*</span>
</span>
2024-06-28 10:23:42 +02:00
<div class="relative flex-none flex">
<input
:name="name"
:type="type"
:value="transformedValue"
:disabled="disabled"
placeholder=""
:min="min"
:max="max"
class="group-[.field-base]:h-[35px] group-[.field-sm]:h-[23px] group-[.field-base]:border-2 group-[.field-sm]:border border-gray-600 border-solid text-gray-300 bg-gray-700 leading-none rounded-lg group-[.field-base]:text-sm group-[.field-sm]:text-xs py-0 group-[.field-base]:px-2 group-[.field-sm]:px-1 w-full"
@input="onInput"
@change="onChange"
2024-06-28 11:49:47 +02:00
@focus="focus = true"
@blur="focus = false"
2024-06-28 10:23:42 +02:00
/>
<div v-if="hint" class="h-full items-center flex absolute top-0 right-0">
2021-08-22 16:15:16 +02:00
<div v-tooltip="hint">
2024-06-28 10:23:42 +02:00
<ui-sprite src="info-button" class="text-primary-700"></ui-sprite>
2021-04-10 19:45:11 +02:00
</div>
</div>
</div>
</label>
</template>
2024-06-28 11:49:47 +02:00
<script setup>
2021-04-10 19:45:11 +02:00
import wNumb from 'wnumb';
2024-06-28 11:49:47 +02:00
import {ref, computed} from 'vue';
const emit = defineEmits(['update:modelValue']);
2021-04-10 19:45:11 +02:00
var numb = {
natural: wNumb({
mark: '',
thousand: '',
decimals: 0,
2024-06-27 21:42:47 +02:00
decoder: (a) => a * 100,
encoder: (a) => a / 100,
2021-08-22 16:15:16 +02:00
}),
2021-04-10 19:45:11 +02:00
area: wNumb({
mark: ',',
thousand: '',
decimals: 2,
2024-06-27 21:42:47 +02:00
decoder: (a) => a * 100,
encoder: (a) => a / 100,
}),
2021-04-10 19:45:11 +02:00
};
var transformers = {
none: {
display: {
2024-06-27 21:42:47 +02:00
to: (v) => v,
from: (v) => v,
2021-04-10 19:45:11 +02:00
},
edit: {
2024-06-27 21:42:47 +02:00
to: (v) => v,
from: (v) => v,
},
2021-04-10 19:45:11 +02:00
},
area: {
display: {
2024-06-27 21:42:47 +02:00
to: (v) => (v === null ? '' : numb.area.to(v)),
from: (v) => (v === '' ? null : numb.area.from(v)),
2021-04-10 19:45:11 +02:00
},
edit: {
to(v) {
if (v === null) {
return '';
}
if (Math.round(v / 100) * 100 === v) {
2024-06-27 21:42:47 +02:00
return numb.natural.to(v);
}
2024-06-27 21:42:47 +02:00
return numb.area.to(v);
2021-08-22 16:15:16 +02:00
},
from(v) {
if (v === '') {
return null;
}
if (v.indexOf(',') === -1) {
2024-06-27 21:42:47 +02:00
return numb.natural.from(v);
}
2021-08-22 16:15:16 +02:00
2024-06-27 21:42:47 +02:00
return numb.area.from(v);
},
},
},
2021-04-10 19:45:11 +02:00
};
2024-06-28 11:49:47 +02:00
const props = defineProps({
mode: {
type: String,
default: () => 'none',
2021-04-10 19:45:11 +02:00
},
2024-06-28 11:49:47 +02:00
required: {
type: Boolean,
default: () => false,
2021-04-10 19:45:11 +02:00
},
2024-06-28 11:49:47 +02:00
size: {
type: String,
default: () => 'base',
2021-04-10 19:45:11 +02:00
},
2024-06-28 11:49:47 +02:00
id: {
type: String,
required: true,
},
2024-06-28 11:49:47 +02:00
hint: {
type: String,
default: () => '',
2023-12-30 22:21:08 +01:00
},
2024-06-28 11:49:47 +02:00
modelValue: {
type: String,
default: () => '',
},
label: {
type: String,
default: () => '',
},
type: {
type: String,
default: () => 'text',
},
disabled: {
default: () => false,
type: Boolean,
},
min: {
type: Number,
default: () => undefined,
},
max: {
type: Number,
default: () => undefined,
},
name: {
required: true,
type: String,
},
});
const focus = ref(false);
const sizes = ref({
sm: 'field-sm',
base: 'field-base',
lg: 'field-lg',
});
2021-04-10 19:45:11 +02:00
2024-06-28 11:49:47 +02:00
const transformedValue = computed({
get: () => transformers[props.mode][focus.value ? 'edit' : 'display'].to(props.modelValue),
set: (v) => emit('update:modelValue', transformers[props.mode][focus.value ? 'edit' : 'display'].from(v)),
});
function onChange(v) {
if (props.mode !== 'none') {
transformedValue.value = v.target.value;
}
2021-04-10 19:45:11 +02:00
}
2024-06-28 11:49:47 +02:00
function onInput(v) {
if (props.mode === 'none') {
transformedValue.value = v.target.value;
}
}
</script>