2022-03-31 20:23:38 -05:00
|
|
|
<template>
|
2022-12-10 10:44:21 -06:00
|
|
|
<div class="relative w-full" v-click-outside="clickedOutside">
|
2023-12-10 17:53:27 -06:00
|
|
|
<p class="text-sm font-semibold" :class="disabled ? 'text-fg-muted' : ''">{{ label }}</p>
|
|
|
|
<button type="button" :disabled="disabled" class="relative w-full border border-border rounded shadow-sm pl-3 pr-8 py-2 text-left focus:outline-none text-sm" :class="buttonClass" aria-haspopup="listbox" aria-expanded="true" @click.stop.prevent="clickShowMenu">
|
|
|
|
<span class="flex items-center" :class="!selectedText ? 'text-fg-muted' : 'text-fg'">
|
2022-04-01 18:33:40 -05:00
|
|
|
<span class="block truncate" :class="small ? 'text-sm' : ''">{{ selectedText || placeholder || '' }}</span>
|
2022-03-31 20:23:38 -05:00
|
|
|
</span>
|
|
|
|
<span class="ml-3 absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
|
|
|
<span class="material-icons">expand_more</span>
|
|
|
|
</span>
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<transition name="menu">
|
2023-12-10 17:53:27 -06:00
|
|
|
<ul v-show="showMenu" class="absolute z-10 -mt-px w-full bg-primary border border-border shadow-lg max-h-56 rounded-b-md py-1 ring-1 ring-bg ring-opacity-5 overflow-auto focus:outline-none text-sm" role="listbox">
|
2022-03-31 20:23:38 -05:00
|
|
|
<template v-for="item in items">
|
2023-12-10 17:53:27 -06:00
|
|
|
<li :key="item.value" class="text-fg select-none relative py-2 cursor-pointer hover:bg-black-400" role="option" @click="clickedOption(item.value)">
|
2022-03-31 20:23:38 -05:00
|
|
|
<div class="flex items-center">
|
|
|
|
<span class="font-normal ml-3 block truncate font-sans text-sm">{{ item.text }}</span>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</template>
|
|
|
|
</ul>
|
|
|
|
</transition>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
export default {
|
|
|
|
props: {
|
|
|
|
value: [String, Number],
|
|
|
|
label: {
|
|
|
|
type: String,
|
|
|
|
default: ''
|
|
|
|
},
|
|
|
|
items: {
|
|
|
|
type: Array,
|
|
|
|
default: () => []
|
|
|
|
},
|
|
|
|
disabled: Boolean,
|
2022-04-01 18:33:40 -05:00
|
|
|
small: Boolean,
|
|
|
|
placeholder: String
|
2022-03-31 20:23:38 -05:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
showMenu: false
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
selected: {
|
|
|
|
get() {
|
|
|
|
return this.value
|
|
|
|
},
|
|
|
|
set(val) {
|
|
|
|
this.$emit('input', val)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
selectedItem() {
|
|
|
|
return this.items.find((i) => i.value === this.selected)
|
|
|
|
},
|
|
|
|
selectedText() {
|
|
|
|
return this.selectedItem ? this.selectedItem.text : ''
|
|
|
|
},
|
|
|
|
buttonClass() {
|
2023-01-08 15:32:15 -06:00
|
|
|
const classes = []
|
2022-03-31 20:23:38 -05:00
|
|
|
if (this.small) classes.push('h-9')
|
|
|
|
else classes.push('h-10')
|
|
|
|
|
2023-12-10 17:53:27 -06:00
|
|
|
if (this.disabled) classes.push('cursor-not-allowed border-border bg-primary bg-opacity-70 border-opacity-70 text-fg-muted')
|
|
|
|
else classes.push('cursor-pointer border-border bg-primary text-fg')
|
2022-03-31 20:23:38 -05:00
|
|
|
|
|
|
|
return classes.join(' ')
|
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
clickShowMenu() {
|
|
|
|
if (this.disabled) return
|
|
|
|
this.showMenu = !this.showMenu
|
|
|
|
},
|
|
|
|
clickedOutside() {
|
|
|
|
this.showMenu = false
|
|
|
|
},
|
|
|
|
clickedOption(itemValue) {
|
|
|
|
this.selected = itemValue
|
|
|
|
this.showMenu = false
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {}
|
|
|
|
}
|
|
|
|
</script>
|