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