generated from corrad-software/corrad-af-2024
143 lines
3.1 KiB
Vue
143 lines
3.1 KiB
Vue
<script setup>
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: [String, Number, Array],
|
|
default: ''
|
|
},
|
|
options: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: 'Select an option'
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
required: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
error: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
label: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
size: {
|
|
type: String,
|
|
default: 'md'
|
|
},
|
|
multiple: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
});
|
|
|
|
const emit = defineEmits(['update:modelValue']);
|
|
|
|
const updateValue = (event) => {
|
|
emit('update:modelValue', event.target.value);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="rs-select-wrapper">
|
|
<label v-if="label" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
{{ label }}
|
|
<span v-if="required" class="text-red-500">*</span>
|
|
</label>
|
|
|
|
<select
|
|
:value="modelValue"
|
|
@change="updateValue"
|
|
:disabled="disabled"
|
|
:required="required"
|
|
:multiple="multiple"
|
|
class="rs-select"
|
|
:class="{
|
|
'rs-select-sm': size === 'sm',
|
|
'rs-select-md': size === 'md',
|
|
'rs-select-lg': size === 'lg',
|
|
'rs-select-error': error,
|
|
'rs-select-disabled': disabled
|
|
}"
|
|
>
|
|
<option v-if="!multiple && placeholder" value="" disabled>
|
|
{{ placeholder }}
|
|
</option>
|
|
<option
|
|
v-for="option in options"
|
|
:key="option.value || option"
|
|
:value="option.value || option"
|
|
>
|
|
{{ option.label || option }}
|
|
</option>
|
|
</select>
|
|
|
|
<div v-if="error" class="rs-select-error-message">
|
|
{{ error }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.rs-select-wrapper {
|
|
@apply w-full;
|
|
}
|
|
|
|
.rs-select {
|
|
@apply w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors appearance-none;
|
|
border-color: rgb(var(--fk-border-color));
|
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e");
|
|
background-position: right 0.5rem center;
|
|
background-repeat: no-repeat;
|
|
background-size: 1.5em 1.5em;
|
|
padding-right: 2.5rem;
|
|
}
|
|
|
|
.rs-select:hover {
|
|
@apply border-gray-400 dark:border-gray-500;
|
|
}
|
|
|
|
.rs-select:focus {
|
|
@apply outline-none ring-2 ring-blue-500 border-blue-500;
|
|
}
|
|
|
|
.rs-select-sm {
|
|
@apply px-2 py-1 text-sm;
|
|
padding-right: 2rem;
|
|
}
|
|
|
|
.rs-select-md {
|
|
@apply px-3 py-2 text-sm;
|
|
padding-right: 2.5rem;
|
|
}
|
|
|
|
.rs-select-lg {
|
|
@apply px-4 py-3 text-base;
|
|
padding-right: 3rem;
|
|
}
|
|
|
|
.rs-select-error {
|
|
@apply border-red-500 dark:border-red-500 focus:ring-red-500 focus:border-red-500;
|
|
}
|
|
|
|
.rs-select-disabled {
|
|
@apply bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 cursor-not-allowed;
|
|
}
|
|
|
|
.rs-select-error-message {
|
|
@apply text-sm text-red-500 mt-1;
|
|
}
|
|
|
|
.rs-select[multiple] {
|
|
background-image: none;
|
|
padding-right: 0.75rem;
|
|
min-height: 6rem;
|
|
}
|
|
</style> |