277 lines
6.1 KiB
JavaScript
277 lines
6.1 KiB
JavaScript
/**
|
|
* MetonaToast - 轻量级Toast通知库
|
|
* @module metona-toast
|
|
* @version 2.0.0
|
|
* @author metona
|
|
* @description 轻量、零依赖、精致美观的Toast通知库。单文件,开箱即用。
|
|
* @license MIT
|
|
*/
|
|
|
|
import { meToast, Toast } from './core.js';
|
|
import { animationUtils } from './animations.js';
|
|
import { themeUtils } from './themes.js';
|
|
import { i18nUtils } from './i18n.js';
|
|
import { pluginUtils, presetPlugins } from './plugins.js';
|
|
import { DEFAULTS } from './constants.js';
|
|
|
|
// 版本信息
|
|
const VERSION = '2.0.0';
|
|
|
|
/**
|
|
* 主对象增强
|
|
*/
|
|
const enhancedMeToast = {
|
|
...meToast,
|
|
|
|
version: VERSION,
|
|
|
|
animations: animationUtils,
|
|
themes: themeUtils,
|
|
i18n: i18nUtils,
|
|
plugins: pluginUtils,
|
|
presetPlugins,
|
|
|
|
/**
|
|
* 安装插件,并连接必要的生命周期钩子
|
|
*/
|
|
use(plugin, options = {}) {
|
|
if (typeof plugin === 'string') {
|
|
const preset = presetPlugins[plugin];
|
|
if (!preset) {
|
|
console.warn(`Preset plugin "${plugin}" not found`);
|
|
return this;
|
|
}
|
|
this.plugins.register(plugin, { ...preset, ...options });
|
|
|
|
// 连接插件钩子
|
|
if (plugin === 'accessibility') {
|
|
Toast.on('afterShow', (toast) => preset.announce(toast));
|
|
}
|
|
if (plugin === 'persistence') {
|
|
const saved = preset.install();
|
|
if (saved) this.configure(saved);
|
|
Toast.on('afterClose', () => { preset.save(this.getConfig()); });
|
|
}
|
|
} else if (plugin && typeof plugin === 'object') {
|
|
const name = plugin.name || 'custom';
|
|
this.plugins.register(name, { ...plugin, ...options });
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* 初始化
|
|
*/
|
|
init(options = {}) {
|
|
if (options.config) {
|
|
this.configure(options.config);
|
|
}
|
|
|
|
if (options.theme) {
|
|
this.themes.switchTheme(options.theme);
|
|
}
|
|
|
|
if (options.locale) {
|
|
this.i18n.switchLocale(options.locale);
|
|
}
|
|
|
|
if (options.plugins && Array.isArray(options.plugins)) {
|
|
options.plugins.forEach((plugin) => {
|
|
this.use(plugin);
|
|
});
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* 销毁
|
|
*/
|
|
destroy() {
|
|
this.dismiss();
|
|
|
|
if (this.plugins && typeof this.plugins.destroy === 'function') {
|
|
this.plugins.destroy();
|
|
}
|
|
|
|
if (this.themes) {
|
|
if (typeof this.themes.clearThemeListeners === 'function') {
|
|
this.themes.clearThemeListeners();
|
|
}
|
|
if (typeof this.themes.unwatchSystemTheme === 'function') {
|
|
this.themes.unwatchSystemTheme();
|
|
}
|
|
}
|
|
|
|
if (this.i18n && typeof this.i18n.clearLocaleListeners === 'function') {
|
|
this.i18n.clearLocaleListeners();
|
|
}
|
|
|
|
if (this.animations && typeof this.animations.cancelAll === 'function') {
|
|
this.animations.cancelAll();
|
|
}
|
|
|
|
if (typeof document !== 'undefined') {
|
|
const containers = document.querySelectorAll('.met-container');
|
|
containers.forEach((c) => c.parentNode && c.parentNode.removeChild(c));
|
|
|
|
const style = document.getElementById('metona-toast-styles');
|
|
if (style) style.parentNode.removeChild(style);
|
|
}
|
|
|
|
this._toasts.clear();
|
|
},
|
|
|
|
/**
|
|
* 获取状态
|
|
*/
|
|
getStatus() {
|
|
return {
|
|
version: VERSION,
|
|
toasts: this._toasts.size,
|
|
theme: this.themes?.getCurrentTheme?.() || 'auto',
|
|
locale: this.i18n?.getCurrentLocale?.() || 'zh-CN',
|
|
plugins: this.plugins?.getNames?.() || [],
|
|
animations: this.animations?.getActiveCount?.() || 0,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* 获取配置
|
|
*/
|
|
getConfig() {
|
|
return { ...this._config };
|
|
},
|
|
|
|
/**
|
|
* 更新配置
|
|
*/
|
|
updateConfig(config) {
|
|
if (config && typeof config === 'object') {
|
|
this._config = { ...this._config, ...config };
|
|
}
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* 重置配置
|
|
*/
|
|
resetConfig() {
|
|
this._config = { ...DEFAULTS };
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* 获取Toast列表
|
|
*/
|
|
getToasts() {
|
|
return Array.from(this._toasts.values());
|
|
},
|
|
|
|
/**
|
|
* 检查是否有Toast
|
|
*/
|
|
hasToasts() {
|
|
return this._toasts.size > 0;
|
|
},
|
|
|
|
/**
|
|
* 获取Toast
|
|
*/
|
|
getToast(id) {
|
|
if (!id) return null;
|
|
return this._toasts.get(id) || null;
|
|
},
|
|
|
|
/**
|
|
* 关闭所有Toast
|
|
*/
|
|
closeAll() {
|
|
this._toasts.forEach((t) => t.close());
|
|
},
|
|
|
|
/**
|
|
* 清除所有Toast
|
|
*/
|
|
clearAll() {
|
|
this._toasts.forEach((t) => t.close());
|
|
},
|
|
|
|
/**
|
|
* 暂停所有Toast
|
|
*/
|
|
pauseAll() {
|
|
this._toasts.forEach((t) => t._pause());
|
|
},
|
|
|
|
/**
|
|
* 恢复所有Toast
|
|
*/
|
|
resumeAll() {
|
|
this._toasts.forEach((t) => t._resume());
|
|
},
|
|
|
|
/**
|
|
* 更新所有Toast
|
|
*/
|
|
updateAll(partial) {
|
|
if (partial && typeof partial === 'object') {
|
|
this._toasts.forEach((t) => t.update(partial));
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 查找Toast
|
|
*/
|
|
findToasts(predicate) {
|
|
if (typeof predicate !== 'function') return [];
|
|
return Array.from(this._toasts.values()).filter(predicate);
|
|
},
|
|
|
|
/**
|
|
* 按类型查找Toast
|
|
*/
|
|
findByType(type) {
|
|
return this.findToasts((t) => t.type === type);
|
|
},
|
|
|
|
/**
|
|
* 按位置查找Toast
|
|
*/
|
|
findByPosition(position) {
|
|
return this.findToasts((t) => t.config.position === position);
|
|
},
|
|
|
|
};
|
|
// 初始化主题和国际化
|
|
if (typeof themeUtils.initTheme === 'function') {
|
|
themeUtils.initTheme();
|
|
}
|
|
if (typeof i18nUtils.initI18n === 'function') {
|
|
i18nUtils.initI18n();
|
|
}
|
|
|
|
// 浏览器环境全局注册
|
|
if (typeof window !== 'undefined') {
|
|
window.MeToast = enhancedMeToast;
|
|
window.Met = enhancedMeToast;
|
|
window.metonaToast = enhancedMeToast;
|
|
|
|
// Notification API — 页面不可见时自动发送系统通知
|
|
enhancedMeToast._notify = (toast) => {
|
|
if (typeof Notification === 'undefined' || Notification.permission !== 'granted') return;
|
|
if (!document.hidden) return;
|
|
try {
|
|
new Notification(toast.title || toast.type, { body: toast.message, icon: '/favicon.ico' });
|
|
} catch (_) {}
|
|
};
|
|
Toast.on('afterShow', (toast) => {
|
|
if (toast.config.notifyWhenHidden) enhancedMeToast._notify(toast);
|
|
});
|
|
}
|
|
|
|
// 导出
|
|
export default enhancedMeToast;
|
|
export { enhancedMeToast as meToast, enhancedMeToast as Met, enhancedMeToast as MeToast, Toast, VERSION };
|