any-message
Version:
A beautiful global message prompt.
526 lines (518 loc) • 26.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.message = factory());
})(this, (function () { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var globalConfig = null;
/**
*
* @function compatible ie remove element
*
* @params el:{Element | null}:Elements to be removed
*
* @returns void
*
* **/
var remove = function (el) {
var _a;
(_a = el === null || el === void 0 ? void 0 : el.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(el);
};
/**
*
* @function create common style
*
* @params parent:{HTMLDivElement}:parent el
*
* @return void
*
* **/
var createStyle = function (parent) {
var style = parent.querySelector('style') || document.createElement('style');
style.type = 'text/css';
style.innerHTML = "\n .any_message {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n color: rgba(0, 0, 0, 0.85);\n font-size: 14px;\n font-variant: tabular-nums;\n line-height: 1.5715;\n list-style: none;\n font-feature-settings: 'tnum';\n position: fixed;\n top: 8px;\n left: 0;\n z-index: 1010;\n width: 100%;\n pointer-events: none;\n }\n \n .any_message_box {\n text-align: center;\n padding: 8px 0;\n }\n \n .any_message_content {\n display: inline-flex;\n font-size: 14px;\n padding: 10px 16px;\n background-color: #fff;\n box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d;\n border-radius: 3px;\n text-align: center;\n transition: all .2s ease;\n position: relative;\n top: -20px;\n opacity: 0;\n pointer-events:auto;\n }\n \n .any_message_content .any_message_icon {\n font-style:normal;\n display:flex;\n align-items: center;\n }\n \n .any_message_content .any_message_text{\n text-indent:10px;\n }\n \n .any_message_content .any_message_icon.success{\n color: #06a561;\n }\n \n .any_message_content .any_message_icon.warn{\n color: #f99600;\n }\n \n .any_message_content .any_message_icon.info{\n color: #1e5eff;\n }\n \n .any_message_content .any_message_icon.error{\n color: #f0142f;\n }\n \n .any_message_in {\n opacity: 1;\n top: 0;\n }\n \n .any_message_out {\n opacity: 0;\n top: -20px;\n }\n \n .any_message_loading {\n position: relative;\n display: inline-block;\n width: 16px;\n height: 16px;\n }\n \n .any_message_loading span{\n position: absolute;\n top: 0;\n left: 0;\n margin: 10%;\n border: 3px solid;\n border-color: #1e5eff transparent transparent;\n border-radius: 50%;\n -webkit-border-radius: 50%;\n -ms-border-radius: 50%;\n -o-border-radius: 50%;\n -moz-border-radius: 50%;\n width: 80%;\n height: 80%;\n box-sizing: border-box;\n animation: any_message_loader 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n -webkit-animation: any_message_loader 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n -ms-animation: any_message_loader 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n -o-animation: any_message_loader 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n -moz-animation: any_message_loader 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n }\n \n .any_message_loading span:nth-child(1) {\n animation-delay: -0.3s;\n -webkit-animation-delay: -0.3s;\n -ms-animation-delay: -0.3s;\n -o-animation-delay: -0.3s;\n -moz-animation-delay: -0.3s;\n }\n \n .any_message_loading span:nth-child(2) {\n animation-delay: -0.2s;\n -webkit-animation-delay: -0.2s;\n -ms-animation-delay: -0.2s;\n -o-animation-delay: -0.2s;\n -moz-animation-delay: -0.2s;\n }\n \n .any_message_loading span:nth-child(3) {\n animation-delay: -0.1s;\n -webkit-animation-delay: -0.1s;\n -ms-animation-delay: -0.1s;\n -o-animation-delay: -0.1s;\n -moz-animation-delay: -0.1s;\n }\n \n .any_message_loading span:nth-child(4) {\n animation-delay: 0s;\n -webkit-animation-delay: 0s;\n -ms-animation-delay: 0s;\n -o-animation-delay: 0s;\n -moz-animation-delay: 0s;\n }\n \n @keyframes any_message_loader {\n 0% {\n transform: rotate(0);\n -webkit-transform: rotate(0);\n -ms-transform: rotate(0);\n -moz-transform: rotate(0);\n -o-transform: rotate(0);\n }\n \n 100% {\n transform: rotate(360deg);\n -webkit-transform: rotate(360deg);\n -ms-transform: rotate(360deg);\n -moz-transform: rotate(360deg);\n -o-transform: rotate(360deg);\n }\n }\n ";
parent.appendChild(style);
};
/**
*
* @function Query whether the public box already exists
*
* @return HTMLDivElement | null
*
* **/
var findEl = function () {
return document.querySelector('.any_message');
};
/**
*
* @function Create common box
*
* @return HTMLDivElement
*
* **/
var createBox = function () {
var box = findEl();
if (!box) {
box = document.createElement('div');
box.setAttribute('class', 'any_message');
}
createStyle(box);
return box;
};
/**
*
* @function Get display content
*
* @params content:{string | HTMLElement}:need show content
* @params icon:{IconType}:icon configuration, whether to display icon, icon type and customized content
*
* @return string
*
* **/
var getInnerHtml = function (content, icon) {
return "\n ".concat(icon.show && getIconStr(icon.type, icon === null || icon === void 0 ? void 0 : icon.custom), "\n <span class=\"any_message_text\">").concat(content, "</span>\n ");
};
/**
*
* @function return icon according to type
*
* @params type:{'info' | 'warn' | 'error' | 'success'}:Icon types. There are four basic icons by default. For more, you need to pass the second parameter for customization
* @params custom:[string]:HTML tag string of custom icon
*
* @return string
*
* **/
var getIconStr = function (type, custom) {
return "<i class=\"any_message_icon ".concat(type, "\">\n ").concat(custom
? custom
: type === 'success'
? "<svg viewBox=\"64 64 896 896\" focusable=\"false\" data-icon=\"check-circle\" width=\"1em\" height=\"1em\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z\"></path></svg>"
: type === 'error'
? "<svg viewBox=\"64 64 896 896\" focusable=\"false\" data-icon=\"close-circle\" width=\"1em\" height=\"1em\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z\"></path></svg>"
: type === 'warn'
? "<svg viewBox=\"64 64 896 896\" focusable=\"false\" data-icon=\"exclamation-circle\" width=\"1em\" height=\"1em\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\"></path></svg>"
: type === 'loading'
? "<span class='any_message_loading'><span></span><span></span><span></span><span></span></span>"
: "<svg viewBox=\"64 64 896 896\" focusable=\"false\" data-icon=\"info-circle\" width=\"1em\" height=\"1em\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\"></path></svg>", "\n </i>");
};
/**
*
* @function add style
*
* @params el:{HTMLElement}:need add style el
* @params className:{string}:need add class
*
* @returns void
*
* **/
var updateClassName = function (el, className) {
var oldClassName = el.getAttribute('class');
oldClassName === null || oldClassName === void 0 ? void 0 : oldClassName.trim();
if (!oldClassName || !findHaveClass(oldClassName, className)) {
el.setAttribute('class', !oldClassName ? className : oldClassName + ' ' + className);
}
};
/**
*
* @function query whether to include a style
*
* @params oldClassName:{string}:old class
* @params className:{string}:need find class
*
* @returns boolean
*
* **/
var findHaveClass = function (oldClassName, className) {
return oldClassName.indexOf(className) !== -1;
};
/**
*
* @function Create public message body
*
* @params content:{string | HTMLElement}:need show content
* @params duration:{number = 3}:Automatic closing time, no automatic closing when it is less than or equal to 0
* @params params:[ParamsType]:Configurable message closing callback, click callback, icon information, message style name
*
* @return Promise<HTMLElement>
*
* **/
var createMessage = function (content, duration, params) {
if (duration === void 0) { duration = 3; }
return new Promise(function (resolve) {
var _a = params || {}, _b = _a.className, className = _b === void 0 ? '' : _b, icon = _a.icon, onClick = _a.onClick, onClose = _a.onClose, _c = _a.key, key = _c === void 0 ? '' : _c, maxCount = _a.maxCount, style = _a.style;
var box = createBox();
var message_box = findMessageElByKey(key);
var append = message_box === undefined;
if (!message_box) {
message_box = document.createElement('div');
message_box.setAttribute('class', 'any_message_box');
if (key)
message_box.setAttribute('data-key', key);
}
var message;
if (append) {
message = document.createElement('div');
message.setAttribute('class', "any_message_content ".concat(className));
mergeStyle(message, style);
message_box.appendChild(message);
}
else {
message = message_box.querySelector('.any_message_content');
}
message.innerHTML = getInnerHtml(content, __assign({ show: true }, icon));
if (!findEl()) {
document.body.appendChild(box);
}
checkMaxLength(maxCount);
if (append) {
box.appendChild(message_box);
setTimeout(function () {
updateClassName(message, 'any_message_in');
message_box &&
removeElByTimer(message_box, message, duration, function () {
resolve(message);
onClose === null || onClose === void 0 ? void 0 : onClose(message);
}, onClick);
}, 100);
}
else {
message_box &&
removeElByTimer(message_box, message, duration, function () {
resolve(message);
onClose === null || onClose === void 0 ? void 0 : onClose(message);
}, onClick);
}
});
};
/**
*
* @function merge style
*
* @params el:{HTMLElement}:need merge el
* @params style:{CSSStyleType}
*
*/
var mergeStyle = function (el, style) {
if (style)
for (var key in style) {
el.style[key] = style[key];
}
};
/**
*
* @function check max length
*
* @params maxCount:{number}:max length
*
* @returns void
*
*/
var checkMaxLength = function (maxCount) {
if (maxCount === void 0) { maxCount = 0; }
var msg = findMessageEls();
if (maxCount > 0 && msg.length >= maxCount) {
remove(msg[0]);
}
};
/**
*
* @function find whether there is an element that can be assigned a value
*
* @params key:{string}:The key to be queried needs to be set data-key
*
* @returns HTMLDivElement | undefined
*
*/
var findMessageElByKey = function (key) {
var result;
if (key) {
var mList = findMessageEls();
for (var i = 0; i < mList.length; i++) {
var item = mList[i];
if (item.getAttribute('data-key') === key) {
result = item;
break;
}
}
}
return result;
};
/**
*
* @function get all messages
*
* @returns NodeListOf<HTMLDivElement> | []
*
*/
var findMessageEls = function () {
return document.querySelectorAll('.any_message .any_message_box') || [];
};
/**
*
* @function remove element at specified time
*
* @params el:{HTMLElement}:message box el
* @params msg_el:{HTMLElement}:message body el
* @params duration:{number = 3}:Automatic closing time, no automatic closing when it is less than or equal to 0
* @params onClose:[()=>void]:close callback
* @params onClick:[(e?:any)=>void]:click callback
*
* @return void
*
* **/
var removeElByTimer = function (el, msg_el, duration, onClose, onClick) {
clearTimer(el);
var timer = undefined;
var startTimer = function () {
if (duration > 0) {
timer = setTimeout(function () {
updateClassName(msg_el, 'any_message_out');
timer = setTimeout(function () {
remove(el);
removeStyle();
onClose === null || onClose === void 0 ? void 0 : onClose();
}, 200);
el.setAttribute('data-timer', String(timer));
}, duration * 1000);
el.setAttribute('data-timer', String(timer));
}
};
addEvent(msg_el, 'mousemove', function () {
timer && clearTimeout(timer);
});
addEvent(msg_el, 'mouseout', function () {
timer && startTimer();
});
if (onClick) {
addEvent(msg_el, 'click', onClick);
}
startTimer();
};
/**
*
* @function remove timer
*
* @params el:{HTMLElement}:Element with timer
*
* @returns void
*
* */
var clearTimer = function (el) {
var prevTimer = el.getAttribute('data-timer');
if (prevTimer)
clearTimeout(Number(prevTimer));
};
/**
*
* @function add event
*
* @params node:{HTMLElement}:need add event el
* @params event:{string}:event name
* @params fn:{(e?: any) => void}:event handler
* @params opt_useCapture:[boolean:whether automatic bubbling
*
* @return void
*
* **/
var addEvent = function (node, event, fn, opt_useCapture) {
if (typeof node.addEventListener === 'function') {
node.removeEventListener(event, fn, opt_useCapture || false);
node.addEventListener(event, fn, opt_useCapture || false);
}
else if (typeof (node === null || node === void 0 ? void 0 : node.attachEvent) === 'function') {
node === null || node === void 0 ? void 0 : node.detachEvent('on' + event, fn);
node === null || node === void 0 ? void 0 : node.attachEvent('on' + event, fn);
}
};
/**
*
* @function get parameters
*
* @params config:{string | HTMLElement | MessageType}:parameter
*
* @tips The parameters are optional. However, if the parameters are transferred at the same time, the subsequent parameters will have higher priority than the preceding parameters. For example, the local parameter config contains the duration parameter, the global config is set, and the duration parameter is passed. The priority will be the highest duration priority. If the duration parameter is not passed, the local duration priority will be the highest, and the global duration will be the last
*
* @return void
*
* **/
var getConfig = function (config, duration, params) {
if ((typeof config === 'object' && config instanceof HTMLElement) ||
typeof config === 'string') {
return {
content: config || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.content) || '',
duration: typeof (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.duration) === 'number' && typeof duration !== 'number'
? globalConfig.duration
: duration,
params: __assign(__assign({}, globalConfig), params),
};
}
else {
return {
content: (config === null || config === void 0 ? void 0 : config.content) || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.content) || '',
duration: typeof (config === null || config === void 0 ? void 0 : config.duration) === 'number' && typeof duration !== 'number'
? config.duration
: typeof (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.duration) === 'number' && typeof duration !== 'number'
? globalConfig.duration
: duration,
params: __assign(__assign(__assign({}, globalConfig), config), params),
};
}
};
/**
*
* @function success
*
* @params content:{string | HTMLElement | MessageType}:need show content
* @params duration:{number = 3}:close time
* @params params:[ParamsType]:icon info
*
* @return Promise<HTMLElement>
*
* **/
var success = function (content, duration, params) {
var config = getConfig(content, duration, __assign(__assign({}, params), { icon: __assign(__assign({}, params === null || params === void 0 ? void 0 : params.icon), { type: 'success' }) }));
return createMessage(config.content, config.duration, config.params);
};
/**
*
* @function warning
*
* @params content:{string | HTMLElement | MessageType}:need show content
* @params duration:{number = 3}:close time
* @params params:[ParamsType]:icon info
*
* @return Promise<HTMLElement>
*
* **/
var warn = function (content, duration, params) {
var config = getConfig(content, duration, __assign(__assign({}, params), { icon: __assign(__assign({}, params === null || params === void 0 ? void 0 : params.icon), { type: 'warn' }) }));
return createMessage(config.content, config.duration, config.params);
};
/**
*
* @function error
*
* @params content:{string | HTMLElement | MessageType}:need show content
* @params duration:{number = 3}:close time
* @params params:[ParamsType]:icon info
*
* @return Promise<HTMLElement>
*
* **/
var error = function (content, duration, params) {
var config = getConfig(content, duration, __assign(__assign({}, params), { icon: __assign(__assign({}, params === null || params === void 0 ? void 0 : params.icon), { type: 'error' }) }));
return createMessage(config.content, config.duration, config.params);
};
/**
*
* @function info
*
* @params content:{string | HTMLElement | MessageType}:need show content
* @params duration:{number = 3}:close time
* @params params:[ParamsType]:icon info
*
* @return Promise<HTMLElement>
*
* **/
var info = function (content, duration, params) {
var config = getConfig(content, duration, __assign(__assign({}, params), { icon: __assign(__assign({}, params === null || params === void 0 ? void 0 : params.icon), { type: 'info' }) }));
return createMessage(config.content, config.duration, config.params);
};
/**
*
* @function loading
*
* @params content:{string | HTMLElement | MessageType}:need show content
* @params duration:{number = 3}:close time
* @params params:[ParamsType]:icon info
*
* @return Promise<HTMLElement>
*
* **/
var loading = function (content, duration, params) {
var config = getConfig(content, duration, __assign(__assign({}, params), { icon: __assign(__assign({}, params === null || params === void 0 ? void 0 : params.icon), { type: 'loading' }) }));
return createMessage(config.content, config.duration, config.params);
};
/**
*
* @function remove style
*
* @return void
*
* **/
var removeStyle = function () {
if (document.querySelectorAll('.any_message .any_message_box').length === 0) {
remove(document.querySelector('.any_message style'));
}
};
/**
*
* @object global config
*
* @tips lower priority than calling the corresponding method directly
*
*/
var config = function (params) {
globalConfig = params;
};
/**
*
* @function destroy message
*
* @params id:[string]:need destroy key
*
* @return void
*
*/
var destroy = function (id) {
if (id) {
var box_1 = findMessageElByKey(id);
if (box_1) {
clearTimer(box_1);
var content = box_1.querySelector('.any_message_content');
content && updateClassName(content, 'any_message_out');
setTimeout(function () {
box_1 && remove(box_1);
}, 200);
}
}
else {
var els = findMessageEls();
for (var i = 0; i < els.length; i++) {
clearTimer(els[i]);
}
remove(document.querySelector('.any_message'));
}
};
var message = {
success: success,
destroy: destroy,
warn: warn,
error: error,
info: info,
loading: loading,
config: config,
};
return message;
}));