adrema/resources/js/components/FSelect.vue

113 lines
3.6 KiB
Vue

<template>
<label class="flex flex-col relative" :for="id" :class="{['h-field-'+size]: inset === true}">
<div class="relative h-full flex flex-col">
<span v-if="label && !inset" class="leading-none font-semibold relative z-10 text-gray-400" :class="{
'text-xs': size == 'sm',
'text-sm': size === null
}">{{ label }}<span v-show="required" class="text-red-300">&nbsp;*</span></span>
<span v-if="label && inset" class="absolute z-10 top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
'text-xs': size == 'sm',
'text-sm': size === null
}" v-text="label"></span>
<div class="relative h-full mt-1" :class="{['h-field-'+size]: inset === false}">
<select :value="value" @change="trigger"
class="border-gray-600 border-solid bg-gray-700 w-full appearance-none outline-none"
:class="{
'rounded-lg text-sm border-2 p-2 text-gray-300': size === null,
'rounded-lg py-2 px-2 text-xs border-2 text-gray-800': size == 'sm'
}"
>
<option v-if="placeholder" v-html="placeholder" :value="null"></option>
<option v-for="(option, key) in parsedOptions" :key="key"
v-html="option" :value="key"
></option>
</select>
<div class="absolute pointer-events-none top-0 right-0 -mx-1 flex items-center h-full mr-4 cursor-pointer">
<div v-if="hint" v-tooltip="hint" class="px-1">
<sprite src="info-button" class="w-5 h-5 text-indigo-200"></sprite>
</div>
<div class="px-1 relative">
<sprite class="w-3 h-3 fill-current" src="chevron-down"></sprite>
</div>
</div>
</div>
</div>
</label>
</template>
<script>
export default {
props: {
id: {},
inset: {
type: Boolean,
default: false
},
size: {
default: function() { return null; }
},
emptyLabel: {
default: false,
type: Boolean
},
value: {
default: undefined
},
label: {
default: null
},
required: {
type: Boolean,
default: false
},
placeholder: {
default: '--kein--',
type: String
},
def: {
required: false,
type: Number,
default: -1
},
hint: {},
options: {
default: function() { return []; }
}
},
computed: {
parsedOptions() {
return this.options;
}
},
methods: {
trigger(v) {
this.$emit('input', isNaN(parseInt(v.target.value))
? (v.target.value ? v.target.value : null)
: parseInt(v.target.value)
);
},
clear() {
this.$emit('input', null);
}
},
mounted() {
if (this.def !== -1 && typeof this.value === 'undefined') {
this.$emit('input', this.def);
return;
}
if (this.placeholder && typeof this.value === 'undefined') {
this.$emit('input', null);
}
}
};
</script>
<style scope>
.inset-bg {
background: linear-gradient(to bottom, hsl(247.5, 66.7%, 97.6%) 0%, hsl(247.5, 66.7%, 97.6%) 41%, hsl(0deg 0% 100%) 41%, hsl(180deg 0% 100%) 100%);
}
</style>