163 lines
4.0 KiB
Vue
163 lines
4.0 KiB
Vue
<script setup>
|
|
import { ref } from 'vue';
|
|
import { arrow, useFloating, offset } from '@floating-ui/vue';
|
|
|
|
// 4 个方向按钮的 refs
|
|
const referenceBottom = ref(null);
|
|
const referenceTop = ref(null);
|
|
const referenceLeft = ref(null);
|
|
const referenceRight = ref(null);
|
|
|
|
const floatingBottom = ref(null);
|
|
const floatingTop = ref(null);
|
|
const floatingLeft = ref(null);
|
|
const floatingRight = ref(null);
|
|
|
|
const arrowBottom = ref(null);
|
|
const arrowTop = ref(null);
|
|
const arrowLeft = ref(null);
|
|
const arrowRight = ref(null);
|
|
|
|
// useFloating 分别初始化
|
|
const { floatingStyles: bottomStyles, middlewareData: bottomData } = useFloating(
|
|
referenceBottom,
|
|
floatingBottom,
|
|
{ placement: 'bottom-start', middleware: [offset(10), arrow({ element: arrowBottom })] }
|
|
);
|
|
|
|
const { floatingStyles: topStyles, middlewareData: topData } = useFloating(
|
|
referenceTop,
|
|
floatingTop,
|
|
{ placement: 'top', middleware: [offset(10), arrow({ element: arrowTop })] }
|
|
);
|
|
|
|
const { floatingStyles: leftStyles, middlewareData: leftData } = useFloating(
|
|
referenceLeft,
|
|
floatingLeft,
|
|
{ placement: 'left', middleware: [offset(10), arrow({ element: arrowLeft })] }
|
|
);
|
|
|
|
const { floatingStyles: rightStyles, middlewareData: rightData } = useFloating(
|
|
referenceRight,
|
|
floatingRight,
|
|
{ placement: 'right', middleware: [offset(10), arrow({ element: arrowRight })] }
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<t-tooltip content="这是Tooltip内容">
|
|
<t-button>hover me</t-button>
|
|
<t-button>hover me</t-button>
|
|
</t-tooltip>
|
|
<div class="demo">
|
|
<!-- Bottom -->
|
|
<div class="item">
|
|
<button ref="referenceBottom">Bottom</button>
|
|
<div ref="floatingBottom" :style="bottomStyles" class="floating-box">
|
|
Bottom Floating
|
|
<div
|
|
ref="arrowBottom"
|
|
class="floating-arrow"
|
|
:style="{
|
|
left: bottomData.arrow?.x != null ? `${bottomData.arrow.x}px` : '',
|
|
top: bottomData.arrow?.y != null ? `${bottomData.arrow.y}px` : '',
|
|
}"
|
|
></div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Top -->
|
|
<div class="item">
|
|
<button ref="referenceTop">Top</button>
|
|
<div ref="floatingTop" :style="topStyles" class="floating-box">
|
|
Top Floating
|
|
<div
|
|
ref="arrowTop"
|
|
class="floating-arrow"
|
|
:style="{
|
|
left: topData.arrow?.x != null ? `${topData.arrow.x}px` : '',
|
|
top: topData.arrow?.y != null ? `${topData.arrow.y}px` : '',
|
|
}"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Left -->
|
|
<div class="item">
|
|
<button ref="referenceLeft">Left</button>
|
|
<div ref="floatingLeft" :style="leftStyles" class="floating-box">
|
|
Left Floating
|
|
<div
|
|
ref="arrowLeft"
|
|
class="floating-arrow"
|
|
:style="{
|
|
left: leftData.arrow?.x != null ? `${leftData.arrow.x}px` : '',
|
|
top: leftData.arrow?.y != null ? `${leftData.arrow.y}px` : '',
|
|
}"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right -->
|
|
<div class="item">
|
|
<button ref="referenceRight">Right</button>
|
|
<div ref="floatingRight" :style="rightStyles" class="floating-box">
|
|
Right Floating
|
|
<div
|
|
ref="arrowRight"
|
|
class="floating-arrow"
|
|
:style="{
|
|
left: rightData.arrow?.x != null ? `${rightData.arrow.x}px` : '',
|
|
top: rightData.arrow?.y != null ? `${rightData.arrow.y}px` : '',
|
|
}"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style>
|
|
.demo {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 120px;
|
|
padding: 40px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.item {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.floating-box {
|
|
position: absolute;
|
|
background-color: #333;
|
|
color: #fff;
|
|
padding: 4px 8px;
|
|
font-size: 12px;
|
|
border-radius: 4px;
|
|
z-index: 10;
|
|
}
|
|
|
|
/* 箭头 */
|
|
.floating-arrow {
|
|
position: absolute;
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
.floating-arrow::before {
|
|
position: absolute;
|
|
content: "";
|
|
width: 8px;
|
|
height: 8px;
|
|
background: #333;
|
|
transform: rotate(45deg);
|
|
box-sizing: border-box;
|
|
}
|
|
</style>
|