dropdown floating
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ChevronDownIcon, ChevronUpIcon} from '@heroicons/vue/24/outline';
|
import {ChevronDownIcon, ChevronUpIcon} from '@heroicons/vue/24/outline';
|
||||||
import {vOnClickOutside} from '@vueuse/components';
|
import {vOnClickOutside} from '@vueuse/components';
|
||||||
import {useEventListener} from '@vueuse/core';
|
import {useElementBounding, useEventListener} from '@vueuse/core';
|
||||||
import {ref} from 'vue';
|
import {computed, ref} from 'vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
inline?: boolean;
|
inline?: boolean;
|
||||||
@@ -15,6 +15,16 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const isOpen = ref(false);
|
const isOpen = ref(false);
|
||||||
|
const root = ref<HTMLElement | null>(null);
|
||||||
|
const floating = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
const { left, bottom, width } = useElementBounding(root);
|
||||||
|
|
||||||
|
const floatingStyle = computed(() => ({
|
||||||
|
left: `${left.value}px`,
|
||||||
|
top: `${bottom.value}px`,
|
||||||
|
minWidth: `${width.value}px`,
|
||||||
|
}));
|
||||||
|
|
||||||
const doAutoClose = () => {
|
const doAutoClose = () => {
|
||||||
if (props.autoClose) {
|
if (props.autoClose) {
|
||||||
@@ -30,7 +40,7 @@ useEventListener('keyup', e => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dropdown" :class="{'dropdown-open': isOpen, 'dropdown-close': !isOpen}" v-on-click-outside="doAutoClose">
|
<div ref="root" class="dropdown" :class="{'dropdown-open': isOpen, 'dropdown-close': !isOpen}" v-on-click-outside="[doAutoClose, { ignore: [floating] }]">
|
||||||
<button @click="isOpen = !isOpen" class="cursor-pointer">
|
<button @click="isOpen = !isOpen" class="cursor-pointer">
|
||||||
<Transition
|
<Transition
|
||||||
enter-active-class="transition-transform"
|
enter-active-class="transition-transform"
|
||||||
@@ -51,12 +61,21 @@ useEventListener('keyup', e => {
|
|||||||
<div v-if="inline && isOpen">
|
<div v-if="inline && isOpen">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="isOpen" class="relative">
|
|
||||||
<div class="z-10 divide-y rounded-b-md absolute">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
|
<Teleport to="body">
|
||||||
|
<Transition
|
||||||
|
enter-active-class="transition-opacity"
|
||||||
|
enter-from-class="opacity-0"
|
||||||
|
leave-from-class="transition-opacity"
|
||||||
|
leave-to-class="opacity-0">
|
||||||
|
<div v-if="!inline && isOpen" ref="floating" class="dropdown-floating" :style="floatingStyle">
|
||||||
|
<div class="divide-y rounded-b-md">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</Teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -66,4 +85,12 @@ useEventListener('keyup', e => {
|
|||||||
.chevron {
|
.chevron {
|
||||||
@apply w-4 h-4 me-1;
|
@apply w-4 h-4 me-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-floating {
|
||||||
|
@apply fixed z-10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-floating > div {
|
||||||
|
@apply bg-slate-800 rounded-b-md shadow-lg;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ const getIskBalance = (transaction: TransactionResponse) => {
|
|||||||
<template #button>
|
<template #button>
|
||||||
{{formatEveDate(t.data.date)}}
|
{{formatEveDate(t.data.date)}}
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<TransferList :transfers="t.data.transfers" />
|
||||||
<TransferList :transfers="t.data.transfers" />
|
|
||||||
</div>
|
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
@@ -89,10 +87,6 @@ tr:hover>td>.transfer-dropdown :deep(>button) {
|
|||||||
@apply bg-slate-900;
|
@apply bg-slate-900;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transfer-dropdown {
|
|
||||||
@appky z-1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.transfer-dropdown :deep(>button) {
|
.transfer-dropdown :deep(>button) {
|
||||||
@apply bg-slate-800 hover:bg-slate-900 border-none flex items-center w-full;
|
@apply bg-slate-800 hover:bg-slate-900 border-none flex items-center w-full;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,14 +63,6 @@ const logout = async () => {
|
|||||||
@apply w-full;
|
@apply w-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-dropdown :deep(>div) {
|
|
||||||
@apply w-full;
|
|
||||||
|
|
||||||
> div {
|
|
||||||
@apply w-full bg-slate-800;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-dropdown :deep(>button) {
|
.user-dropdown :deep(>button) {
|
||||||
@apply bg-slate-700 hover:bg-slate-800 border-none flex items-center w-full;
|
@apply bg-slate-700 hover:bg-slate-800 border-none flex items-center w-full;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user