UNPKG

element-plus

Version:

A Component Library for Vue3.0

272 lines (260 loc) 9.66 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var aria = require('../utils/aria'); var dom = require('../utils/dom'); var isServer = require('../utils/isServer'); var PopupManager = require('../utils/popup-manager'); var util = require('../utils/util'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var isServer__default = /*#__PURE__*/_interopDefaultLegacy(isServer); var PopupManager__default = /*#__PURE__*/_interopDefaultLegacy(PopupManager); const TypeMap = { success: 'success', info: 'info', warning: 'warning', error: 'error', }; var script = vue.defineComponent({ name: 'ElNotification', props: { customClass: { type: String, default: '' }, dangerouslyUseHTMLString: { type: Boolean, default: false }, duration: { type: Number, default: 4500 }, iconClass: { type: String, default: '' }, id: { type: String, default: '' }, message: { type: [String, Object], default: '', }, offset: { type: Number, default: 0 }, onClick: { type: Function, default: () => void 0, }, onClose: { type: Function, required: true, }, position: { type: String, default: 'top-right', }, showClose: { type: Boolean, default: true }, title: { type: String, default: '' }, type: { type: String, default: '' }, zIndex: { type: Number, default: 0 }, }, emits: ['destroy'], setup(props) { const visible = vue.ref(false); let timer = null; const typeClass = vue.computed(() => { const type = props.type; return type && TypeMap[type] ? `el-icon-${TypeMap[type]}` : ''; }); const horizontalClass = vue.computed(() => { return props.position.indexOf('right') > 1 ? 'right' : 'left'; }); const verticalProperty = vue.computed(() => { return props.position.startsWith('top') ? 'top' : 'bottom'; }); const positionStyle = vue.computed(() => { return { [verticalProperty.value]: `${props.offset}px`, }; }); function startTimer() { if (props.duration > 0) { timer = setTimeout(() => { if (visible.value) { close(); } }, props.duration); } } function clearTimer() { clearTimeout(timer); timer = null; } function close() { visible.value = false; } function onKeydown({ code }) { if (code === aria.EVENT_CODE.delete || code === aria.EVENT_CODE.backspace) { clearTimer(); } else if (code === aria.EVENT_CODE.esc) { if (visible.value) { close(); } } else { startTimer(); } } vue.onMounted(() => { startTimer(); visible.value = true; dom.on(document, 'keydown', onKeydown); }); vue.onBeforeUnmount(() => { dom.off(document, 'keydown', onKeydown); }); return { horizontalClass, typeClass, positionStyle, visible, close, clearTimer, startTimer, }; }, }); const _hoisted_1 = { key: 0 }; function render(_ctx, _cache, $props, $setup, $data, $options) { return (vue.openBlock(), vue.createBlock(vue.Transition, { name: "el-notification-fade", onBeforeLeave: _ctx.onClose, onAfterLeave: _cache[5] || (_cache[5] = $event => (_ctx.$emit('destroy'))) }, { default: vue.withCtx(() => [ vue.withDirectives(vue.createVNode("div", { id: _ctx.id, class: ['el-notification', _ctx.customClass, _ctx.horizontalClass], style: _ctx.positionStyle, role: "alert", onMouseenter: _cache[2] || (_cache[2] = (...args) => (_ctx.clearTimer && _ctx.clearTimer(...args))), onMouseleave: _cache[3] || (_cache[3] = (...args) => (_ctx.startTimer && _ctx.startTimer(...args))), onClick: _cache[4] || (_cache[4] = (...args) => (_ctx.onClick && _ctx.onClick(...args))) }, [ (_ctx.type || _ctx.iconClass) ? (vue.openBlock(), vue.createBlock("i", { key: 0, class: ["el-notification__icon", [_ctx.typeClass, _ctx.iconClass]] }, null, 2 /* CLASS */)) : vue.createCommentVNode("v-if", true), vue.createVNode("div", { class: ["el-notification__group", { 'is-with-icon': _ctx.typeClass || _ctx.iconClass }] }, [ vue.createVNode("h2", { class: "el-notification__title", textContent: vue.toDisplayString(_ctx.title) }, null, 8 /* PROPS */, ["textContent"]), vue.withDirectives(vue.createVNode("div", { class: "el-notification__content", style: !!_ctx.title ? null : 'margin: 0' }, [ vue.renderSlot(_ctx.$slots, "default", {}, () => [ (!_ctx.dangerouslyUseHTMLString) ? (vue.openBlock(), vue.createBlock("p", _hoisted_1, vue.toDisplayString(_ctx.message), 1 /* TEXT */)) : (vue.openBlock(), vue.createBlock(vue.Fragment, { key: 1 }, [ vue.createCommentVNode(" Caution here, message could've been compromized, nerver use user's input as message "), vue.createCommentVNode(" eslint-disable-next-line "), vue.createVNode("p", { innerHTML: _ctx.message }, null, 8 /* PROPS */, ["innerHTML"]) ], 64 /* STABLE_FRAGMENT */)) ]) ], 4 /* STYLE */), [ [vue.vShow, _ctx.message] ]), (_ctx.showClose) ? (vue.openBlock(), vue.createBlock("div", { key: 0, class: "el-notification__closeBtn el-icon-close", onClick: _cache[1] || (_cache[1] = vue.withModifiers((...args) => (_ctx.close && _ctx.close(...args)), ["stop"])) })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */) ], 46 /* CLASS, STYLE, PROPS, HYDRATE_EVENTS */, ["id"]), [ [vue.vShow, _ctx.visible] ]) ]), _: 3 /* FORWARDED */ }, 8 /* PROPS */, ["onBeforeLeave"])) } script.render = render; script.__file = "packages/notification/src/index.vue"; const notifications = { 'top-left': [], 'top-right': [], 'bottom-left': [], 'bottom-right': [], }; let seed = 1; const Notification = function (options = {}) { if (isServer__default['default']) return; const position = options.position || 'top-right'; let verticalOffset = options.offset || 0; notifications[position] .forEach(({ vm }) => { verticalOffset += (vm.el.offsetHeight || 0) + 16; }); verticalOffset += 16; const id = 'notification_' + seed++; const userOnClose = options.onClose; options = Object.assign(Object.assign({}, options), { onClose: () => { close(id, position, userOnClose); }, offset: verticalOffset, id, zIndex: PopupManager__default['default'].nextZIndex() }); const container = document.createElement('div'); const vm = vue.createVNode(script, options, util.isVNode(options.message) ? { default: () => options.message, } : null); vm.props.onDestroy = () => { vue.render(null, container); }; vue.render(vm, container); notifications[position].push({ vm }); document.body.appendChild(container.firstElementChild); return { close: () => { vm.component.proxy.visible = false; }, }; }; ['success', 'warning', 'info', 'error'].forEach(type => { Object.assign(Notification, { [type]: (options = {}) => { if (typeof options === 'string' || util.isVNode(options)) { options = { message: options, }; } options.type = type; return Notification(options); }, }); }); function close(id, position, userOnClose) { const orientedNotifications = notifications[position]; const idx = orientedNotifications.findIndex(({ vm }) => { const { id: _id } = vm.component.props; return id === _id; }); if (idx === -1) { return; } const { vm } = orientedNotifications[idx]; if (!vm) return; userOnClose === null || userOnClose === void 0 ? void 0 : userOnClose(vm); const removedHeight = vm.el.offsetHeight; orientedNotifications.splice(idx, 1); const len = orientedNotifications.length; if (len < 1) return; for (let i = idx; i < len; i++) { const verticalPos = position.split('-')[0]; const pos = parseInt(orientedNotifications[i].vm.el.style[verticalPos], 10) - removedHeight - 16; orientedNotifications[i].vm.component.props.offset = pos; } } Notification.install = (app) => { app.config.globalProperties.$notify = Notification; }; exports.default = Notification;