Created
August 17, 2022 08:34
-
-
Save lao9s/8e66aaf203bfe5a067b958c8fc9e9de0 to your computer and use it in GitHub Desktop.
import Dropdown from "@/Components/Dropdown.vue" <Dropdown align="left" :closeable-on-content="false" @close="$emit('close')"> <template #trigger> <button type="button" v-tooltip="'Emoji'" class="hover:text-o
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script setup> | |
import {computed, onMounted, onUnmounted, ref} from 'vue'; | |
const props = defineProps({ | |
align: { | |
type: String, | |
default: 'right', | |
}, | |
widthClasses: { | |
type: String, | |
default: 'w-48', | |
}, | |
contentClasses: { | |
type: Array, | |
default: () => ['py-0', 'bg-white'], | |
}, | |
closeableOnContent: { | |
type: Boolean, | |
default: true, | |
}, | |
}); | |
const emit = defineEmits(['close']); | |
let open = ref(false); | |
const closeOnEscape = (e) => { | |
if (open.value && e.key === 'Escape') { | |
close(); | |
} | |
}; | |
const closeOnContentClick = () => { | |
if (props.closeableOnContent) { | |
close(); | |
} | |
} | |
const close = () => { | |
open.value = false; | |
emit('close'); | |
} | |
onMounted(() => document.addEventListener('keydown', closeOnEscape)); | |
onUnmounted(() => document.removeEventListener('keydown', closeOnEscape)); | |
const alignmentClasses = computed(() => { | |
if (props.align === 'left') { | |
return 'origin-top-left left-0'; | |
} | |
if (props.align === 'right') { | |
return 'origin-top-right right-0'; | |
} | |
return 'origin-top'; | |
}); | |
</script> | |
<template> | |
<div class="relative"> | |
<div @click="open = ! open"> | |
<slot name="trigger"/> | |
</div> | |
<!-- Full Screen Dropdown Overlay --> | |
<div v-show="open" class="fixed inset-0 z-40" @click="close"/> | |
<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-1 rounded-md shadow-mix" | |
:class="[widthClasses, alignmentClasses]" | |
style="display: none;" | |
@click="closeOnContentClick" | |
> | |
<div class="rounded-md border border-gray-200" :class="contentClasses"> | |
<slot name="content"/> | |
</div> | |
</div> | |
</transition> | |
</div> | |
</template> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment