88 lines
1.9 KiB
Vue
88 lines
1.9 KiB
Vue
<script setup>
|
|
import { computed, ref } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
const emit = defineEmits(['update:modelValue', 'update:options', 'keyup.enter']);
|
|
|
|
const $props = defineProps({
|
|
modelValue: {
|
|
type: [String, Number],
|
|
default: null,
|
|
},
|
|
isOutlined: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
});
|
|
|
|
const { t } = useI18n();
|
|
const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
|
|
const vnInputRef = ref(null);
|
|
const value = computed({
|
|
get() {
|
|
return $props.modelValue;
|
|
},
|
|
set(value) {
|
|
emit('update:modelValue', value);
|
|
},
|
|
});
|
|
const hover = ref(false);
|
|
const styleAttrs = computed(() => {
|
|
return $props.isOutlined
|
|
? {
|
|
dense: true,
|
|
outlined: true,
|
|
rounded: true,
|
|
}
|
|
: {};
|
|
});
|
|
|
|
const onEnterPress = () => {
|
|
emit('keyup.enter');
|
|
};
|
|
|
|
const handleValue = (val = null) => {
|
|
value.value = val;
|
|
};
|
|
|
|
const focus = () => {
|
|
vnInputRef.value.focus();
|
|
};
|
|
|
|
defineExpose({
|
|
focus,
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
@mouseover="hover = true"
|
|
@mouseleave="hover = false"
|
|
:rules="$attrs.required ? [requiredFieldRule] : null"
|
|
>
|
|
<QInput
|
|
ref="vnInputRef"
|
|
v-model="value"
|
|
v-bind="{ ...$attrs, ...styleAttrs }"
|
|
:type="$attrs.type"
|
|
:class="{ required: $attrs.required }"
|
|
@keyup.enter="onEnterPress()"
|
|
:clearable="false"
|
|
>
|
|
<template v-if="$slots.prepend" #prepend>
|
|
<slot name="prepend" />
|
|
</template>
|
|
|
|
<template #append>
|
|
<slot name="append" v-if="$slots.append" />
|
|
<QIcon
|
|
name="close"
|
|
size="xs"
|
|
v-if="hover && value"
|
|
@click="handleValue(null)"
|
|
></QIcon>
|
|
</template>
|
|
</QInput>
|
|
</div>
|
|
</template>
|