Skip to content

Instantly share code, notes, and snippets.

@mostafizurhimself
Created October 19, 2021 11:21
Show Gist options
  • Save mostafizurhimself/9124bdea207b964edcefe786d4cf0d87 to your computer and use it in GitHub Desktop.
Save mostafizurhimself/9124bdea207b964edcefe786d4cf0d87 to your computer and use it in GitHub Desktop.
Custom dropdown component with Vue 3
<template>
<div class="relative">
<div @click="open = ! open">
<slot name="trigger"></slot>
</div>
<!-- Full Screen Dropdown Overlay -->
<div v-show="open" class="fixed inset-0 z-40" @click="open = false">
</div>
<transition enter-active-class="transition ease-out duration-200" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
<div v-show="open" class="absolute z-50 mt-2 rounded-md shadow-lg" :class="[widthClass, alignmentClasses]" style="display: none;">
<div class="rounded-md ring-1 ring-black ring-opacity-5" :class="contentClasses">
<slot name="content"></slot>
</div>
</div>
</transition>
</div>
</template>
<script>
import { onMounted, onUnmounted, ref } from "vue";
export default {
props: {
align: {
default: "right",
},
width: {
default: "48",
},
contentClasses: {
default: () => ["py-1", "bg-white"],
},
},
setup() {
let open = ref(false);
const closeOnEscape = (e) => {
if (open.value && e.keyCode === 27) {
open.value = false;
}
};
onMounted(() => document.addEventListener("keydown", closeOnEscape));
onUnmounted(() =>
document.removeEventListener("keydown", closeOnEscape)
);
return {
open,
};
},
computed: {
widthClass() {
return {
40: "w-40",
44: "w-44",
48: "w-48",
64: "w-64",
72: "w-72",
80: "w-80",
}[this.width.toString()];
},
alignmentClasses() {
if (this.align === "left") {
return "origin-top-left left-0";
} else if (this.align === "right") {
return "origin-top-right right-0";
} else {
return "origin-top";
}
},
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment