element-plus
Version:
A Component Library for Vue3.0
142 lines (135 loc) • 5.05 kB
JavaScript
import { ref, computed, watch, defineComponent, toDisplayString, renderSlot, createTextVNode, createCommentVNode, Fragment, withDirectives, createVNode, Teleport } from 'vue';
import ElPopper, { usePopper, defaultProps, renderPopper, Effect, renderArrow, renderTrigger } from '../el-popper';
import { ClickOutside } from '../directives';
import { warn } from '../utils/error';
import { renderIf, PatchFlags, renderBlock } from '../utils/vnode';
import { isString } from '../utils/util';
import PopupManager from '../utils/popup-manager';
import { on } from '../utils/dom';
const SHOW_EVENT = 'show';
const HIDE_EVENT = 'hide';
function usePopover(props, ctx) {
const zIndex = ref(PopupManager.nextZIndex());
const width = computed(() => {
if (isString(props.width)) {
return props.width;
}
return props.width + 'px';
});
const popperStyle = computed(() => {
return {
width: width.value,
zIndex: zIndex.value,
};
});
const popperProps = usePopper(props, ctx);
watch(popperProps.visibility, val => {
if (val) {
zIndex.value = PopupManager.nextZIndex();
}
ctx.emit(val ? SHOW_EVENT : HIDE_EVENT);
});
return Object.assign(Object.assign({}, popperProps), { popperStyle });
}
const emits = ['update:visible', 'after-enter', 'after-leave', SHOW_EVENT, HIDE_EVENT];
const NAME = 'ElPopover';
const _hoist = { key: 0, class: 'el-popover__title', role: 'title' };
var script = defineComponent({
name: NAME,
components: {
ElPopper,
},
props: Object.assign(Object.assign({}, defaultProps), { content: {
type: String,
}, trigger: {
type: String,
default: 'click',
}, title: {
type: String,
}, transition: {
type: String,
default: 'fade-in-linear',
}, width: {
type: [String, Number],
default: 150,
}, appendToBody: {
type: Boolean,
default: true,
} }),
emits,
setup(props, ctx) {
if (process.env.NODE_ENV !== 'production' && props.visible && !ctx.slots.reference) {
warn(NAME, `
You cannot init popover without given reference
`);
}
const states = usePopover(props, ctx);
return states;
},
render() {
const { $slots } = this;
const trigger = $slots.reference ? $slots.reference() : null;
const title = renderIf(this.title, 'div', _hoist, toDisplayString(this.title), PatchFlags.TEXT);
const content = renderSlot($slots, 'default', {}, () => [createTextVNode(toDisplayString(this.content), PatchFlags.TEXT)]);
const { events, onAfterEnter, onAfterLeave, onPopperMouseEnter, onPopperMouseLeave, popperStyle, popperId, popperClass, showArrow, transition, visibility, } = this;
const kls = [
this.content ? 'el-popover--plain' : '',
'el-popover',
popperClass,
].join(' ');
let popover = renderPopper({
effect: Effect.LIGHT,
name: transition,
popperClass: kls,
popperStyle: popperStyle,
popperId,
visibility,
onMouseEnter: onPopperMouseEnter,
onMouseLeave: onPopperMouseLeave,
onAfterEnter,
onAfterLeave,
stopPopperMouseEvent: false,
}, [
title,
content,
renderArrow(showArrow),
]);
const _trigger = trigger ? renderTrigger(trigger, Object.assign({ ariaDescribedby: popperId, ref: 'triggerRef' }, events)) : createCommentVNode('v-if', true);
return renderBlock(Fragment, null, [
this.trigger === 'click'
? withDirectives(_trigger, [[ClickOutside, this.hide]])
: _trigger,
createVNode(Teleport, {
disabled: !this.appendToBody,
to: 'body',
}, [popover], PatchFlags.PROPS, ['disabled']),
]);
},
});
script.__file = "packages/popover/src/index.vue";
const attachEvents = (el, binding, vnode) => {
const _ref = binding.arg || binding.value;
const popover = vnode.dirs[0].instance.$refs[_ref];
if (popover) {
popover.triggerRef = el;
Object.entries(popover.events).map(([eventName, e]) => {
on(el, eventName.toLowerCase().slice(2), e);
});
}
};
var PopoverDirective = {
mounted(el, binding, vnode) {
attachEvents(el, binding, vnode);
},
updated(el, binding, vnode) {
attachEvents(el, binding, vnode);
},
};
const VPopover = 'popover';
script.install = (app) => {
app.component(script.name, script);
app.directive(VPopover, PopoverDirective);
};
script.directive = PopoverDirective;
const _Popover = script;
export default _Popover;