143 lines
2.6 KiB
Vue
143 lines
2.6 KiB
Vue
<style lang="scss" scoped>
|
|
.optional-badge {
|
|
border-radius: 4px;
|
|
color: #283e59;
|
|
background-color: #edf2f9;
|
|
padding: 1px 3px;
|
|
}
|
|
|
|
.length {
|
|
top: 10px;
|
|
right: 10px;
|
|
background-color: #e5eeff;
|
|
padding: 3px 4px;
|
|
}
|
|
|
|
.counter {
|
|
padding-right: 64px;
|
|
}
|
|
</style>
|
|
|
|
<template>
|
|
<div :class="divOuterClass">
|
|
<label v-if="label" class="block text-sm mb-2" :for="id">
|
|
{{ label }}
|
|
<span v-if="!required" class="optional-badge text-xs">
|
|
optional
|
|
</span>
|
|
</label>
|
|
|
|
<div class="relative component">
|
|
<input
|
|
:class="localInputClasses"
|
|
:value="modelValue"
|
|
@input="$emit('update:modelValue', $event.target.value)"
|
|
ref="input"
|
|
:type="type"
|
|
:maxlength="maxlength"
|
|
:id="id"
|
|
:required="required"
|
|
:autofocus="autofocus"
|
|
@focus="showMaxLength"
|
|
@blur="displayMaxLength = false"
|
|
>
|
|
<span v-if="maxlength && displayMaxLength" class="length absolute text-xs rounded">
|
|
{{ charactersLeft }}
|
|
</span>
|
|
</div>
|
|
|
|
<p v-if="help" class="text-sm mb-3">
|
|
{{ help }}
|
|
</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
emits: ['update:modelValue'],
|
|
|
|
props: {
|
|
id: {
|
|
type: String,
|
|
default: 'text-input-',
|
|
},
|
|
inputClass: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
divOuterClass: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
modelValue: {
|
|
type: [String, Number],
|
|
default: '',
|
|
},
|
|
type: {
|
|
type: String,
|
|
default: 'text',
|
|
},
|
|
name: {
|
|
type: String,
|
|
default: 'input',
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
help: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
label: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
required: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
autofocus: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
maxlength: {
|
|
type: Number,
|
|
default: null,
|
|
},
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
localInputClasses: '',
|
|
displayMaxLength: false,
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
charactersLeft() {
|
|
var char = 0;
|
|
if (this.modelValue) {
|
|
char = this.modelValue.length;
|
|
}
|
|
|
|
return `${this.maxlength - char} / ${this.maxlength}`;
|
|
},
|
|
},
|
|
|
|
created() {
|
|
this.localInputClasses = 'border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm ' + this.inputClass;
|
|
},
|
|
|
|
methods: {
|
|
focus() {
|
|
this.$refs.input.focus()
|
|
},
|
|
|
|
showMaxLength() {
|
|
this.displayMaxLength = true;
|
|
}
|
|
}
|
|
}
|
|
</script>
|