Skip to content

Commit ef30b02

Browse files
author
Tenny
committed
feat: Popover bottom
Signed-off-by: Tenny <joel.shu@qq.com>
1 parent c8b8410 commit ef30b02

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

docs/components/popover.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</template>
2626
</textarea>
2727
<template #preview>
28-
<Popover content="Content">
28+
<Popover content="Content" placement="bottom">
2929
<template #trigger>
3030
<Button @click="click1">悬浮</Button>
3131
</template>

src/components/Popover.vue

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
ref,
88
Transition,
99
nextTick,
10-
onMounted,
1110
} from 'vue';
1211
import type { PropType } from 'vue';
1312
@@ -39,8 +38,11 @@ export default defineComponent({
3938
},
4039
/** 显示的内容,也可以通过写入默认 slot 修改显示内容 */
4140
content: String,
41+
/** 弹出位置 */
4242
placement: {
43-
type: String as PropType<'top' | 'bottom' | 'left' | 'right'>,
43+
type: String as PropType<
44+
'topStart' | 'top' | 'topEnd' | 'bottomStart' | 'bottom' | 'bottomEnd'
45+
>,
4446
default: 'top',
4547
},
4648
},
@@ -49,20 +51,32 @@ export default defineComponent({
4951
5052
const $popover = ref<HTMLDivElement>();
5153
52-
const posStyle = ref();
54+
let closeT: number | undefined;
55+
56+
const posStyle = ref({});
5357
5458
function handleMouseEnter(e: Event) {
59+
if (show.value) {
60+
if (closeT != null) {
61+
clearTimeout(closeT);
62+
closeT = undefined;
63+
}
64+
return;
65+
}
5566
const $target = e.target as HTMLElement;
5667
show.value = true;
57-
console.log('enter');
5868
nextTick(() => {
5969
const { left, top } = getDistanceToContainer($target);
6070
let offsetTop = 0;
6171
let offsetLeft = 0;
6272
if ($popover.value != null) {
6373
const popoverRect = $popover.value.getBoundingClientRect();
64-
offsetTop = popoverRect.height + 10;
6574
const targetRect = $target.getBoundingClientRect();
75+
if (props.placement === 'top') {
76+
offsetTop = popoverRect.height + 10;
77+
} else if (props.placement === 'bottom') {
78+
offsetTop = -(targetRect.height + 10);
79+
}
6680
offsetLeft = popoverRect.width / 2 - targetRect.width / 2;
6781
}
6882
posStyle.value = {
@@ -74,7 +88,9 @@ export default defineComponent({
7488
7589
/** 鼠标离开事件 */
7690
function hanldeMouseLeave() {
77-
show.value = false;
91+
closeT = setTimeout(() => {
92+
show.value = false;
93+
}, 150) as any;
7894
}
7995
8096
function handleClick(e: Event) {
@@ -108,9 +124,25 @@ export default defineComponent({
108124
'div',
109125
{
110126
...attrs,
111-
class: ['nt-popover', attrs.class],
127+
class: [
128+
'nt-popover',
129+
props.placement.startsWith('top')
130+
? 'nt-popover-top'
131+
: '',
132+
props.placement.startsWith('bottom')
133+
? 'nt-popover-bottom'
134+
: '',
135+
props.placement.endsWith('Start')
136+
? 'nt-popover-start'
137+
: '',
138+
props.placement.endsWith('End')
139+
? 'nt-popover-end'
140+
: '',
141+
attrs.class,
142+
],
112143
style: [attrs.style, posStyle.value],
113144
ref: $popover,
145+
...prop,
114146
},
115147
[
116148
slots.default != null

style/popover/index.css

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
height: 8px;
1818
z-index: -1;
1919
left: 50%;
20-
bottom: -4px;
2120
margin-left: -4px;
2221
}
2322

@@ -30,9 +29,22 @@
3029
background-color: #ffffff;
3130
border-width: 1px;
3231
border-style: solid;
33-
border: transparent var(--nt-popover-border-color)
32+
}
33+
34+
/* top */
35+
.nt-popover-top .nt-popover-arrow {
36+
bottom: -4px;
37+
}
38+
.nt-popover-top .nt-popover-arrow::before {
39+
border-color: transparent var(--nt-popover-border-color)
3440
var(--nt-popover-border-color) transparent;
35-
box-sizing:
36-
inset 0 -0.5px 0 var(--td-gray-color-9),
37-
inset -0.5px 0 0 var(--td-gray-color-9);
41+
}
42+
43+
/* bottom */
44+
.nt-popover-bottom .nt-popover-arrow {
45+
top: -4px;
46+
}
47+
.nt-popover-bottom .nt-popover-arrow::before {
48+
border-color: var(--nt-popover-border-color) transparent transparent
49+
var(--nt-popover-border-color);
3850
}

0 commit comments

Comments
 (0)