release: v0.2.1 — bug修复、代码去重、功能增强、覆盖率88.57%
This commit is contained in:
+147
-36
@@ -1,23 +1,24 @@
|
||||
/**
|
||||
* MetonaToast API — meToast 核心 API 对象
|
||||
* @module api
|
||||
* @version 0.2.0
|
||||
* @version 0.2.1
|
||||
*/
|
||||
|
||||
import { Toast, _containerCache } from './toast.js';
|
||||
import { DEFAULTS } from './constants.js';
|
||||
import { escapeHTML } from './utils.js';
|
||||
import { t } from './i18n.js';
|
||||
import { t, setCurrentLocale } from './i18n.js';
|
||||
import { applyTheme } from './themes.js';
|
||||
import { setCurrentLocale } from './i18n.js';
|
||||
import { confirmHTML, promptHTML, progressHTML, actionHTML } from './templates.js';
|
||||
import { presetPlugins } from './plugins.js';
|
||||
import type {
|
||||
ToastConfig, ToastOptions, ToastInstance,
|
||||
LoadingControl, ProgressControl, CountdownControl,
|
||||
ActionControl, QueueControl, GroupAPI,
|
||||
ActionButton, PromiseOptions, ConfirmOptions,
|
||||
PromptOptions, ProgressOptions, CountdownOptions,
|
||||
QueueOptions, StackOptions, MeToast, ErrorInfo,
|
||||
QueueOptions, StackOptions, MeToast, ErrorInfo, Plugin,
|
||||
StatusInfo, InitOptions,
|
||||
} from './types.js';
|
||||
|
||||
/**
|
||||
@@ -47,13 +48,16 @@ const normalizeArgs = (args: unknown[], defaultType = 'default'): ToastOptions =
|
||||
};
|
||||
};
|
||||
|
||||
/** 版本号常量 */
|
||||
const VERSION = '0.2.1';
|
||||
|
||||
/**
|
||||
* meToast API 对象
|
||||
*/
|
||||
const meToast: MeToast = {
|
||||
_toasts: new Map<string, ToastInstance>(),
|
||||
_config: { ...DEFAULTS } as unknown as ToastConfig,
|
||||
version: '0.2.0',
|
||||
version: '0.2.1',
|
||||
|
||||
configure(opts: Partial<ToastConfig>): MeToast {
|
||||
if (!opts || typeof opts !== 'object') return this;
|
||||
@@ -476,27 +480,21 @@ const meToast: MeToast = {
|
||||
this._toasts.forEach(t => t.close());
|
||||
},
|
||||
|
||||
/**
|
||||
* 立即移除指定 Toast(不触发离场动画)
|
||||
*/
|
||||
removeToast(id: string): void {
|
||||
if (!id) return;
|
||||
const t = this._toasts.get(id);
|
||||
if (t) t.remove();
|
||||
},
|
||||
|
||||
clear(position?: string): void {
|
||||
this._toasts.forEach(t => {
|
||||
if (!position || t.config.position === position) t.close();
|
||||
});
|
||||
},
|
||||
|
||||
destroy(): void {
|
||||
this.dismiss();
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
const containers = document.querySelectorAll('.met-container');
|
||||
containers.forEach(c => { if (c.parentNode) c.parentNode.removeChild(c); });
|
||||
|
||||
const style = document.getElementById('metona-toast-styles');
|
||||
if (style && style.parentNode) style.parentNode.removeChild(style);
|
||||
}
|
||||
|
||||
this._toasts.clear();
|
||||
_containerCache.clear();
|
||||
},
|
||||
|
||||
getAll(): Map<string, ToastInstance> {
|
||||
return new Map(this._toasts);
|
||||
},
|
||||
@@ -587,15 +585,126 @@ const meToast: MeToast = {
|
||||
return this.findToasts(t => t.config.position === position);
|
||||
},
|
||||
|
||||
// ====== 以下由 index.ts 增强 ======
|
||||
// ====== 以下方法依赖子模块(themes/i18n/plugins/animations),由 index.ts 注入 ======
|
||||
|
||||
init(_options?: Record<string, unknown>): MeToast { return this; },
|
||||
getStatus() { return { version: '0.2.0', toasts: 0, theme: '', locale: '', plugins: [], animations: 0 }; },
|
||||
getConfig(): ToastConfig { return { ...this._config }; },
|
||||
updateConfig(_config: Partial<ToastConfig>): MeToast { return this; },
|
||||
resetConfig(): MeToast { return this; },
|
||||
use(_plugin: string | Record<string, unknown>, _options?: Record<string, unknown>): MeToast { return this; },
|
||||
init(options: InitOptions = {}): MeToast {
|
||||
if (options.config) {
|
||||
this.configure(options.config);
|
||||
}
|
||||
if (options.theme && this.themes) {
|
||||
this.themes.switchTheme(options.theme);
|
||||
}
|
||||
if (options.locale && this.i18n) {
|
||||
this.i18n.switchLocale(options.locale);
|
||||
}
|
||||
if (options.plugins && Array.isArray(options.plugins)) {
|
||||
options.plugins.forEach((p) => {
|
||||
this.use(p as string);
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
getStatus(): StatusInfo {
|
||||
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(): ToastConfig {
|
||||
return { ...this._config };
|
||||
},
|
||||
|
||||
updateConfig(config: Partial<ToastConfig>): MeToast {
|
||||
if (config && typeof config === 'object') {
|
||||
Object.assign(this._config, config);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
resetConfig(): MeToast {
|
||||
const keys = Object.keys(this._config);
|
||||
keys.forEach(k => delete (this._config as Record<string, unknown>)[k]);
|
||||
Object.assign(this._config, DEFAULTS);
|
||||
return this;
|
||||
},
|
||||
|
||||
use(plugin: string | Plugin, options: Record<string, unknown> = {}): MeToast {
|
||||
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: ToastInstance) => {
|
||||
const acc = preset as Record<string, (t: ToastInstance) => void>;
|
||||
if (typeof acc.announce === 'function') acc.announce(toast);
|
||||
});
|
||||
}
|
||||
if (plugin === 'persistence') {
|
||||
const saved = typeof preset.install === 'function'
|
||||
? preset.install(this.plugins as unknown as import('./types.js').PluginManager)
|
||||
: null;
|
||||
if (saved) this.configure(saved as Partial<ToastConfig>);
|
||||
Toast.on('afterClose', () => {
|
||||
const p = preset as Record<string, (c: unknown) => void>;
|
||||
if (typeof p.save === 'function') p.save(this.getConfig());
|
||||
});
|
||||
}
|
||||
} else if (plugin && typeof plugin === 'object') {
|
||||
this.plugins.register(plugin.name || 'custom', { ...plugin, ...options } as Plugin);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
destroy(): void {
|
||||
if (this._destroyed) return;
|
||||
this._destroyed = true;
|
||||
this.dismiss();
|
||||
|
||||
// 清理子模块
|
||||
if (this.plugins && typeof (this.plugins as unknown as Record<string, unknown>).destroy === 'function') {
|
||||
(this.plugins as unknown as Record<string, () => void>).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();
|
||||
}
|
||||
|
||||
// 清理 DOM
|
||||
if (typeof document !== 'undefined') {
|
||||
const containers = document.querySelectorAll('.met-container');
|
||||
containers.forEach((c) => { if (c.parentNode) c.parentNode.removeChild(c); });
|
||||
|
||||
const style = document.getElementById('metona-toast-styles');
|
||||
if (style && style.parentNode) style.parentNode.removeChild(style);
|
||||
}
|
||||
|
||||
this._toasts.clear();
|
||||
_containerCache.clear();
|
||||
},
|
||||
|
||||
// 子模块引用(由 index.ts 注入实际实现)
|
||||
animations: null as unknown as MeToast['animations'],
|
||||
themes: null as unknown as MeToast['themes'],
|
||||
i18n: null as unknown as MeToast['i18n'],
|
||||
@@ -604,14 +713,16 @@ const meToast: MeToast = {
|
||||
};
|
||||
|
||||
// 连接 Toast 静态回调到 meToast 实例
|
||||
Toast._onError = (info: ErrorInfo) => {
|
||||
const onError = meToast._config.onError;
|
||||
if (typeof onError === 'function') {
|
||||
try { onError(info); } catch (_e) { /* noop */ }
|
||||
}
|
||||
};
|
||||
Toast._removeToast = (id: string) => {
|
||||
meToast._toasts.delete(id);
|
||||
};
|
||||
Toast.setCallbacks({
|
||||
onError: (info: ErrorInfo) => {
|
||||
const onError = meToast._config.onError;
|
||||
if (typeof onError === 'function') {
|
||||
try { onError(info); } catch (_e) { /* noop */ }
|
||||
}
|
||||
},
|
||||
removeToast: (id: string) => {
|
||||
meToast._toasts.delete(id);
|
||||
},
|
||||
});
|
||||
|
||||
export { meToast as default, meToast };
|
||||
|
||||
Reference in New Issue
Block a user