Added custom dropdown
This commit is contained in:
@@ -1,32 +1,73 @@
|
|||||||
<template>
|
<!-- DROPDOWN DOCS -->
|
||||||
<Listbox v-model="unitFilter" class="w-32 mx-5">
|
<!--
|
||||||
<div class="relative">
|
Params
|
||||||
<ListboxButton class="w-full h-full bg-gray-dark text-white px-4 rounded-md hover:bg-blue transition-all">
|
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>
|
Events
|
||||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2">
|
changeSelection: sends the index of the option the user selects for use in the parent component
|
||||||
<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>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/vue'
|
|
||||||
|
|
||||||
export default {
|
<script setup>
|
||||||
props: ['currentValue', 'values'],
|
import { ref, onMounted, onUnmounted } from 'vue';
|
||||||
emits: ['update:currentValue']
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleMenu() {
|
||||||
|
showMenu.value = !showMenu.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOption(index) {
|
||||||
|
emit('changeSelection', index);
|
||||||
|
toggleMenu();
|
||||||
|
}
|
||||||
</script>
|
</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