Files
MetonaToast/examples/index.html
T

443 lines
24 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">
<title>MetonaToast — 基础功能与代码示例</title>
<style>
:root {
--bg: #0b1121; --surface: #151d33; --border: #1e2d4d;
--text: #e2e8f0; --muted: #64748b; --accent: #6366f1; --accent-light: #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.6; min-height: 100vh;
}
.hero {
text-align: center; padding: 80px 20px 60px;
background: radial-gradient(ellipse at 50% 0%, rgba(99,102,241,0.15) 0%, transparent 60%),
linear-gradient(180deg, #0f172a 0%, var(--bg) 100%);
border-bottom: 1px solid var(--border);
}
.hero h1 { font-size: 48px; 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: 16px; margin-top: 8px; }
.hero .badges { display: flex; gap: 12px; justify-content: center; margin-top: 20px; flex-wrap: wrap; }
.hero .badges span {
background: var(--surface); border: 1px solid var(--border); border-radius: 20px;
padding: 5px 16px; font-size: 13px; color: var(--accent-light);
}
.container { max-width: 900px; margin: 0 auto; padding: 40px 20px; }
.section { margin-bottom: 48px; }
.section h2 { font-size: 22px; margin-bottom: 4px; }
.section > p { color: var(--muted); font-size: 14px; margin-bottom: 20px; }
.card {
background: var(--surface); border: 1px solid var(--border);
border-radius: var(--radius); padding: 24px; margin-bottom: 16px;
}
.card h3 { font-size: 14px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 14px; }
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.btn {
padding: 9px 18px; border: none; border-radius: 8px; font-size: 13px;
font-weight: 500; cursor: pointer; transition: 0.2s; color: #fff;
}
.btn:hover { transform: translateY(-1px); filter: brightness(1.15); }
.c-success { background: #10b981; } .c-error { background: #ef4444; }
.c-warning { background: #f59e0b; color: #1e293b; } .c-info { background: #3b82f6; }
.c-primary { background: #6366f1; } .c-purple { background: #8b5cf6; }
.c-pink { background: #ec4899; } .c-teal { background: #14b8a6; }
.c-orange { background: #f97316; } .c-slate { background: #475569; }
pre {
background: #0a0f1a; border: 1px solid var(--border); border-radius: 8px;
padding: 14px 18px; overflow-x: auto; margin: 0;
font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', Consolas, monospace;
font-size: 12.5px; line-height: 1.75; color: #cbd5e1;
}
pre .kw { color: #c084fc; } pre .fn { color: #60a5fa; }
pre .s { color: #34d399; } pre .cm { color: #475569; }
.api-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.api-table th, .api-table td { text-align: left; padding: 7px 12px; border-bottom: 1px solid var(--border); }
.api-table th { color: var(--muted); font-weight: 500; font-size: 11px; text-transform: uppercase; }
.api-table code { background: rgba(99,102,241,0.15); color: #a5b4fc; padding: 1px 6px; border-radius: 4px; font-size: 12px; }
footer { text-align: center; color: var(--muted); font-size: 13px; padding: 40px 20px; border-top: 1px solid var(--border); }
footer a { color: var(--accent-light); text-decoration: none; }
</style>
</head>
<body>
<header class="hero">
<h1><span>MetonaToast</span></h1>
<p>轻量 · 零依赖 · 精致美观的 Toast 通知库</p>
<div class="badges">
<span>📦 &lt;10KB gzip</span><span>🎨 80+ 图标</span><span>🎭 11 动画</span><span>🌍 国际化</span><span>🔌 插件</span>
</div>
</header>
<main class="container">
<!-- 安装 -->
<section class="section">
<h2>📦 安装与引用</h2>
<div class="card">
<h3>npm</h3>
<pre><span class="cm"># 安装</span>
npm install metona-toast
<span class="cm"># ES Module</span>
<span class="kw">import</span> MeToast <span class="kw">from</span> <span class="s">'metona-toast'</span>;
<span class="cm"># CommonJS</span>
<span class="kw">const</span> MeToast = <span class="fn">require</span>(<span class="s">'metona-toast'</span>);</pre>
</div>
<div class="card">
<h3>CDN</h3>
<pre><span class="cm">&lt;!-- UMD 开发版 --&gt;</span>
<span class="kw">&lt;script</span> <span class="fn">src</span>=<span class="s">"https://unpkg.com/metona-toast@2.0.0/dist/metona-toast.js"</span><span class="kw">&gt;&lt;/script&gt;</span>
<span class="cm">&lt;!-- 压缩版(生产环境推荐)--&gt;</span>
<span class="kw">&lt;script</span> <span class="fn">src</span>=<span class="s">"https://unpkg.com/metona-toast@2.0.0/dist/metona-toast.min.js"</span><span class="kw">&gt;&lt;/script&gt;</span>
<span class="cm">&lt;!-- ES Module 直接引用 --&gt;</span>
<span class="kw">&lt;script</span> <span class="fn">type</span>=<span class="s">"module"</span><span class="kw">&gt;</span>
<span class="kw">import</span> MeToast <span class="kw">from</span> <span class="s">'https://unpkg.com/metona-toast@2.0.0/dist/metona-toast.esm.js'</span>;
<span class="kw">&lt;/script&gt;</span></pre>
</div>
</section>
<!-- 基础调用 -->
<section class="section">
<h2>🎯 基础调用</h2>
<p>五种核心类型,一行代码搞定</p>
<div class="card">
<div class="btn-row">
<button class="btn c-success" onclick="MeToast.success('操作成功!')">成功</button>
<button class="btn c-error" onclick="MeToast.error('操作失败!')">错误</button>
<button class="btn c-warning" onclick="MeToast.warning('请注意检查')">警告</button>
<button class="btn c-info" onclick="MeToast.info('系统维护中')">信息</button>
<button class="btn c-slate" onclick="MeToast.show('默认消息')">默认</button>
</div>
<pre><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">warning</span>(<span class="s">'请注意检查'</span>);
MeToast.<span class="fn">info</span>(<span class="s">'系统维护中'</span>);
MeToast.<span class="fn">show</span>(<span class="s">'默认消息'</span>);</pre>
</div>
</section>
<!-- 带配置 -->
<section class="section">
<h2>⚙️ 配置选项</h2>
<p>标题、位置、时长、主题、动画……灵活可控</p>
<div class="card">
<div class="btn-row">
<button class="btn c-success" onclick="MeToast.success({title:'保存成功',message:'文件已同步到云端'})">带标题</button>
<button class="btn c-pink" onclick="MeToast.info('显示10秒',{duration:10000})">长时10s</button>
<button class="btn c-purple" onclick="MeToast.warning('底部居中',{position:'bottom-center'})">底部居中</button>
<button class="btn c-teal" onclick="MeToast.info('手动关闭',{duration:0,closeButton:true})">手动关闭</button>
<button class="btn c-orange" onclick="MeToast.success('弹跳动画',{animation:'bounce'})">弹跳动画</button>
</div>
<pre><span class="cm">// 带标题</span>
MeToast.<span class="fn">success</span>({ <span class="fn">title</span>: <span class="s">'保存成功'</span>, <span class="fn">message</span>: <span class="s">'文件已同步到云端'</span> });
<span class="cm">// 自定义时长 — 显示10秒</span>
MeToast.<span class="fn">info</span>(<span class="s">'显示10秒'</span>, { <span class="fn">duration</span>: 10000 });
<span class="cm">// 自定义位置 — 底部居中</span>
MeToast.<span class="fn">warning</span>(<span class="s">'底部居中'</span>, { <span class="fn">position</span>: <span class="s">'bottom-center'</span> });
<span class="cm">// 手动关闭 — 不自动消失</span>
MeToast.<span class="fn">info</span>(<span class="s">'手动关闭'</span>, { <span class="fn">duration</span>: 0, <span class="fn">closeButton</span>: <span class="kw">true</span> });
<span class="cm">// 自定义动画 — 弹跳效果</span>
MeToast.<span class="fn">success</span>(<span class="s">'弹跳动画'</span>, { <span class="fn">animation</span>: <span class="s">'bounce'</span> });</pre>
</div>
</section>
<!-- Loading 链式 -->
<section class="section">
<h2>🔄 Loading 链式转换</h2>
<p>加载中 → 成功/失败/警告/信息,优雅切换</p>
<div class="card">
<div class="btn-row">
<button class="btn c-purple" onclick="demoLoading()">提交成功</button>
<button class="btn c-error" onclick="demoLoadingFail()">提交失败</button>
</div>
<pre><span class="cm">// loading → success</span>
<span class="kw">const</span> loading = MeToast.<span class="fn">loading</span>(<span class="s">'正在提交...'</span>);
<span class="kw">setTimeout</span>(() => loading.<span class="fn">success</span>(<span class="s">'提交成功!'</span>), 2000);
<span class="cm">// loading → error</span>
<span class="kw">const</span> loading = MeToast.<span class="fn">loading</span>(<span class="s">'正在提交...'</span>);
<span class="kw">setTimeout</span>(() => loading.<span class="fn">error</span>(<span class="s">'提交失败,请重试'</span>), 2000);</pre>
</div>
</section>
<!-- Promise -->
<section class="section">
<h2>⛓ Promise 封装</h2>
<p>一行代码自动处理 loading / success / error</p>
<div class="card">
<div class="btn-row">
<button class="btn c-primary" onclick="demoPromise()">模拟请求</button>
</div>
<pre><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>,
}
);</pre>
</div>
</section>
<!-- 对话框 -->
<section class="section">
<h2>💬 确认框 & 输入框</h2>
<p>内置对话框,返回 Promise</p>
<div class="card">
<div class="btn-row">
<button class="btn c-pink" onclick="demoConfirm()">确认对话框</button>
<button class="btn c-teal" onclick="demoPrompt()">输入对话框</button>
</div>
<pre><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="fn">confirmColor</span>: <span class="s">'#ef4444'</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="fn">placeholder</span>: <span class="s">'请输入...'</span>,
});</pre>
</div>
</section>
<!-- 进度 & 倒计时 -->
<section class="section">
<h2>📊 进度条 & 倒计时</h2>
<p>实时更新的进度通知和自动倒计时</p>
<div class="card">
<div class="btn-row">
<button class="btn c-orange" onclick="demoProgress()">进度条</button>
<button class="btn c-info" onclick="demoCountdown()">倒计时 5s</button>
</div>
<pre><span class="cm">// 进度条 — 实时更新</span>
<span class="kw">const</span> p = MeToast.<span class="fn">progress</span>(<span class="s">'上传中...'</span>);
<span class="kw">let</span> v = 0;
<span class="kw">const</span> t = <span class="fn">setInterval</span>(() => {
v += <span class="fn">Math</span>.random() * 28;
<span class="kw">if</span> (v >= 100) { <span class="fn">clearInterval</span>(t); p.<span class="fn">complete</span>(<span class="s">'上传完成!'</span>); }
<span class="kw">else</span> p.<span class="fn">setProgress</span>(v);
}, 400);
<span class="cm">// 倒计时 — {seconds} 自动替换</span>
MeToast.<span class="fn">countdown</span>(<span class="s">'{seconds} 秒后执行'</span>, 5, {
<span class="fn">onComplete</span>: () => MeToast.<span class="fn">success</span>(<span class="s">'已执行'</span>),
});</pre>
</div>
</section>
<!-- 队列 & 堆叠 -->
<section class="section">
<h2>📋 队列 & 堆叠</h2>
<p>顺序逐个展示 or 同时错峰展示</p>
<div class="card">
<div class="btn-row">
<button class="btn c-primary" onclick="demoQueue()">队列展示</button>
<button class="btn c-purple" onclick="demoStack()">堆叠展示</button>
</div>
<pre><span class="cm">// 队列 — 一个接一个</span>
<span class="kw">await</span> MeToast.<span class="fn">queue</span>([<span class="s">'步骤一'</span>, <span class="s">'步骤二'</span>, <span class="s">'步骤三'</span>], {
<span class="fn">delay</span>: 800,
<span class="fn">duration</span>: 2000,
<span class="fn">type</span>: <span class="s">'info'</span>,
});
<span class="cm">// 堆叠 — 同时错峰</span>
MeToast.<span class="fn">stack</span>([<span class="s">'消息 1'</span>, <span class="s">'消息 2'</span>, <span class="s">'消息 3'</span>, <span class="s">'消息 4'</span>], {
<span class="fn">stagger</span>: 150,
<span class="fn">type</span>: <span class="s">'info'</span>,
});</pre>
</div>
</section>
<!-- 插件 -->
<section class="section">
<h2>🔌 插件</h2>
<p>3 款预设插件,按需安装</p>
<div class="card">
<div class="btn-row">
<button class="btn c-purple" onclick="MeToast.use('keyboard');MeToast.info('已安装 keyboard — 试试按 ESC')">keyboard</button>
<button class="btn c-info" onclick="MeToast.use('persistence');MeToast.info('已安装 persistence — 配置将自动保存')">persistence</button>
<button class="btn c-teal" onclick="MeToast.use('accessibility');MeToast.info('已安装 accessibility — 屏幕阅读器可用')">accessibility</button>
</div>
<pre><span class="cm">// keyboard — ESC 关闭所有 Toast</span>
MeToast.<span class="fn">use</span>(<span class="s">'keyboard'</span>);
<span class="cm">// persistence — 配置持久化(自动保存/加载)</span>
MeToast.<span class="fn">use</span>(<span class="s">'persistence'</span>);
<span class="cm">// accessibility — 屏幕阅读器朗读公告</span>
MeToast.<span class="fn">use</span>(<span class="s">'accessibility'</span>);</pre>
</div>
</section>
<!-- 全局配置 -->
<section class="section">
<h2>🔧 全局配置</h2>
<p>一次配置,所有 Toast 自动继承</p>
<div class="card">
<pre>MeToast.<span class="fn">configure</span>({
<span class="fn">position</span>: <span class="s">'top-right'</span>, <span class="cm">// 默认位置</span>
<span class="fn">duration</span>: 4000, <span class="cm">// 默认显示时长(ms)</span>
<span class="fn">max</span>: 6, <span class="cm">// 同时最多显示条数</span>
<span class="fn">theme</span>: <span class="s">'auto'</span>, <span class="cm">// light | dark | auto | warm</span>
<span class="fn">animation</span>: <span class="s">'slide'</span>, <span class="cm">// 默认动画效果</span>
<span class="fn">pauseOnHover</span>: <span class="kw">true</span>, <span class="cm">// 悬停暂停计时</span>
<span class="fn">closeOnClick</span>: <span class="kw">true</span>, <span class="cm">// 点击关闭</span>
<span class="fn">showProgress</span>: <span class="kw">true</span>, <span class="cm">// 显示进度条</span>
<span class="fn">draggable</span>: <span class="kw">true</span>, <span class="cm">// 允许拖拽关闭</span>
<span class="fn">locale</span>: <span class="s">'zh-CN'</span>, <span class="cm">// 默认语言</span>
});</pre>
</div>
</section>
<!-- 主题 -->
<section class="section">
<h2>🎨 主题 & 国际化</h2>
<p>内置四种主题,支持自定义注册;内置中英文,可扩展</p>
<div class="card">
<div class="btn-row">
<button class="btn c-slate" onclick="MeToast.themes.switchTheme('light');MeToast.configure({theme:'light'});MeToast.success('浅色主题')">浅色</button>
<button class="btn c-slate" onclick="MeToast.themes.switchTheme('dark');MeToast.configure({theme:'dark'});MeToast.success('深色主题')">深色</button>
<button class="btn c-slate" onclick="MeToast.themes.switchTheme('warm');MeToast.configure({theme:'warm'});MeToast.success('暖色主题')">暖色</button>
<button class="btn c-info" onclick="MeToast.i18n.switchLocale('en-US');MeToast.success('Switched to English')">EN</button>
<button class="btn c-info" onclick="MeToast.i18n.switchLocale('zh-CN');MeToast.success('已切换为中文')">中文</button>
</div>
<pre><span class="cm">// 切换主题(switchTheme + configure 同步全局配置)</span>
MeToast.themes.<span class="fn">switchTheme</span>(<span class="s">'warm'</span>);
MeToast.<span class="fn">configure</span>({ <span class="fn">theme</span>: <span class="s">'warm'</span> });
<span class="cm">// 切换语言 — 英文</span>
MeToast.i18n.<span class="fn">switchLocale</span>(<span class="s">'en-US'</span>);
<span class="cm">// 切换回中文</span>
MeToast.i18n.<span class="fn">switchLocale</span>(<span class="s">'zh-CN'</span>);
<span class="cm">// 注册自定义主题</span>
MeToast.themes.<span class="fn">registerTheme</span>(<span class="s">'ocean'</span>, {
<span class="fn">bg</span>: <span class="s">'rgba(240,249,255,0.96)'</span>,
<span class="fn">text</span>: <span class="s">'#0c4a6e'</span>,
<span class="fn">border</span>: <span class="s">'rgba(14,165,233,0.2)'</span>,
<span class="fn">shadow</span>: <span class="s">'0 10px 36px -10px rgba(14,165,233,0.18)'</span>,
<span class="fn">hoverShadow</span>: <span class="s">'0 14px 48px -10px rgba(14,165,233,0.22)'</span>,
<span class="fn">progressBg</span>: <span class="s">'rgba(14,165,233,0.1)'</span>,
<span class="fn">closeHoverBg</span>: <span class="s">'rgba(14,165,233,0.1)'</span>,
});</pre>
</div>
</section>
<!-- Toast 管理 -->
<section class="section">
<h2>🔧 Toast 管理</h2>
<p>查找、关闭、清除、暂停、恢复</p>
<div class="card">
<div class="btn-row">
<button class="btn c-success" onclick="MeToast.success('消息 '+Date.now()%100)">发一条</button>
<button class="btn c-info" onclick="MeToast.info('消息 '+Date.now()%100)">再发一条</button>
<button class="btn c-warning" onclick="alert('当前: '+MeToast.count()+' 条')">查看数量</button>
<button class="btn c-slate" onclick="MeToast.pauseAll();MeToast.info('已暂停全部计时')">暂停全部</button>
<button class="btn c-slate" onclick="MeToast.resumeAll();MeToast.info('已恢复全部计时')">恢复全部</button>
<button class="btn c-error" onclick="MeToast.dismiss()">关闭全部</button>
</div>
<pre>MeToast.<span class="fn">count</span>(); <span class="cm">// 当前数量</span>
MeToast.<span class="fn">getToasts</span>(); <span class="cm">// 获取所有实例</span>
MeToast.<span class="fn">dismiss</span>(); <span class="cm">// 关闭全部</span>
MeToast.<span class="fn">dismiss</span>(id); <span class="cm">// 关闭指定</span>
MeToast.<span class="fn">pauseAll</span>(); <span class="cm">// 暂停全部计时</span>
MeToast.<span class="fn">resumeAll</span>(); <span class="cm">// 恢复全部计时</span>
MeToast.<span class="fn">destroy</span>(); <span class="cm">// 完全销毁</span></pre>
</div>
</section>
<!-- API 速览 -->
<section class="section">
<h2>📖 API 速览</h2>
<div class="card">
<table class="api-table">
<tr><th>方法</th><th>说明</th><th>示例</th></tr>
<tr><td><code>success(msg, opts?)</code></td><td>成功通知</td><td><code>MeToast.success('保存成功')</code></td></tr>
<tr><td><code>error(msg, opts?)</code></td><td>错误通知</td><td><code>MeToast.error('网络错误')</code></td></tr>
<tr><td><code>warning(msg, opts?)</code></td><td>警告通知</td><td><code>MeToast.warning('请注意')</code></td></tr>
<tr><td><code>info(msg, opts?)</code></td><td>信息通知</td><td><code>MeToast.info('系统维护中')</code></td></tr>
<tr><td><code>loading(msg, opts?)</code></td><td>加载状态</td><td><code>MeToast.loading('加载中...')</code></td></tr>
<tr><td><code>promise(p, opts)</code></td><td>Promise 自动状态</td><td><code>MeToast.promise(fetch(...), opts)</code></td></tr>
<tr><td><code>confirm(msg, opts?)</code></td><td>确认对话框 → boolean</td><td><code>await MeToast.confirm('删除?')</code></td></tr>
<tr><td><code>prompt(msg, opts?)</code></td><td>输入对话框 → string</td><td><code>await MeToast.prompt('姓名?')</code></td></tr>
<tr><td><code>progress(msg, opts?)</code></td><td>进度条通知</td><td><code>MeToast.progress('上传中...')</code></td></tr>
<tr><td><code>countdown(msg, s, opts?)</code></td><td>倒计时</td><td><code>MeToast.countdown('{seconds}s', 10)</code></td></tr>
<tr><td><code>queue(msgs, opts?)</code></td><td>队列顺序展示</td><td><code>MeToast.queue(['a','b','c'])</code></td></tr>
<tr><td><code>stack(msgs, opts?)</code></td><td>堆叠错峰展示</td><td><code>MeToast.stack(['a','b','c'])</code></td></tr>
<tr><td><code>configure(opts)</code></td><td>全局配置</td><td><code>MeToast.configure({duration:5000})</code></td></tr>
<tr><td><code>dismiss(id?)</code></td><td>关闭 toast</td><td><code>MeToast.dismiss()</code></td></tr>
</table>
</div>
</section>
</main>
<footer>
<p>MetonaToast v2.0.0 · <a href="demo.html">全功能演示 →</a></p>
</footer>
<script src="../dist/metona-toast.js"></script>
<script>
MeToast.configure({ position: 'top-right', duration: 4000, theme: 'dark', animation: 'slide', pauseOnHover: true, showProgress: true });
function demoLoading() {
const l = MeToast.loading('正在提交...');
setTimeout(() => l.success('提交成功!'), 2000);
}
function demoLoadingFail() {
const l = MeToast.loading('正在提交...');
setTimeout(() => l.error('提交失败,请重试'), 2000);
}
async function demoPromise() {
const p = new Promise((resolve, reject) => {
setTimeout(() => Math.random() > 0.3 ? resolve('ok') : reject('fail'), 2000);
});
try { await MeToast.promise(p, { loading: '加载中...', success: '加载完成!', error: '加载失败' }); } catch (_) {}
}
async function demoConfirm() {
const ok = await MeToast.confirm('确定删除吗?', { confirmText: '删除', confirmColor: '#ef4444' });
if (ok) MeToast.success('已删除'); else MeToast.info('已取消');
}
async function demoPrompt() {
const name = await MeToast.prompt('请输入姓名', { placeholder: '请输入...' });
if (name) MeToast.info(`你好,${name}`);
}
function demoProgress() {
const p = MeToast.progress('上传中...');
let v = 0;
const t = setInterval(() => { v += Math.random() * 28; if (v >= 100) { clearInterval(t); p.complete('上传完成!'); } else p.setProgress(v); }, 400);
}
function demoCountdown() {
MeToast.countdown('{seconds} 秒后执行', 5, { onComplete: () => MeToast.success('已执行') });
}
async function demoQueue() {
await MeToast.queue(['步骤一', '步骤二', '步骤三'], { delay: 800, duration: 2000, type: 'info' });
}
function demoStack() {
MeToast.stack(['消息 1', '消息 2', '消息 3', '消息 4'], { stagger: 150, type: 'info' });
}
</script>
</body>
</html>