46 lines
1.4 KiB
Vue
46 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
import {vElementHover} from '@vueuse/components';
|
|
import {useElementBounding} from '@vueuse/core';
|
|
import {computed, ref} from 'vue';
|
|
import {useSharedWindowSize} from './tooltip';
|
|
|
|
const open = defineModel('open', { default: false });
|
|
|
|
const { width, height } = useSharedWindowSize();
|
|
const mainDiv = ref<HTMLDivElement | null>(null);
|
|
const { top, left } = useElementBounding(mainDiv);
|
|
|
|
const positions = computed(() => {
|
|
if (top.value < height.value / 2) {
|
|
if (left.value < width.value / 2) {
|
|
return ['top', 'left'];
|
|
}
|
|
return ['top', 'right'];
|
|
}
|
|
if (left.value < width.value / 2) {
|
|
return ['bottom', 'left'];
|
|
}
|
|
return ['bottom', 'right'];
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div ref="mainDiv" class="flex flex-col items-center justify-center" :class="{
|
|
'open': open,
|
|
'tooltip-top': positions.includes('top'),
|
|
'tooltip-bottom': positions.includes('bottom'),
|
|
'tooltip-left': positions.includes('left'),
|
|
'tooltip-right': positions.includes('right')
|
|
}">
|
|
<div v-element-hover="(h: boolean) => open = h" class="m-auto header">
|
|
<slot name="header" />
|
|
</div>
|
|
<div v-if="open" class="m-auto">
|
|
<div class="z-10 relative">
|
|
<div class="absolute">
|
|
<slot />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template> |