Files
MetonaToast/site/demo.html
T

260 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">
<title>在线演示 — MetonaToast</title>
<style>
:root {
--bg: #0b1121; --surface: #151d33; --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.6; min-height:100vh; }
a { color:var(--accent2); text-decoration:none; }
code { background:rgba(99,102,241,0.12); color:#a5b4fc; padding:1px 6px; border-radius:4px; font-size:0.85em; }
.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:1300px; margin:0 auto; display:flex; align-items:center; justify-content:space-between; padding:0 20px; 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:20px; }
.nav-links a { color:var(--muted); font-size:13px; font-weight:500; transition:.2s; }
.nav-links a:hover { color:var(--accent2); }
.hero { text-align:center; padding:50px 20px 40px; border-bottom:1px solid var(--border); background:radial-gradient(ellipse at 50% 0%,rgba(99,102,241,0.12) 0%,transparent 50%); }
.hero h1 { font-size:36px; 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:14px; margin-top:6px; }
.container { max-width:1300px; margin:0 auto; padding:32px 20px; display:grid; grid-template-columns:repeat(auto-fill,minmax(380px,1fr)); gap:20px; }
.card { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:22px; }
.card h2 { font-size:16px; margin-bottom:4px; }
.card > p { color:var(--muted); font-size:12px; margin-bottom:14px; }
.btn-row { display:flex; flex-wrap:wrap; gap:7px; }
.btn { padding:8px 15px; border:none; border-radius:7px; font-size:12px; font-weight:500; cursor:pointer; transition:.15s; color:#fff; }
.btn:hover { transform:translateY(-1px); filter:brightness(1.15); }
.btn-sm { padding:5px 10px; font-size:11px; border-radius:5px; }
.btn-outline { background:transparent; border:1px solid var(--border); color:var(--text); }
.btn-outline:hover { border-color:var(--accent); background:rgba(99,102,241,0.06); }
.c-s { background:#10b981; } .c-e { background:#ef4444; } .c-w { background:#f59e0b; color:#1e293b; }
.c-i { background:#3b82f6; } .c-p { background:#6366f1; } .c-pp { background:#8b5cf6; }
.c-pk { background:#ec4899; } .c-t { background:#14b8a6; } .c-o { background:#f97316; }
.c-sl { background:#475569; } .c-r { background:#f43f5e; }
.label { font-size:10px; text-transform:uppercase; letter-spacing:0.8px; color:var(--muted); margin-bottom:12px; font-weight:600; }
.demo-section { border-top:1px solid var(--border); padding-top:10px; margin-top:10px; }
footer { text-align:center; padding:30px 20px; color:var(--muted); font-size:12px; border-top:1px solid var(--border); }
@media (max-width:768px) { .container { grid-template-columns:1fr; } }
</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://github.com/metona/metona-toast" target="_blank">GitHub</a>
</div>
</div>
</nav>
<header class="hero">
<h1><span>在线演示</span></h1>
<p>所有功能均可点击体验 — 192 个测试用例全部通过验证</p>
</header>
<main class="container">
<!-- 基础通知 -->
<div class="card">
<div class="label">📢 基础通知</div>
<div class="btn-row">
<button class="btn c-s" onclick="M.success('操作成功!')">✓ 成功</button>
<button class="btn c-e" onclick="M.error('操作失败!')">✕ 错误</button>
<button class="btn c-w" onclick="M.warning('请注意检查')">⚠ 警告</button>
<button class="btn c-i" onclick="M.info('系统维护中')"> 信息</button>
<button class="btn c-sl" onclick="M.show('默认消息')">— 默认</button>
</div>
<div class="demo-section">
<div class="btn-row">
<button class="btn btn-outline btn-sm" onclick="M.success({title:'保存成功',message:'文件已同步到云端'})">带标题</button>
<button class="btn btn-outline btn-sm" onclick="M.info('显示10秒',{duration:10000})">长时10s</button>
<button class="btn btn-outline btn-sm" onclick="M.info('手动关闭',{duration:0})">手动关闭</button>
<button class="btn btn-outline btn-sm" onclick="M.info('隐藏图标',{icon:false})">无图标</button>
<button class="btn btn-outline btn-sm" onclick="M.info('隐藏进度条',{showProgress:false})">无进度条</button>
</div>
</div>
</div>
<!-- Loading 链式 -->
<div class="card">
<div class="label">🔄 Loading 链式转换</div>
<div class="btn-row">
<button class="btn c-p" onclick="demoLoading()">提交成功</button>
<button class="btn c-e" onclick="demoLoadingFail()">提交失败</button>
<button class="btn c-pp" onclick="demoPromise()">Promise 风格</button>
</div>
</div>
<!-- 对话框 -->
<div class="card">
<div class="label">💬 对话框</div>
<div class="btn-row">
<button class="btn c-pk" onclick="demoConfirm()">确认对话框</button>
<button class="btn c-t" onclick="demoPrompt()">输入对话框</button>
<button class="btn c-o" onclick="demoCountdown()">倒计时 5s</button>
</div>
</div>
<!-- 进度 & 队列 -->
<div class="card">
<div class="label">📊 进度 & 队列</div>
<div class="btn-row">
<button class="btn c-o" onclick="demoProgress()">进度条</button>
<button class="btn c-p" onclick="demoQueue()">队列展示</button>
<button class="btn c-pp" onclick="demoStack()">堆叠展示</button>
</div>
</div>
<!-- Action Toast -->
<div class="card">
<div class="label">⚡ Action Toast <span style="color:#34d399;font-size:10px;">NEW</span></div>
<div class="btn-row">
<button class="btn c-e" onclick="demoActionDelete()">删除+撤销</button>
<button class="btn c-i" onclick="demoActionMulti()">多个操作</button>
<button class="btn c-s" onclick="demoActionSuccess()">成功+查看</button>
</div>
</div>
<!-- 分组管理 -->
<div class="card">
<div class="label">📁 分组管理 <span style="color:#34d399;font-size:10px;">NEW</span></div>
<div class="btn-row">
<button class="btn c-p" onclick="demoGroup()">创建分组</button>
<button class="btn c-e" onclick="dismissGroup()">关闭分组</button>
<button class="btn btn-outline btn-sm" onclick="M.info('分组数量: '+group.count())">查看数量</button>
</div>
</div>
<!-- 动画效果 -->
<div class="card">
<div class="label">🎭 动画效果</div>
<div class="btn-row">
<button class="btn btn-outline btn-sm" onclick="anim('slide')">slide</button>
<button class="btn btn-outline btn-sm" onclick="anim('fade')">fade</button>
<button class="btn btn-outline btn-sm" onclick="anim('scale')">scale</button>
<button class="btn btn-outline btn-sm" onclick="anim('bounce')">bounce</button>
<button class="btn btn-outline btn-sm" onclick="anim('flip')">flip</button>
<button class="btn btn-outline btn-sm" onclick="anim('rotate')">rotate</button>
<button class="btn btn-outline btn-sm" onclick="anim('zoom')">zoom</button>
<button class="btn btn-outline btn-sm" onclick="anim('slideUp')">slideUp</button>
<button class="btn btn-outline btn-sm" onclick="anim('slideDown')">slideDown</button>
<button class="btn btn-outline btn-sm" onclick="anim('slideLeft')">slideLeft</button>
<button class="btn btn-outline btn-sm" onclick="anim('slideRight')">slideRight</button>
</div>
</div>
<!-- 位置 -->
<div class="card">
<div class="label">📍 位置</div>
<div class="btn-row">
<button class="btn c-sl" onclick="M.success('左上角',{position:'top-left'})">↖ top-left</button>
<button class="btn c-sl" onclick="M.success('顶部居中',{position:'top-center'})">↑ top-center</button>
<button class="btn c-sl" onclick="M.success('右上角',{position:'top-right'})">↗ top-right</button>
<button class="btn c-sl" onclick="M.success('左下角',{position:'bottom-left'})">↙ bottom-left</button>
<button class="btn c-sl" onclick="M.success('底部居中',{position:'bottom-center'})">↓ bottom-center</button>
<button class="btn c-sl" onclick="M.success('右下角',{position:'bottom-right'})">↘ bottom-right</button>
</div>
</div>
<!-- 主题 -->
<div class="card">
<div class="label">🎨 主题切换</div>
<div class="btn-row">
<button class="btn btn-outline btn-sm" onclick="switchTheme('light')">☀️ Light</button>
<button class="btn btn-outline btn-sm" onclick="switchTheme('dark')">🌙 Dark</button>
<button class="btn btn-outline btn-sm" onclick="switchTheme('auto')">🔄 Auto</button>
<button class="btn btn-outline btn-sm" onclick="switchTheme('warm')">🔥 Warm</button>
</div>
</div>
<!-- 插件 -->
<div class="card">
<div class="label">🔌 插件</div>
<div class="btn-row">
<button class="btn c-p" onclick="M.use('keyboard');M.info('已安装 — 试试按 ESC 键','keyboard插件')">keyboard ESC关闭</button>
<button class="btn c-i" onclick="M.use('persistence');M.info('已安装 — 配置将自动保存','persistence插件')">persistence 持久化</button>
<button class="btn c-t" onclick="M.use('accessibility');M.info('已安装 — 屏幕阅读器可用','accessibility插件')">accessibility 无障碍</button>
</div>
</div>
<!-- 管理 -->
<div class="card">
<div class="label">🔧 Toast 管理</div>
<div class="btn-row">
<button class="btn c-s" onclick="M.success('消息 '+(M.count()+1))">发一条</button>
<button class="btn c-i" onclick="M.info('消息 '+(M.count()+1))">再发一条</button>
<button class="btn c-w" onclick="alert('当前共 '+M.count()+' 条消息')">查看数量</button>
<button class="btn c-e" onclick="M.dismiss()">关闭全部</button>
<button class="btn c-sl" onclick="M.pauseAll();M.info('已暂停全部计时')">暂停全部</button>
<button class="btn c-sl" onclick="M.resumeAll();M.info('已恢复全部计时')">恢复全部</button>
</div>
</div>
</main>
<footer>
MetonaToast v2.0.0 · MIT License · <a href="index.html">首页</a> · <a href="docs.html">文档</a>
</footer>
<script src="../dist/metona-toast.js"></script>
<script>
const M = MeToast;
M.configure({ position:'top-right', duration:4000, theme:'dark', animation:'slide', pauseOnHover:true, showProgress:true });
// Loading
function demoLoading() { const l=M.loading('正在提交...'); setTimeout(()=>l.success('提交成功!'),2000); }
function demoLoadingFail() { const l=M.loading('正在提交...'); setTimeout(()=>l.error('提交失败,请重试'),2000); }
async function demoPromise() {
const p=new Promise((r,e)=>setTimeout(()=>Math.random()>0.3?r('ok'):e('fail'),2000));
try{await M.promise(p,{loading:'处理中...',success:'成功!',error:'失败'});}catch(_){}
}
// 对话框
async function demoConfirm() { const ok=await M.confirm('确定删除吗?',{confirmText:'删除',confirmColor:'#ef4444'}); if(ok)M.success('已删除'); else M.info('已取消'); }
async function demoPrompt() { const v=await M.prompt('请输入姓名',{placeholder:'请输入...'}); if(v) M.info('你好,'+v+''); }
// 进度 & 队列
function demoProgress() { const p=M.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() { M.countdown('{seconds} 秒后执行',5,{onComplete:()=>M.success('已执行')}); }
async function demoQueue() { await M.queue(['步骤一','步骤二','步骤三'],{delay:800,duration:2000,type:'info'}); }
function demoStack() { M.stack(['消息1','消息2','消息3','消息4'],{stagger:150,type:'info'}); }
// Action
function demoActionDelete() {
let deleted=true;
M.action('文件 data.json 已删除',[{text:'撤销',onClick:()=>{deleted=false;M.success('已撤销删除');},color:'#3b82f6'}]);
}
function demoActionMulti() {
M.action('邮件已发送',[
{text:'查看',onClick:()=>M.info('打开邮件详情'),color:'#3b82f6'},
{text:'撤回',onClick:()=>M.warning('邮件已撤回'),color:'#f59e0b'},
]);
}
function demoActionSuccess() {
M.action('上传完成',[{text:'查看文件',onClick:()=>M.info('打开文件管理器'),color:'#10b981'}]);
}
// 分组
const group = M.group('demo-group');
function demoGroup() { group.success('分组消息 #'+(group.count()+1)); group.info('分组消息 #'+(group.count()+1)); }
function dismissGroup() { M.dismissGroup('demo-group'); M.info('已关闭 demo-group 分组'); }
// 动画
function anim(name) { M.success('动画: '+name,{animation:name,duration:3000}); }
function switchTheme(t) { M.themes.switchTheme(t); M.configure({theme:t}); const n={light:'浅色',dark:'深色',auto:'自动',warm:'暖色'}; M.info('主题: '+n[t],{theme:t}); }
</script>
</body>
</html>