parsley/app/javascript/components/AppDropdown.vue

81 lines
1.5 KiB
Vue

<template>
<div ref="dropdown" class="dropdown" :class="{'is-active': open, 'is-hoverable': hover}">
<div class="dropdown-trigger">
<slot name="button">
<button type="button" class="button" :class="buttonClass" @click="toggle">
<span>{{ label }}</span>
<app-icon icon="caret-bottom" size="xs"></app-icon>
</button>
</slot>
</div>
<div class="dropdown-menu">
<div class="dropdown-content">
<slot>
Default Content
</slot>
</div>
</div>
</div>
</template>
<script setup>
import { useTemplateRef } from "vue";
import { onClickOutside } from '@vueuse/core'
const emit = defineEmits(["close", "open"]);
const props = defineProps({
open: {
required: false,
type: Boolean,
default: false
},
hover: {
required: false,
type: Boolean,
default: false
},
label: {
required: false,
type: String,
default: 'Select'
},
buttonClass: {
required: false,
default: ""
}
});
const dropdownElement = useTemplateRef("dropdown");
onClickOutside(dropdownElement, event => handleOutsideClick(event))
function toggle() {
if (props.open) {
triggerClose();
} else {
triggerOpen();
}
}
function triggerOpen() {
emit("open");
}
function triggerClose() {
emit("close");
}
function handleOutsideClick(evt) {
if (props.open) {
if (!dropdownElement.value.contains(evt.target)) {
triggerClose();
}
}
}
</script>