-
Notifications
You must be signed in to change notification settings - Fork 290
/
Copy pathpopover.tsx
65 lines (63 loc) · 2.42 KB
/
popover.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { defineComponent, toRefs, ref, Teleport, Transition, watch, provide } from 'vue';
import { FlexibleOverlay } from '../../overlay';
import { PopperTrigger } from '../../shared/components/popper-trigger';
import { popoverProps, PopoverProps } from './popover-types';
import { POPPER_TRIGGER_TOKEN } from '../../shared/components/popper-trigger/src/popper-trigger-types';
import { usePopover, usePopoverEvent } from './use-popover';
import PopoverIcon from './popover-icon';
import { useNamespace } from '@devui/shared/utils';
import './popover.scss';
export default defineComponent({
name: 'DPopover',
inheritAttrs: false,
props: popoverProps,
emits: ['show', 'hide'],
setup(props: PopoverProps, { slots, attrs, emit, expose }) {
const { content, popType, position, align, offset, showAnimation } = toRefs(props);
const origin = ref<HTMLElement>();
const popoverRef = ref<HTMLElement>();
const visible = ref(false);
const { placement, handlePositionChange, onMouseenter, onMouseleave } = usePopoverEvent(props, visible, origin);
const { overlayStyles } = usePopover(props, visible, placement, origin, popoverRef);
const ns = useNamespace('popover');
provide(POPPER_TRIGGER_TOKEN, origin);
expose({
triggerEl: origin,
});
watch(visible, (newVal) => {
if (newVal) {
emit('show');
} else {
emit('hide');
}
});
return () => (
<>
<PopperTrigger>{slots.default?.()}</PopperTrigger>
<Teleport to="body">
<Transition name={showAnimation.value ? ns.m(`fade-${placement.value}`) : ''}>
<FlexibleOverlay
v-model={visible.value}
ref={popoverRef}
origin={origin.value}
position={position.value}
align={align.value}
offset={offset.value}
class={[ns.e('content'), popType.value !== 'default' ? 'is-icon' : '']}
show-arrow
is-arrow-center={false}
style={overlayStyles.value}
place-strategy="no-space"
{...attrs}
onPositionChange={handlePositionChange}
onMouseenter={onMouseenter}
onMouseleave={onMouseleave}>
<PopoverIcon type={popType.value} />
{slots.content?.() || <span>{content.value}</span>}
</FlexibleOverlay>
</Transition>
</Teleport>
</>
);
},
});