parsley/app/javascript/components/AppDropdown.vue

81 lines
1.5 KiB
Vue
Raw Normal View History

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>