111 lines
3.5 KiB
Vue
111 lines
3.5 KiB
Vue
<template>
|
|
<div class="row mb-3">
|
|
<label
|
|
:for="inputId"
|
|
:class="[wide ? 'col-sm-4' : 'col-sm-2', isCheckbox ? 'form-check-label' : 'col-form-label']"
|
|
>
|
|
{{ label }}
|
|
<BIconInfoCircle v-if="tooltip !== undefined" v-tooltip :title="tooltip" />
|
|
</label>
|
|
<div :class="[wide ? 'col-sm-8' : 'col-sm-10']">
|
|
<div v-if="!isTextarea" :class="{ 'form-check form-switch': isCheckbox, 'input-group': postfix || prefix }">
|
|
<span v-if="prefix" class="input-group-text" :id="descriptionId">
|
|
{{ prefix }}
|
|
</span>
|
|
<input
|
|
v-model="model"
|
|
:class="[isCheckbox ? 'form-check-input' : 'form-control']"
|
|
:id="inputId"
|
|
:placeholder="placeholder"
|
|
:type="type"
|
|
:maxlength="maxlength"
|
|
:min="min"
|
|
:max="max"
|
|
:step="step"
|
|
:disabled="disabled"
|
|
:aria-describedby="descriptionId"
|
|
/>
|
|
<span v-if="postfix" class="input-group-text" :id="descriptionId">
|
|
{{ postfix }}
|
|
</span>
|
|
<slot />
|
|
</div>
|
|
<div v-else>
|
|
<textarea
|
|
v-model="model"
|
|
class="form-control"
|
|
:id="inputId"
|
|
:maxlength="maxlength"
|
|
:rows="rows"
|
|
:disabled="disabled"
|
|
:placeholder="placeholder"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { BIconInfoCircle } from 'bootstrap-icons-vue';
|
|
import { defineComponent } from 'vue';
|
|
|
|
export default defineComponent({
|
|
components: {
|
|
BIconInfoCircle,
|
|
},
|
|
props: {
|
|
modelValue: [String, Number, Boolean, Date],
|
|
label: String,
|
|
placeholder: String,
|
|
type: String,
|
|
maxlength: String,
|
|
min: String,
|
|
max: String,
|
|
step: String,
|
|
rows: String,
|
|
disabled: Boolean,
|
|
postfix: String,
|
|
prefix: String,
|
|
wide: Boolean,
|
|
tooltip: String,
|
|
},
|
|
data() {
|
|
return {};
|
|
},
|
|
computed: {
|
|
model: {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
get(): any {
|
|
if (this.type === 'checkbox') return !!this.modelValue;
|
|
return this.modelValue;
|
|
},
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
set(value: any) {
|
|
this.$emit('update:modelValue', value);
|
|
},
|
|
},
|
|
uniqueLabel() {
|
|
// normally, the label is sufficient to build a unique id
|
|
// if two inputs with the same label text on one page is required,
|
|
// use a unique placeholder even if it is a checkbox
|
|
return (
|
|
this.label?.replace(/[^A-Za-z0-9]/g, '') +
|
|
(this.placeholder ? this.placeholder.replace(/[^A-Za-z0-9]/g, '') : '')
|
|
);
|
|
},
|
|
inputId() {
|
|
return 'input' + this.uniqueLabel;
|
|
},
|
|
descriptionId() {
|
|
return 'desc' + this.uniqueLabel;
|
|
},
|
|
isTextarea() {
|
|
return this.type === 'textarea';
|
|
},
|
|
isCheckbox() {
|
|
return this.type === 'checkbox';
|
|
},
|
|
},
|
|
});
|
|
</script>
|