Added custom dropdown
This commit is contained in:
@@ -1,32 +1,73 @@
|
||||
<template>
|
||||
<Listbox v-model="unitFilter" class="w-32 mx-5">
|
||||
<div class="relative">
|
||||
<ListboxButton class="w-full h-full bg-gray-dark text-white px-4 rounded-md hover:bg-blue transition-all">
|
||||
<!-- DROPDOWN DOCS -->
|
||||
<!--
|
||||
Params
|
||||
values: array of objects to populate dropdown with
|
||||
display: the key of the object to use as a display value
|
||||
currentIndex: the index of the currrently selected item, used to update the button
|
||||
|
||||
<span class="block w-full text-left">{{ currentValue }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
<Icon icon="carbon:chevron-sort" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
<ListboxOptions class="w-full bg-gray-dark last:rounded-b-md first:rounded-none absolute text-white">
|
||||
<ListboxOption v-for="unit in unitFilters" :key="unit.id" :value="unit" :disabled="unit.disabled"
|
||||
v-slot="{ active, selected }"
|
||||
class="ui-active:text-white p-3 hover:last:rounded-b-md hover:bg-blue transition-colors">
|
||||
<li>
|
||||
{{ unit.name }}
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</div>
|
||||
</Listbox>
|
||||
</template>
|
||||
Events
|
||||
changeSelection: sends the index of the option the user selects for use in the parent component
|
||||
-->
|
||||
|
||||
<script>
|
||||
import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/vue'
|
||||
|
||||
export default {
|
||||
props: ['currentValue', 'values'],
|
||||
emits: ['update:currentValue']
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
const props = defineProps(['values', 'display', 'currentIndex']);
|
||||
|
||||
var showMenu = ref(false);
|
||||
|
||||
const dropdownRef = ref(null);
|
||||
|
||||
const emit = defineEmits(['changeSelection']);
|
||||
|
||||
//click outside event handlers
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', handleClickOutside);
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', handleClickOutside);
|
||||
});
|
||||
|
||||
//handler for outside clicks
|
||||
function handleClickOutside(event) {
|
||||
if(dropdownRef.value && !dropdownRef.value.contains(event.target)) {
|
||||
showMenu.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
function toggleMenu() {
|
||||
showMenu.value = !showMenu.value;
|
||||
}
|
||||
|
||||
function selectOption(index) {
|
||||
emit('changeSelection', index);
|
||||
toggleMenu();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- focus div -->
|
||||
<div ref="dropdownRef" class="relative">
|
||||
<!-- list button -->
|
||||
<button @click="toggleMenu"
|
||||
class="relative w-full h-10 bg-gray-dark text-white px-4 rounded-md hover:bg-blue transition-colors py-2 pr-8"
|
||||
:class="{ 'rounded-b-none border-b border-b-gray-600': showMenu }">
|
||||
<span class="block w-full text-left"> {{ values[currentIndex][display] }}</span>
|
||||
<span class="absolute bottom-3 right-2">
|
||||
<Icon icon="carbon:chevron-sort" />
|
||||
</span>
|
||||
</button>
|
||||
<!-- list -->
|
||||
<div v-show="showMenu" class="bg-gray-dark rounded-b-md rounded-t-none absolute w-full text-white">
|
||||
<!-- list option -->
|
||||
<div v-for="(value, index) in values" @click="selectOption(index)"
|
||||
class="p-3 last:rounded-b-md hover:bg-blue w-full transition-colors cursor-pointer">
|
||||
{{ value[display] }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
Reference in New Issue
Block a user