Files
MetonaToast/site/index.html
T
thzxx f7d74d152d chore: v0.1.2 — 全面修复、优化与增强
修复:
- core.js: _resume 计时器 BUG (startedAt 被 _startTimer 覆盖导致暂停恢复失效)
- plugins.js: register 在 install 前展开导致 handler 实例丢失
- locales.js: zh-CN/en-US 大量重复 key 覆盖正确翻译值
- core.js: configure 改为原地更新避免 _config 引用断裂

优化:
- core.js: update() 类型变更时同步更新 DOM 类名和进度条颜色
- animations.js: getActiveCount 返回已注册动画数量
- themes.js: 移除 presetThemes 死代码和重复注册循环
- constants.js: THEMES.auto 从字符串改为规范化对象
- index.js: destroy 添加防重复调用保护

增强:
- core.js: 新增 onError 全局错误回调,钩子异常和定时器错误可被外部捕获
- styles.js: _resume 校准时间基准补偿注释
- 139 tests 全部通过
2026-07-24 14:42:47 +08:00

262 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<title>MetonaToast — 轻量精致的 Toast 通知库</title>
<meta name="description" content="MetonaToast 是轻量、零依赖、精致美观的 Toast 通知库。80+ 图标类型、11 种动画、主题系统、国际化、插件架构。">
<style>
:root {
--bg: #0b1121; --bg2: #111827; --surface: #1a2332;
--border: #1e2d4d; --text: #e2e8f0; --muted: #64748b;
--accent: #6366f1; --accent2: #818cf8; --radius: 14px;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif; background: var(--bg); color: var(--text); line-height: 1.7; }
a { color: var(--accent2); text-decoration: none; }
code { background: rgba(99,102,241,0.12); color: #a5b4fc; padding: 2px 7px; border-radius: 5px; font-size: 0.9em; }
pre { background: #0a0f1a; border: 1px solid var(--border); border-radius: 10px; padding: 18px 22px; overflow-x: auto; font: 13px/1.8 'SF Mono','Cascadia Code','Fira Code',Consolas,monospace; color: #cbd5e1; }
pre .kw { color: #c084fc; } pre .fn { color: #60a5fa; } pre .s { color: #34d399; } pre .cm { color: #475569; }
.nav { position: sticky; top: 0; z-index: 100; background: rgba(11,17,33,0.88); backdrop-filter: blur(14px); border-bottom: 1px solid var(--border); }
.nav-inner { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; height: 56px; }
.nav-logo { font-size: 18px; font-weight: 700; background: linear-gradient(135deg, #818cf8, #c084fc, #f472b6); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.nav-links { display: flex; gap: 24px; }
.nav-links a { color: var(--muted); font-size: 14px; font-weight: 500; transition: .2s; }
.nav-links a:hover { color: var(--accent2); }
.hero { text-align: center; padding: 100px 20px 70px; background: radial-gradient(ellipse at 50% 0%, rgba(99,102,241,0.18) 0%, transparent 60%), linear-gradient(180deg, #0f172a 0%, var(--bg) 100%); border-bottom: 1px solid var(--border); }
.hero h1 { font-size: 52px; font-weight: 800; }
.hero h1 span { background: linear-gradient(135deg, #818cf8, #c084fc, #f472b6); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.hero p { color: var(--muted); font-size: 17px; margin-top: 12px; max-width: 600px; margin-left: auto; margin-right: auto; }
.hero .badges { display: flex; gap: 12px; justify-content: center; margin-top: 24px; flex-wrap: wrap; }
.hero .badges span { background: var(--surface); border: 1px solid var(--border); border-radius: 20px; padding: 6px 18px; font-size: 13px; color: var(--accent2); }
.hero-actions { margin-top: 32px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.btn { padding: 11px 28px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; transition: .2s; border: none; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent2); transform: translateY(-1px); }
.btn-outline { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-outline:hover { border-color: var(--accent); color: var(--accent2); }
.container { max-width: 1100px; margin: 0 auto; padding: 60px 24px; }
.section-title { font-size: 28px; font-weight: 700; text-align: center; margin-bottom: 8px; }
.section-desc { color: var(--muted); text-align: center; margin-bottom: 40px; font-size: 15px; }
.features { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 18px; }
.feature { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 28px; transition: .2s; }
.feature:hover { border-color: var(--accent); }
.feature-icon { font-size: 28px; margin-bottom: 12px; }
.feature h3 { font-size: 16px; margin-bottom: 6px; }
.feature p { color: var(--muted); font-size: 13px; line-height: 1.6; }
.code-block { max-width: 750px; margin: 0 auto; }
.theme-demo { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin: 24px 0; }
.theme-btn { padding: 10px 20px; border-radius: 8px; border: 1px solid var(--border); cursor: pointer; background: var(--surface); color: var(--text); font-size: 13px; font-weight: 500; transition: .2s; }
.theme-btn:hover { border-color: var(--accent); }
footer { text-align: center; padding: 40px 24px; color: var(--muted); font-size: 13px; border-top: 1px solid var(--border); }
@media (max-width: 768px) {
.hero h1 { font-size: 32px; }
.nav-links { gap: 14px; }
}
</style>
</head>
<body>
<nav class="nav">
<div class="nav-inner">
<div class="nav-logo">MetonaToast</div>
<div class="nav-links">
<a href="index.html">首页</a>
<a href="docs.html">文档</a>
<a href="demo.html">演示</a>
<a href="https://git.metona.cn/MetonaTeam/MetonaToast" target="_blank">Gitea</a>
</div>
</div>
</nav>
<header class="hero">
<h1><span>MetonaToast</span></h1>
<p>轻量 · 零依赖 · 精致美观的 Toast 通知库。纯原生 JavaScriptgzip 不到 10KB。</p>
<div class="badges">
<span>📦 &lt;10KB gzip</span><span>🎨 107 图标</span><span>🎭 11 动画</span><span>🌍 国际化</span><span>🔌 插件</span><span>📘 TypeScript</span>
</div>
<div class="hero-actions">
<button class="btn btn-primary" onclick="demoQuickStart()">快速预览</button>
<button class="btn btn-outline" onclick="location.href='docs.html'">查看文档</button>
</div>
</header>
<main class="container">
<h2 class="section-title">核心特性</h2>
<p class="section-desc">一切你需要的,都在一个不到 10KB 的包中</p>
<div class="features">
<div class="feature">
<div class="feature-icon">🎨</div>
<h3>107 种图标类型</h3>
<p>success / error / warning / info / loading 以及 100+ 扩展类型,覆盖所有常见场景。</p>
</div>
<div class="feature">
<div class="feature-icon">🎭</div>
<h3>11 种动画效果</h3>
<p>slide / fade / scale / bounce / flip / rotate / zoom / slideUp / slideDown / slideLeft / slideRight,每种感官差异明显。</p>
</div>
<div class="feature">
<div class="feature-icon">🖌️</div>
<h3>主题系统</h3>
<p>内置 light / dark / auto / warm 四种主题,支持 <code>registerTheme()</code> 自定义注册任意主题。</p>
</div>
<div class="feature">
<div class="feature-icon">🌍</div>
<h3>国际化</h3>
<p>内置 zh-CN 和 en-US 完整翻译,400+ 词汇。支持 <code>addTranslations()</code> 扩展任意语言。</p>
</div>
<div class="feature">
<div class="feature-icon">🔌</div>
<h3>插件系统</h3>
<p>3 款预设插件 + 自定义插件架构。keyboard / persistence / accessibility 开箱即用。</p>
</div>
<div class="feature">
<div class="feature-icon"></div>
<h3>拖拽关闭</h3>
<p>任意方向拖动 Toast 即可关闭。支持 Pointer Events,移动端和桌面端体验一致。</p>
</div>
<div class="feature">
<div class="feature-icon"></div>
<h3>零依赖</h3>
<p>纯原生 JavaScript 实现,无需任何运行时依赖。兼容所有现代浏览器。</p>
</div>
<div class="feature">
<div class="feature-icon">📘</div>
<h3>TypeScript</h3>
<p>完整类型定义,智能提示全覆盖。<code>MeToast.success()</code><code>.confirm()</code><code>.action()</code> 全部有类型。</p>
</div>
</div>
</main>
<section class="container">
<h2 class="section-title">环境支持</h2>
<p class="section-desc">所有现代浏览器原生支持,无需 polyfill</p>
<div class="env-grid" style="display:grid; grid-template-columns:repeat(auto-fill,minmax(165px,1fr)); gap:12px;">
<div class="feature" style="text-align:center;padding:20px 16px;">
<div style="font-size:28px;margin-bottom:6px;">🌐</div>
<h3>Chrome</h3>
<p>64+</p>
</div>
<div class="feature" style="text-align:center;padding:20px 16px;">
<div style="font-size:28px;margin-bottom:6px;">🦊</div>
<h3>Firefox</h3>
<p>63+</p>
</div>
<div class="feature" style="text-align:center;padding:20px 16px;">
<div style="font-size:28px;margin-bottom:6px;">🧭</div>
<h3>Safari</h3>
<p>11+</p>
</div>
<div class="feature" style="text-align:center;padding:20px 16px;">
<div style="font-size:28px;margin-bottom:6px;">🪟</div>
<h3>Edge</h3>
<p>79+</p>
</div>
<div class="feature" style="text-align:center;padding:20px 16px;">
<div style="font-size:28px;margin-bottom:6px;">📦</div>
<h3>Node.js</h3>
<p>18+</p>
</div>
<div class="feature" style="text-align:center;padding:20px 16px;">
<div style="font-size:28px;margin-bottom:6px;">📘</div>
<h3>TypeScript</h3>
<p>4.5+</p>
</div>
</div>
<p style="text-align:center;color:var(--muted);font-size:13px;margin-top:16px">核心依赖:Web Animations API · Pointer Events · CSS Grid · CSS Custom Properties</p>
</section>
<section class="container">
<h2 class="section-title">快速开始</h2>
<p class="section-desc">浏览器 window 上仅注册两个全局变量:<code>MeToast</code><code>Met</code>,完全等价</p>
<div class="code-block">
<pre><span class="cm"># npm 安装</span>
npm install @metona-team/metona-toast
<span class="cm">// 导入</span>
<span class="kw">import</span> MeToast <span class="kw">from</span> <span class="s">'@metona-team/metona-toast'</span>;
<span class="cm">// 使用</span>
MeToast.<span class="fn">success</span>(<span class="s">'操作成功!'</span>);
MeToast.<span class="fn">error</span>(<span class="s">'操作失败!'</span>);
MeToast.<span class="fn">loading</span>(<span class="s">'加载中...'</span>);
<span class="cm">// CDN 直接引用</span>
<span class="kw">&lt;script</span> <span class="fn">src</span>=<span class="s">"https://git.metona.cn/MetonaTeam/MetonaToast/raw/branch/master/dist/metona-toast.min.js"</span><span class="kw">&gt;&lt;/script&gt;</span></pre>
</div>
</section>
<section class="container">
<h2 class="section-title">高级功能速览</h2>
<p class="section-desc">不仅仅是一个 Toast——确认框、输入框、进度条、倒计时、队列,应有尽有</p>
<div class="code-block">
<pre><span class="cm">// Promise 风格 — 自动 loading → success/error</span>
<span class="kw">await</span> MeToast.<span class="fn">promise</span>(<span class="fn">fetch</span>(<span class="s">'/api/data'</span>), {
<span class="fn">loading</span>: <span class="s">'加载中...'</span>,
<span class="fn">success</span>: <span class="s">'加载完成!'</span>,
<span class="fn">error</span>: <span class="s">'加载失败'</span>,
});
<span class="cm">// 确认对话框 → Promise&lt;boolean&gt;</span>
<span class="kw">const</span> ok = <span class="kw">await</span> MeToast.<span class="fn">confirm</span>(<span class="s">'确定删除吗?'</span>, { <span class="fn">confirmText</span>: <span class="s">'删除'</span> });
<span class="cm">// 输入对话框 → Promise&lt;string|null&gt;</span>
<span class="kw">const</span> name = <span class="kw">await</span> MeToast.<span class="fn">prompt</span>(<span class="s">'请输入姓名'</span>);
<span class="cm">// Action Toast — 内嵌操作按钮</span>
MeToast.<span class="fn">action</span>(<span class="s">'文件已删除'</span>, [
{ <span class="fn">text</span>: <span class="s">'撤销'</span>, <span class="fn">onClick</span>: () => <span class="fn">restore</span>() },
{ <span class="fn">text</span>: <span class="s">'查看'</span>, <span class="fn">onClick</span>: () => <span class="fn">open</span>() },
]);
<span class="cm">// Toast 分组管理</span>
<span class="kw">const</span> orderGroup = MeToast.<span class="fn">group</span>(<span class="s">'orders'</span>);
orderGroup.<span class="fn">success</span>(<span class="s">'订单已创建'</span>);
orderGroup.<span class="fn">dismiss</span>(); <span class="cm">// 一键关闭整组</span></pre>
</div>
</section>
<section class="container">
<h2 class="section-title">主题切换</h2>
<p class="section-desc">点击按钮实时预览四种内置主题</p>
<div class="theme-demo">
<button class="theme-btn" onclick="switchTheme('light')">☀️ 浅色 Light</button>
<button class="theme-btn" onclick="switchTheme('dark')">🌙 深色 Dark</button>
<button class="theme-btn" onclick="switchTheme('auto')">🔄 自动 Auto</button>
<button class="theme-btn" onclick="switchTheme('warm')">🔥 暖色 Warm</button>
</div>
</section>
<footer>
<p>MetonaToast v0.1.2 · MIT License · <a href="https://git.metona.cn/MetonaTeam/MetonaToast">Gitea</a></p>
</footer>
<script src="../dist/metona-toast.js"></script>
<script>
MeToast.configure({ position: 'top-right', duration: 4000, theme: 'dark', animation: 'slide' });
function demoQuickStart() {
MeToast.success('✨ 欢迎使用 MetonaToast');
setTimeout(() => MeToast.info('💡 试试点击右上角的 Toast 来关闭它'), 800);
setTimeout(() => MeToast.warning('⚠️ 你也可以拖动 Toast 来关闭'), 1600);
}
function switchTheme(t) {
MeToast.themes.switchTheme(t);
MeToast.configure({ theme: t });
const names = { light: '浅色', dark: '深色', auto: '自动', warm: '暖色' };
MeToast.info('已切换到「' + names[t] + '」主题', { theme: t });
}
</script>
</body>
</html>