900 lines
56 KiB
HTML
900 lines
56 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>课程书架 组件设计稿 · Storybook 形式 · stack idealjs</title>
|
||
<style>
|
||
/* ====== 画布与页面基座(与整页版 v2 一致) ====== */
|
||
@page { size: 1280px 800px; margin: 0; }
|
||
*, *::before, *::after { box-sizing: border-box; }
|
||
html, body {
|
||
margin: 0; padding: 0; width: 1280px;
|
||
background: #f0f0ef;
|
||
font-family: "Noto Sans CJK SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||
color: #1a1a1a;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
.page {
|
||
width: 1280px; height: 800px; position: relative;
|
||
background: #f0f0ef; overflow: hidden; page-break-after: always;
|
||
}
|
||
.page:last-child { page-break-after: auto; }
|
||
|
||
@media screen {
|
||
html { height: auto; display: flex; justify-content: center; background: #f0f0ef; }
|
||
body {
|
||
transform-origin: top center;
|
||
scale: min(1, calc(100vw / 1280px));
|
||
margin: 0 auto;
|
||
box-shadow: 0 0 48px rgba(15, 23, 42, 0.18);
|
||
}
|
||
}
|
||
|
||
.pagenum { position: absolute; bottom: 26px; right: 40px; font-size: 13px; color: #8a8a8a; letter-spacing: 2px; }
|
||
.footline { position: absolute; bottom: 26px; left: 40px; font-size: 13px; color: #8a8a8a; letter-spacing: 1px; }
|
||
|
||
/* ====== Storybook 页头 ====== */
|
||
.story-head { position: absolute; top: 36px; left: 40px; right: 40px; }
|
||
.story-head .tag {
|
||
display: inline-block; font-size: 15px; font-weight: 700; color: #6d28d9;
|
||
background: #efe6fb; border-radius: 8px; padding: 3px 12px;
|
||
font-family: "DejaVu Sans Mono", "Noto Sans CJK SC", monospace;
|
||
}
|
||
.story-head h2 { margin: 8px 0 4px; font-size: 28px; font-weight: 800; color: #1a1a1a; }
|
||
.story-head .desc { font-size: 14.5px; color: #6b6b6b; }
|
||
|
||
/* ====== 展示画布与变体 ====== */
|
||
.canvas {
|
||
background: #fbfbfa;
|
||
border: 1px dashed #cfcfcd;
|
||
border-radius: 18px;
|
||
padding: 22px;
|
||
position: absolute;
|
||
}
|
||
.vrow { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
|
||
.variant { display: flex; flex-direction: column; gap: 8px; }
|
||
.vlabel {
|
||
font-size: 11.5px; color: #6b6b6b;
|
||
font-family: "DejaVu Sans Mono", "Noto Sans CJK SC", monospace;
|
||
}
|
||
.vlabel b { color: #1a1a1a; }
|
||
|
||
.note { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 8px; }
|
||
.note .idx {
|
||
flex: none; width: 22px; height: 22px; border-radius: 50%;
|
||
background: #1a1a1a; color: #ffffff; font-size: 13px; font-weight: 700;
|
||
display: flex; align-items: center; justify-content: center; margin-top: 1px;
|
||
}
|
||
.note .txt { font-size: 13.5px; line-height: 1.55; color: #3d3d3d; }
|
||
.note .txt b { color: #1a1a1a; }
|
||
.panel { background: #ffffff; border-radius: 18px; padding: 18px 20px; box-shadow: 0 1px 2px rgba(26,26,26,0.06); }
|
||
.panel h3 { margin: 0 0 10px; font-size: 16px; font-weight: 700; color: #1a1a1a; }
|
||
|
||
table.spec { width: 100%; border-collapse: collapse; font-size: 12.5px; color: #3d3d3d; }
|
||
table.spec th { text-align: left; font-weight: 700; color: #1a1a1a; border-bottom: 2px solid #d5d5d3; padding: 6px 10px 6px 0; }
|
||
table.spec td { border-bottom: 1px solid #ececea; padding: 5px 10px 5px 0; vertical-align: top; }
|
||
table.spec td.k { color: #1a1a1a; font-weight: 600; white-space: nowrap; }
|
||
table.spec code {
|
||
font-family: "DejaVu Sans Mono", monospace; font-size: 12px;
|
||
background: #f4f2fa; color: #6d28d9; border-radius: 5px; padding: 1px 6px;
|
||
}
|
||
|
||
/* ====== 组件本体样式(复用整页版 v2) ====== */
|
||
.topbar {
|
||
height: 46px; background: #111111; color: #b9b9b9;
|
||
border-radius: 12px; display: flex; align-items: center;
|
||
padding: 0 16px; gap: 22px; font-size: 12.5px;
|
||
}
|
||
.topbar .logo { color: #ffffff; font-weight: 800; letter-spacing: 0.5px; font-size: 13.5px; }
|
||
.topbar .menu { display: flex; gap: 20px; margin: 0 auto; }
|
||
.topbar .menu span.active { color: #ffffff; font-weight: 600; }
|
||
.topbar .ava {
|
||
width: 24px; height: 24px; border-radius: 50%;
|
||
background: #6366f1;
|
||
display: flex; align-items: center; justify-content: center;
|
||
color: #fff; font-size: 11px; font-weight: 700;
|
||
}
|
||
.topbar .bell { font-size: 14px; }
|
||
|
||
.rail {
|
||
width: 40px; background: #ffffff; border-radius: 12px;
|
||
display: flex; flex-direction: column; align-items: center;
|
||
gap: 14px; padding: 14px 0; font-size: 14px; color: #8a8a8a;
|
||
}
|
||
|
||
.searchpill {
|
||
font-size: 12.5px; color: #8a8a8a; background: #fff;
|
||
border-radius: 999px; padding: 7px 20px; border: 1px solid #d5d5d3;
|
||
}
|
||
|
||
.stat {
|
||
border-radius: 16px; padding: 12px 18px 10px;
|
||
display: flex; flex-direction: column; gap: 2px; min-width: 150px;
|
||
}
|
||
.stat .num { font-size: 26px; font-weight: 800; color: #1a1a1a; }
|
||
.stat .lab { font-size: 11px; color: #6b6b6b; letter-spacing: 0.5px; }
|
||
|
||
.pill { font-size: 10.5px; padding: 3px 11px; border-radius: 999px; font-weight: 600; }
|
||
.pill.done { background: #efe6fb; color: #6d28d9; }
|
||
.pill.wip { background: #ffffff; color: #6b6b6b; border: 1px solid #d5d5d3; }
|
||
.pill.time { background: #ffffff; color: #1a1a1a; border: 1px solid #d5d5d3; }
|
||
|
||
.cbtn {
|
||
width: 26px; height: 26px; border-radius: 50%;
|
||
background: #1a1a1a; color: #ffffff;
|
||
display: flex; align-items: center; justify-content: center; font-size: 12px;
|
||
}
|
||
|
||
.chip { font-size: 10px; color: #555; border: 1px solid #cfcfcd; border-radius: 999px; padding: 1px 8px; }
|
||
|
||
.icotile {
|
||
width: 26px; height: 26px; border-radius: 9px;
|
||
display: flex; align-items: center; justify-content: center; font-size: 14px;
|
||
}
|
||
|
||
.ccard {
|
||
background: #ffffff; border-radius: 16px;
|
||
padding: 10px 12px 10px 14px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.06);
|
||
display: flex; flex-direction: column; gap: 5px;
|
||
width: 262px;
|
||
}
|
||
.ccard .icorow { display: flex; align-items: center; gap: 8px; }
|
||
.ccard .zone {
|
||
width: 100%; aspect-ratio: 16 / 9; border-radius: 10px;
|
||
background: #f7f7f5; border: 1px solid #ececea;
|
||
display: flex; align-items: center; padding: 10px 12px;
|
||
font-size: 11px; color: #8a8a8a; line-height: 1.5;
|
||
}
|
||
.ccard .ttl { font-size: 13.5px; font-weight: 700; color: #1a1a1a; margin: 0; }
|
||
.ccard .dsc { font-size: 11px; line-height: 1.4; color: #8a8a8a; margin: 0; flex: 1; }
|
||
.ccard .btm { display: flex; align-items: center; justify-content: space-between; }
|
||
.ccard.media { background: var(--tint, #e0e7ff); box-shadow: none; }
|
||
.ccard.media .player {
|
||
flex: 1; min-height: 54px; border-radius: 12px;
|
||
background: var(--tint, #e0e7ff);
|
||
display: flex; align-items: center; justify-content: center; position: relative;
|
||
}
|
||
.playbtn {
|
||
width: 44px; height: 44px; border-radius: 50%;
|
||
background: #111111; color: #ffffff;
|
||
display: flex; align-items: center; justify-content: center; font-size: 16px;
|
||
box-shadow: 0 4px 14px rgba(17,17,17,0.28);
|
||
}
|
||
|
||
.ev { border-radius: 14px; padding: 10px 12px; display: flex; flex-direction: column; gap: 3px; width: 224px; }
|
||
.ev .r1 { display: flex; justify-content: space-between; align-items: center; font-size: 10.5px; font-weight: 700; color: #1a1a1a; }
|
||
.ev .date { font-size: 9.5px; color: #6b6b6b; font-weight: 600; }
|
||
.ev .r2 { font-size: 10.5px; color: #555; line-height: 1.45; }
|
||
.ev .r3 { font-size: 9.5px; color: #6b6b6b; }
|
||
|
||
/* P1 目录卡 */
|
||
.toc-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
|
||
.toc-card { background: #fff; border-radius: 14px; padding: 14px 16px; box-shadow: 0 1px 2px rgba(26,26,26,0.06); }
|
||
.toc-card .t { font-family: "DejaVu Sans Mono", monospace; font-size: 13.5px; font-weight: 700; color: #6d28d9; }
|
||
.toc-card .c { font-size: 12.5px; font-weight: 700; color: #1a1a1a; margin-top: 3px; }
|
||
.toc-card .d { font-size: 11px; color: #8a8a8a; margin-top: 3px; line-height: 1.45; }
|
||
/* P7 课程关系图 */
|
||
.gnode {
|
||
position: absolute; width: 180px; height: 46px;
|
||
background: #ffffff; border-radius: 12px;
|
||
display: flex; align-items: center; gap: 9px; padding: 0 14px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.10);
|
||
}
|
||
.gnode .t { font-size: 13px; font-weight: 700; color: #1a1a1a; flex: 1; }
|
||
.gnode .st { font-size: 10px; padding: 1px 7px; border-radius: 999px; font-weight: 600; }
|
||
.gnode .st.done { background: #efe6fb; color: #6d28d9; }
|
||
.gnode .st.lock { background: #ffffff; color: #6b6b6b; border: 1px solid #d5d5d3; }
|
||
.gnode.rot-l { transform: rotate(-1.5deg); }
|
||
.gnode.rot-r { transform: rotate(1.2deg); }
|
||
.entry-badge {
|
||
position: absolute; top: -10px; left: -10px;
|
||
width: 22px; height: 22px; border-radius: 50%;
|
||
background: #6366f1; color: #ffffff; font-size: 12px; font-weight: 700;
|
||
display: flex; align-items: center; justify-content: center;
|
||
}
|
||
.gedges { position: absolute; inset: 0; pointer-events: none; }
|
||
.edge { fill: none; stroke-width: 1.2; stroke-linecap: butt; stroke-dasharray: 6 3; stroke: #a3b5af; }
|
||
.station { fill: #78928a; }
|
||
.glegend { display: flex; gap: 22px; font-size: 12px; color: #555; align-items: center; }
|
||
.glegend .sw { display: inline-block; width: 30px; border-top: 1.5px dashed #9a9a98; margin-right: 6px; vertical-align: middle; }
|
||
.glegend .sw.rel { border-top-color: #c9c9c7; }
|
||
|
||
/* P8 入口梳理 */
|
||
.profile-card {
|
||
background: #ffffff; border-radius: 16px; padding: 18px 20px;
|
||
width: 368px; display: flex; flex-direction: column; gap: 11px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.06);
|
||
}
|
||
.profile-card .ph { display: flex; align-items: center; gap: 10px; }
|
||
.path-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
|
||
.path-chips .arr { color: #8a8a8a; font-size: 11px; }
|
||
.path-chips .pchip { font-size: 11px; padding: 3px 10px; border-radius: 999px; border: 1px solid #cfcfcd; color: #1a1a1a; background: #ffffff; }
|
||
.path-chips .pchip.start { border-color: #6366f1; color: #6366f1; font-weight: 700; }
|
||
table.spec.tight { font-size: 12px; }
|
||
table.spec.tight th { padding: 4px 10px 4px 0; }
|
||
table.spec.tight td { padding: 3px 10px 3px 0; }
|
||
|
||
/* P7 路线图(线条构件版) */
|
||
.rnode {
|
||
position: absolute; width: 160px; height: 44px;
|
||
background: #ffffff; border-radius: 12px;
|
||
display: flex; align-items: center; gap: 7px; padding: 0 12px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.10);
|
||
}
|
||
.rnode .t { font-size: 12px; font-weight: 700; color: #1a1a1a; flex: 1; }
|
||
.rnode .st { font-size: 9.5px; padding: 1px 6px; border-radius: 999px; font-weight: 600; }
|
||
.rnode .st.done { background: #efe6fb; color: #6d28d9; }
|
||
.rnode .st.lock { background: #ffffff; color: #6b6b6b; border: 1px solid #d5d5d3; }
|
||
.rnode .icotile { width: 22px; height: 22px; border-radius: 7px; font-size: 12px; }
|
||
.linecard {
|
||
background: #ffffff; border-radius: 14px; padding: 12px 14px 10px;
|
||
display: flex; flex-direction: column; gap: 6px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.06);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ================= P1 封面 + 组件目录 ================= -->
|
||
<div class="page">
|
||
<div style="position:absolute; top:0; left:0; right:0; height:46px; background:#111; color:#b9b9b9; display:flex; align-items:center; padding:0 40px; gap:26px; font-size:13px;">
|
||
<span style="color:#fff; font-weight:800; font-size:15px;">stack·idealjs</span>
|
||
<span style="display:flex; gap:24px; margin:0 auto;"><span style="color:#fff;">全栈教程 🎓</span><span>工具使用</span><span>博客</span></span>
|
||
<span style="width:26px; height:26px; border-radius:50%; background:#6366f1;"></span>
|
||
</div>
|
||
<div style="position:absolute; top: 110px; left: 80px; font-size:15px; letter-spacing:4px; font-weight:500; color:#6b6b6b;">STACK IDEALJS · 全栈工程师教程</div>
|
||
<h1 style="position:absolute; top: 158px; left: 80px; margin:0; font-size:74px; line-height:1.15; font-weight:800; color:#1a1a1a;">组件设计稿 · Storybook 拆分</h1>
|
||
<div style="position:absolute; top: 280px; left: 80px; font-size:18px; color:#555; line-height:1.7;">
|
||
整页设计稿(course-shelf v2)拆解为 10 个可独立实现与验收的组件、9 页 stories:变体展示 + Args 表 + 规格。<br>
|
||
组件即实现单元:Docusaurus 侧按组件对应文件落码,每页 stories 即验收清单。
|
||
</div>
|
||
<div style="position:absolute; top: 408px; left: 80px; right: 80px;" class="toc-grid">
|
||
<div class="toc-card"><div class="t"><TopBar /></div><div class="c">黑顶栏</div><div class="d">logo · 菜单 · 当前项高亮 · 🔔 · 头像</div></div>
|
||
<div class="toc-card"><div class="t"><IconRail /></div><div class="c">左窄图标栏</div><div class="d">40px 宽,图标导航</div></div>
|
||
<div class="toc-card"><div class="t"><SearchPill /></div><div class="c">搜索胶囊</div><div class="d">页面标题行右侧搜索</div></div>
|
||
<div class="toc-card"><div class="t"><StatsRow /></div><div class="c">统计卡行</div><div class="d">大数字 + 灰标签,淡彩底</div></div>
|
||
<div class="toc-card"><div class="t"><CourseCard /></div><div class="c">课程白卡</div><div class="d">16:9 预期区(desc ⇄ GIF)· 状态 · 按钮</div></div>
|
||
<div class="toc-card"><div class="t"><CourseCardMedia /></div><div class="c">播放态</div><div class="d">定时翻转/悬停锁定 + ⏱ GIF 循环</div></div>
|
||
<div class="toc-card"><div class="t"><EventsPanel /></div><div class="c">事件栏</div><div class="d">彩色条目:类型 · 日期 · 描述 · 时间</div></div>
|
||
<div class="toc-card"><div class="t"><CourseGraph /></div><div class="c">课程路线图</div><div class="d">一条干线六站点 · 入口 ①②③</div></div>
|
||
<div class="toc-card"><div class="t"><EntryGuide /></div><div class="c">入口梳理</div><div class="d">读者画像 → 起点与路径</div></div>
|
||
<div class="toc-card"><div class="t">Atoms</div><div class="c">原子组件</div><div class="d">Pill · CircleButton · Chip · IconTile</div></div>
|
||
</div>
|
||
<div style="position:absolute; bottom: 78px; left: 80px; display:flex; gap:14px;">
|
||
<div class="stat" style="background:#c9e7f7;"><span class="num">10</span><span class="lab">Components · 组件</span></div>
|
||
<div class="stat" style="background:#d2f5df;"><span class="num">9</span><span class="lab">Stories · 页</span></div>
|
||
<div class="stat" style="background:#efe6fb;"><span class="num">6</span><span class="lab">Variants · 课程变体</span></div>
|
||
</div>
|
||
<div style="position:absolute; bottom: 62px; right: 80px; text-align:right; font-size:14px; color:#8a8a8a; line-height:1.8;">
|
||
v2.1 · 2026-10 · 派生自 course-shelf v2<br>复刻视觉:Learning Plan Dashboard(仅风格参考)
|
||
</div>
|
||
<div class="pagenum">01 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P2 TopBar · IconRail · SearchPill ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><TopBar /> <IconRail /> <SearchPill /></span>
|
||
<h2>骨架导航组件</h2>
|
||
<div class="desc">页面骨架三件套:黑顶栏承载站点导航,左窄栏承载快捷入口,搜索胶囊附属于标题行。</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 150px; left: 40px; width: 760px; height: 250px;">
|
||
<div class="vrow" style="flex-direction: column; gap: 18px;">
|
||
<div class="variant">
|
||
<div class="topbar" style="width: 716px;">
|
||
<span class="logo">stack·idealjs</span>
|
||
<span class="menu"><span class="active">全栈教程 🎓</span><span>工具使用</span><span>实践经历</span><span>博客</span></span>
|
||
<span class="bell">🔔</span>
|
||
<span class="ava">初</span>
|
||
</div>
|
||
<div class="vlabel"><b>default</b> · active = 全栈教程</div>
|
||
</div>
|
||
<div class="variant">
|
||
<div class="topbar" style="width: 716px;">
|
||
<span class="logo">stack·idealjs</span>
|
||
<span class="menu"><span>全栈教程 🎓</span><span>工具使用</span><span>实践经历</span><span class="active">博客</span></span>
|
||
<span class="bell">🔔</span>
|
||
<span class="ava">初</span>
|
||
</div>
|
||
<div class="vlabel"><b>variant</b> · active = 博客(随路由切换)</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 424px; left: 40px; width: 760px; height: 190px;">
|
||
<div class="vrow" style="gap: 28px;">
|
||
<div class="variant">
|
||
<div class="rail" style="height: 128px;"><span>🏠</span><span>📚</span><span>🧩</span><span>⚙️</span></div>
|
||
<div class="vlabel"><b><IconRail /></b> · w 40 · 4 icons</div>
|
||
</div>
|
||
<div class="variant">
|
||
<div class="searchpill">Search…</div>
|
||
<div class="vlabel"><b><SearchPill /></b> · default</div>
|
||
</div>
|
||
<div class="variant">
|
||
<div class="searchpill" style="color:#1a1a1a;">快速开始</div>
|
||
<div class="vlabel"><b>variant</b> · 已输入</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 150px; left: 828px; width: 412px;">
|
||
<div class="panel">
|
||
<h3><TopBar /> Args</h3>
|
||
<table class="spec">
|
||
<tr><th>Prop</th><th>类型</th><th>默认</th><th>说明</th></tr>
|
||
<tr><td class="k"><code>logo</code></td><td>string</td><td>stack·idealjs</td><td>左侧白色粗体站点名</td></tr>
|
||
<tr><td class="k"><code>items</code></td><td>string[]</td><td>四项菜单</td><td>全栈教程/工具使用/实践经历/博客</td></tr>
|
||
<tr><td class="k"><code>active</code></td><td>string</td><td>全栈教程</td><td>当前路由项,白色加粗</td></tr>
|
||
<tr><td class="k"><code>avatar</code></td><td>string</td><td>初</td><td>渐变圆头像,取首字</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="panel" style="margin-top: 14px;">
|
||
<h3>规格说明</h3>
|
||
<div class="note"><span class="idx">1</span><span class="txt"><b>TopBar</b>:高 46px,底 #111111,菜单居中,当前项 #FFF 600;圆角 12px(页面内嵌时)。</span></div>
|
||
<div class="note"><span class="idx">2</span><span class="txt"><b>IconRail</b>:白底 40px 宽,图标 14px 灰 #8A8A8A,项间距 14px;首页/书架/积木/设置。</span></div>
|
||
<div class="note"><span class="idx">3</span><span class="txt"><b>SearchPill</b>:胶囊白底描边,placeholder 灰;输入后文字转主黑。实现映射 Docusaurus navbar search。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">02 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P3 Atoms:Pill · CircleButton · Chip · IconTile ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag">Atoms · Pill / CircleButton / Chip / IconTile</span>
|
||
<h2>原子组件</h2>
|
||
<div class="desc">构成卡片与面板的最小单元,四象限展示:每个原子给出全部变体与尺寸规格。</div>
|
||
</div>
|
||
|
||
<!-- 象限 1:Pill -->
|
||
<div class="canvas" style="top: 146px; left: 40px; width: 590px; height: 196px;">
|
||
<div style="font-size:15px; font-weight:700; color:#1a1a1a; margin-bottom:14px;"><Pill /> 状态胶囊</div>
|
||
<div class="vrow" style="gap: 22px;">
|
||
<div class="variant"><span class="pill done" style="font-size:13px; padding:5px 14px;">✓ Completed 🎉</span><div class="vlabel"><b>done</b> · 紫底 #EFE6FB</div></div>
|
||
<div class="variant"><span class="pill wip" style="font-size:13px; padding:5px 14px;">Upcoming</span><div class="vlabel"><b>wip</b> · 白底描边</div></div>
|
||
<div class="variant"><span class="pill time" style="font-size:13px; padding:5px 14px;">⏱ Watching</span><div class="vlabel"><b>time</b> · 白底描边·黑字</div></div>
|
||
</div>
|
||
<div style="margin-top:16px; font-size:12px; color:#8a8a8a;">高度统一 24px(页面尺寸)/ 28px(卡片尺寸)· 圆角 999px · 字重 600</div>
|
||
</div>
|
||
|
||
<!-- 象限 2:CircleButton -->
|
||
<div class="canvas" style="top: 146px; left: 650px; width: 590px; height: 196px;">
|
||
<div style="font-size:15px; font-weight:700; color:#1a1a1a; margin-bottom:14px;"><CircleButton /> 黑圆按钮</div>
|
||
<div class="vrow" style="gap: 26px;">
|
||
<div class="variant"><span class="cbtn" style="width:34px; height:34px; font-size:15px;">✓</span><div class="vlabel"><b>done</b> · 已完成章节</div></div>
|
||
<div class="variant"><span class="cbtn" style="width:34px; height:34px; font-size:15px;">→</span><div class="vlabel"><b>next</b> · 写作中章节</div></div>
|
||
<div class="variant"><span class="cbtn" style="width:34px; height:34px; font-size:15px;">▶</span><div class="vlabel"><b>play</b> · 媒体卡播放</div></div>
|
||
</div>
|
||
<div style="margin-top:16px; font-size:12px; color:#8a8a8a;">卡内 26px / 解剖展示 34px · 背景 #1A1A1A · 点击进入章节</div>
|
||
</div>
|
||
|
||
<!-- 象限 3:Chip -->
|
||
<div class="canvas" style="top: 360px; left: 40px; width: 590px; height: 168px;">
|
||
<div style="font-size:15px; font-weight:700; color:#1a1a1a; margin-bottom:14px;"><Chip /> 关系标签</div>
|
||
<div class="vrow" style="gap: 18px;">
|
||
<div class="variant"><span class="chip" style="font-size:12px; padding:3px 12px;">前置:无</span><div class="vlabel"><b>prerequisite</b></div></div>
|
||
<div class="variant"><span class="chip" style="font-size:12px; padding:3px 12px;">关联:快速开始 React</span><div class="vlabel"><b>relation</b></div></div>
|
||
<div class="variant"><span class="chip" style="font-size:12px; padding:3px 12px; color:#8a8a8a; border-style:dashed;">关联章节整理中</span><div class="vlabel"><b>empty</b> · 占位虚线</div></div>
|
||
</div>
|
||
<div style="margin-top:16px; font-size:12px; color:#8a8a8a;">数据源 courses.ts 的 relations 字段 · 未填时显示占位样式</div>
|
||
</div>
|
||
|
||
<!-- 象限 4:IconTile -->
|
||
<div class="canvas" style="top: 360px; left: 650px; width: 590px; height: 168px;">
|
||
<div style="font-size:15px; font-weight:700; color:#1a1a1a; margin-bottom:14px;"><IconTile /> 彩色图标块</div>
|
||
<div class="vrow" style="gap: 16px;">
|
||
<div class="variant"><span class="icotile" style="background:#e0e7ff;">🌐</span><div class="vlabel">快速开始</div></div>
|
||
<div class="variant"><span class="icotile" style="background:#fce7f3;">⚛️</span><div class="vlabel">React</div></div>
|
||
<div class="variant"><span class="icotile" style="background:#fef3c7;">🧱</span><div class="vlabel">更多示例</div></div>
|
||
<div class="variant"><span class="icotile" style="background:#d1fae5;">📦</span><div class="vlabel">更多</div></div>
|
||
<div class="variant"><span class="icotile" style="background:#e0f2fe;">🔗</span><div class="vlabel">全栈基础</div></div>
|
||
<div class="variant"><span class="icotile" style="background:#ede9fe;">🧠</span><div class="vlabel">高级教程</div></div>
|
||
</div>
|
||
<div style="margin-top:16px; font-size:12px; color:#8a8a8a;">26×26 · 圆角 9px · 淡彩底取自课程色映射表</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 544px; left: 40px; right: 40px; padding: 12px 16px;" class="panel" data-spec-panel>
|
||
<h3 style="margin-bottom:6px;">原子组件规格速查</h3>
|
||
<table class="spec">
|
||
<tr><th>原子</th><th>尺寸</th><th>颜色</th><th>圆角</th><th>用途</th></tr>
|
||
<tr><td class="k">Pill</td><td>高 24/28px</td><td>紫 #EFE6FB / 白底描边</td><td>999px</td><td>完成度与播放状态徽标</td></tr>
|
||
<tr><td class="k">CircleButton</td><td>26 / 34px</td><td>#1A1A1A + 白字</td><td>50%</td><td>进入章节 / 播放确认</td></tr>
|
||
<tr><td class="k">Chip</td><td>高 20px</td><td>描边 #CFCFCD 灰字</td><td>999px</td><td>章节前置与关联关系</td></tr>
|
||
<tr><td class="k">IconTile</td><td>26×26px</td><td>六课程淡彩底</td><td>9px</td><td>卡片左上角章节图标</td></tr>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">03 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P4 CourseCard ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><CourseCard /></span>
|
||
<h2>课程白卡 · default 态</h2>
|
||
<div class="desc">书架核心单元:16:9 预期区常驻 desc,定时自动翻转为播放对应 GIF;数据全部来自 courses.ts。</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 138px; left: 40px; width: 880px; padding: 16px;">
|
||
<div class="vrow" style="gap: 14px;">
|
||
<div class="variant">
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="icotile" style="background:#e0e7ff;">🌐</span><span class="ttl">快速开始</span></div>
|
||
<div class="zone">写出第一个网页并在浏览器打开,跑起你的第一个 HTTP 服务器。</div>
|
||
<div class="chips"><span class="chip">前置:无</span></div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<div class="vlabel"><b>hello-world</b></div>
|
||
</div><div class="variant">
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="icotile" style="background:#fce7f3;">⚛️</span><span class="ttl">快速开始 React</span></div>
|
||
<div class="zone">用脚手架创建 React 应用,亲手拼出第一个 Todo List。</div>
|
||
<div class="chips"><span class="chip">前置:快速开始</span><span class="chip" style="border-style:dashed;">关联:更多示例</span></div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<div class="vlabel"><b>hello-react</b></div>
|
||
</div><div class="variant">
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="icotile" style="background:#fef3c7;">🧱</span><span class="ttl">更多示例</span></div>
|
||
<div class="zone">浮动布局等补充示例,巩固前面攒下的积木。</div>
|
||
<div class="chips"><span class="chip">前置:快速开始</span></div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<div class="vlabel"><b>more-example</b></div>
|
||
</div>
|
||
</div>
|
||
<div class="vrow" style="gap: 14px; margin-top: 14px;">
|
||
<div class="variant">
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="icotile" style="background:#d1fae5;">📦</span><span class="ttl">更多</span></div>
|
||
<div class="zone">把示例工程构建为可发布产物,看清 build 做了什么。</div>
|
||
<div class="chips"><span class="chip">前置:快速开始 React</span></div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<div class="vlabel"><b>more</b></div>
|
||
</div><div class="variant">
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="icotile" style="background:#e0f2fe;">🔗</span><span class="ttl">全栈基础</span></div>
|
||
<div class="zone">从网页到服务与数据库,串起最小全栈闭环。</div>
|
||
<div class="chips"><span class="chip" style="color:#8a8a8a; border-style:dashed;">关联章节整理中</span></div>
|
||
<div class="btm"><span class="pill wip">Upcoming</span><span class="cbtn">→</span></div>
|
||
</div>
|
||
<div class="vlabel"><b>full-stack</b> · wip 变体</div>
|
||
</div><div class="variant">
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="icotile" style="background:#ede9fe;">🧠</span><span class="ttl">高级教程</span></div>
|
||
<div class="zone">数据流、纯函数、CAP——工程上的心智模型。</div>
|
||
<div class="chips"><span class="chip">前置:全栈基础</span></div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<div class="vlabel"><b>advance</b></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 140px; left: 948px; width: 292px;">
|
||
<div class="panel" style="padding:14px 18px;">
|
||
<h3>Args</h3>
|
||
<table class="spec tight">
|
||
<tr><th>Prop</th><th>类型</th><th>说明</th></tr>
|
||
<tr><td class="k"><code>title</code></td><td>string</td><td>章节名</td></tr>
|
||
<tr><td class="k"><code>desc</code></td><td>string</td><td>预期一句话(16:9 区)</td></tr>
|
||
<tr><td class="k"><code>done</code></td><td>boolean</td><td>✓ 胶囊 / Upcoming</td></tr>
|
||
<tr><td class="k"><code>prerequisites</code></td><td>string[]</td><td>前置 → 实线 chip + 图边</td></tr>
|
||
<tr><td class="k"><code>related</code></td><td>string[]</td><td>关联 → 虚线 chip + 图边</td></tr>
|
||
<tr><td class="k"><code>icon / tint</code></td><td>emoji / hex</td><td>图标与淡彩底</td></tr>
|
||
<tr><td class="k"><code>href</code></td><td>string</td><td>章节路由</td></tr>
|
||
<tr><td class="k"><code>flipInterval</code></td><td>ms</td><td>翻转周期,默认 8000</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="panel" style="margin-top: 12px; padding:14px 18px;">
|
||
<h3>交互</h3>
|
||
<div class="note" style="margin-bottom:4px;"><span class="idx">1</span><span class="txt">整卡可点进入章节;预期区定时翻转(见下页)。</span></div>
|
||
<div class="note" style="margin-bottom:4px;"><span class="idx">2</span><span class="txt">hover / Tab:即时翻到 GIF 并锁定,移出恢复定时。</span></div>
|
||
<div class="note" style="margin-bottom:0;"><span class="idx">3</span><span class="txt">触屏 / 减动效:不自动翻转;首页可用紧凑变体。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">04 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P5 CourseCardMedia ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><CourseCardMedia /></span>
|
||
<h2>播放态 · 定时翻转 / 悬停锁定</h2>
|
||
<div class="desc">预期区(16:9)翻转化淡彩播放态:黑色圆形播放钮 + ⏱ 胶囊,GIF 此刻才挂载并循环。</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 146px; left: 40px; width: 560px; height: 434px;">
|
||
<div class="variant">
|
||
<div class="ccard media" style="--tint:#e0e7ff; width: 512px;">
|
||
<div class="player" style="aspect-ratio: 16 / 9; min-height: 0;">
|
||
<div class="playbtn" style="width:56px; height:56px; font-size:20px;">▶</div>
|
||
<span class="pill time" style="position:absolute; right:12px; top:10px; font-size:12px;">⏱ GIF loop</span>
|
||
<span class="pill time" style="position:absolute; left:12px; bottom:10px; font-size:12px;">预期成果 · 浏览器打开第一个网页</span>
|
||
</div>
|
||
<div>
|
||
<div class="ttl" style="font-size:16px;">快速开始</div>
|
||
<div class="dsc" style="font-size:12px; color:#555;">GIF 来源 static/gifs/hello-world.gif · loop=0 · 悬停期间持续播放</div>
|
||
</div>
|
||
</div>
|
||
<div class="vlabel"><b>playing</b> · 512 × 288(16:9)· tint 随章节主题色</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 600px; left: 40px; width: 560px; height: 140px;">
|
||
<div style="font-size:14px; font-weight:700; color:#1a1a1a; margin-bottom:12px;">六章节 tint 变体(播放器区域)</div>
|
||
<div class="vrow" style="gap: 10px;">
|
||
<div class="variant"><div style="width:70px; height:48px; border-radius:10px; background:#e0e7ff; display:flex; align-items:center; justify-content:center; font-size:12px;">▶</div><div class="vlabel">#E0E7FF</div></div>
|
||
<div class="variant"><div style="width:70px; height:48px; border-radius:10px; background:#fce7f3; display:flex; align-items:center; justify-content:center; font-size:12px;">▶</div><div class="vlabel">#FCE7F3</div></div>
|
||
<div class="variant"><div style="width:70px; height:48px; border-radius:10px; background:#fef3c7; display:flex; align-items:center; justify-content:center; font-size:12px;">▶</div><div class="vlabel">#FEF3C7</div></div>
|
||
<div class="variant"><div style="width:70px; height:48px; border-radius:10px; background:#d1fae5; display:flex; align-items:center; justify-content:center; font-size:12px;">▶</div><div class="vlabel">#D1FAE5</div></div>
|
||
<div class="variant"><div style="width:70px; height:48px; border-radius:10px; background:#e0f2fe; display:flex; align-items:center; justify-content:center; font-size:12px;">▶</div><div class="vlabel">#E0F2FE</div></div>
|
||
<div class="variant"><div style="width:70px; height:48px; border-radius:10px; background:#ede9fe; display:flex; align-items:center; justify-content:center; font-size:12px;">▶</div><div class="vlabel">#EDE9FE</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 148px; left: 628px; width: 612px;">
|
||
<div class="panel">
|
||
<h3>播放器规格</h3>
|
||
<table class="spec">
|
||
<tr><th>项</th><th>规格</th></tr>
|
||
<tr><td class="k">翻转周期</td><td>desc 8s ⇄ GIF 8s(flipInterval 可配);GIF 内部循环</td></tr>
|
||
<tr><td class="k">播放钮</td><td>黑 #111 圆形 · 卡内 44px / 展示 56px · 阴影 0 4px 14px</td></tr>
|
||
<tr><td class="k">⏱ 胶囊</td><td>右上 GIF loop · 左下成果字幕,白底描边胶囊</td></tr>
|
||
<tr><td class="k">GIF</td><td>640×360 · loop=0 · ≤300KB · hover 时才挂载</td></tr>
|
||
<tr><td class="k">触屏</td><td>不进入此态,点击直达章节</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="panel" style="margin-top: 12px;">
|
||
<h3>状态转换</h3>
|
||
<div class="note"><span class="idx">1</span><span class="txt"><b>desc → playing</b>:定时 8s 到期,或 hover / Tab 聚焦即时触发;GIF 挂载循环。</span></div>
|
||
<div class="note"><span class="idx">2</span><span class="txt"><b>锁定</b>:悬停/聚焦期间停在 playing,不翻回;移出后按定时器继续轮换。</span></div>
|
||
<div class="note"><span class="idx">3</span><span class="txt"><b>playing → desc</b>:定时到期或移出,GIF 卸载、缓存保留,再翻回瞬时恢复。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">05 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P6 StatsRow · EventsPanel ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><StatsRow /> · <EventsPanel /></span>
|
||
<h2>数据组件 · 统计行与事件栏</h2>
|
||
<div class="desc">统计行汇报教程规模,事件栏承载章节动态;两者数据均为静态 JSON,可后续接构建脚本生成。</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 148px; left: 40px; width: 700px; height: 168px;">
|
||
<div style="font-size:14px; font-weight:700; color:#1a1a1a; margin-bottom:12px;"><StatsRow /> 三变体</div>
|
||
<div class="vrow" style="gap: 14px;">
|
||
<div class="variant"><div class="stat" style="background:#c9e7f7;"><span class="num">6</span><span class="lab">Total Sections</span></div><div class="vlabel"><b>total</b> · 蓝</div></div>
|
||
<div class="variant"><div class="stat" style="background:#d2f5df;"><span class="num">5</span><span class="lab">Completed 🎉</span></div><div class="vlabel"><b>done</b> · 绿</div></div>
|
||
<div class="variant"><div class="stat" style="background:#efe6fb;"><span class="num">1</span><span class="lab">Upcoming</span></div><div class="vlabel"><b>wip</b> · 紫</div></div>
|
||
</div>
|
||
<div style="margin-top:12px; font-size:12px; color:#8a8a8a;">数值由 courses.ts 推导:total=length · done=count(done) · wip=total-done</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 340px; left: 40px; width: 700px; height: 312px;">
|
||
<div style="font-size:14px; font-weight:700; color:#1a1a1a; margin-bottom:12px;"><EventsPanel /> 最近更新 · 四色变体</div>
|
||
<div class="vrow" style="gap: 14px;">
|
||
<div class="variant">
|
||
<div class="ev" style="background:#c9e7f7;">
|
||
<div class="r1"><span>新增 · Web</span><span class="date">OCT 02</span></div>
|
||
<div class="r2">「更多示例」补充浮动布局一文</div>
|
||
<div class="r3">09:00</div>
|
||
</div>
|
||
<div class="vlabel"><b>新增</b> · 蓝</div>
|
||
</div>
|
||
<div class="variant">
|
||
<div class="ev" style="background:#e9c8f5;">
|
||
<div class="r1"><span>章节 · 高级</span><span class="date">SEP 28</span></div>
|
||
<div class="r2">CAP 一讲更新配图与示例</div>
|
||
<div class="r3">14:30</div>
|
||
</div>
|
||
<div class="vlabel"><b>更新</b> · 紫</div>
|
||
</div>
|
||
<div class="variant">
|
||
<div class="ev" style="background:#f5e6c4;">
|
||
<div class="r1"><span>计划 · 全栈</span><span class="date">SOON</span></div>
|
||
<div class="r2">「全栈基础」章节开写</div>
|
||
<div class="r3">即将开始</div>
|
||
</div>
|
||
<div class="vlabel"><b>计划</b> · 黄</div>
|
||
</div>
|
||
<div class="variant">
|
||
<div class="ev" style="background:#d2f5df;">
|
||
<div class="r1"><span>讨论</span><span class="date">OCT 01</span></div>
|
||
<div class="r2">讨论区新增 3 帖</div>
|
||
<div class="r3">20:00</div>
|
||
</div>
|
||
<div class="vlabel"><b>讨论</b> · 绿</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 148px; left: 772px; width: 468px;">
|
||
<div class="panel">
|
||
<h3><EventsPanel /> Args</h3>
|
||
<table class="spec">
|
||
<tr><th>Prop</th><th>类型</th><th>说明</th></tr>
|
||
<tr><td class="k"><code>items[]</code></td><td>Event[]</td><td>事件数组,倒序展示</td></tr>
|
||
<tr><td class="k"><code>type</code></td><td>新增/更新/计划/讨论</td><td>决定淡彩底色</td></tr>
|
||
<tr><td class="k"><code>date</code></td><td>string</td><td>右上角日期(SOON 等特殊值可)</td></tr>
|
||
<tr><td class="k"><code>desc / time</code></td><td>string</td><td>动态描述与时间行</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="panel" style="margin-top: 12px;">
|
||
<h3>数据与实现</h3>
|
||
<div class="note"><span class="idx">1</span><span class="txt"><b>StatsRow</b>:纯派生数据,无独立配置;卡宽 flex 均分,圆角 16px。</span></div>
|
||
<div class="note"><span class="idx">2</span><span class="txt"><b>EventsPanel</b>:数据源 events.ts(新文件);类型→底色映射:新增蓝/更新紫/计划黄/讨论绿。</span></div>
|
||
<div class="note"><span class="idx">3</span><span class="txt">事件可由 git log 或 RSS 后续自动生成,先手工维护。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">06 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P7 CourseGraph 课程路线图(线条构件版) ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><CourseGraph /></span>
|
||
<h2>课程路线图 · 线条是构件</h2>
|
||
<div class="desc">路线的最小构件是线条:直段 / 圆角转角 / 曲线 / 分流岔口 / 汇合 / 站点。主线在岔口分流出两条车道,曲线并线后继续前进——网状关系在路线内可读。</div>
|
||
</div>
|
||
|
||
<!-- 组合:路线总图(曲线 + 分流 + 并线) -->
|
||
<div class="canvas" style="top: 138px; left: 40px; width: 880px; height: 306px; padding: 0;">
|
||
<svg class="gedges" width="880" height="306" viewBox="0 0 880 306">
|
||
<path class="edge" d="M 12 132 H 22"/>
|
||
<path class="edge" d="M 182 132 C 207 132, 207 52, 232 52"/>
|
||
<path class="edge" d="M 182 132 C 207 132, 207 212, 232 212"/>
|
||
<path class="edge" d="M 392 52 C 417 52, 407 120, 432 120"/>
|
||
<path class="edge" d="M 392 212 C 417 212, 407 144, 432 144"/>
|
||
<path class="edge" d="M 592 132 H 632"/>
|
||
<path class="edge" d="M 712 154 V 232"/>
|
||
<circle class="station" cx="12" cy="132" r="2.8"/>
|
||
<circle class="station" cx="207" cy="132" r="2.8"/>
|
||
<circle class="station" cx="224" cy="52" r="2.8"/>
|
||
<circle class="station" cx="224" cy="212" r="2.8"/>
|
||
<circle class="station" cx="420" cy="132" r="2.8"/>
|
||
<circle class="station" cx="624" cy="132" r="2.8"/>
|
||
<circle class="station" cx="712" cy="224" r="2.8"/>
|
||
</svg>
|
||
<div class="rnode" style="left:22px; top:110px;"><span class="entry-badge" style="width:20px;height:20px;font-size:11px;">①</span><span class="icotile" style="background:#e0e7ff;">🌐</span><span class="t">快速开始</span><span class="st done">✓</span></div>
|
||
<div class="rnode" style="left:232px; top:30px;"><span class="entry-badge" style="width:20px;height:20px;font-size:11px;">②</span><span class="icotile" style="background:#fce7f3;">⚛️</span><span class="t">React</span><span class="st done">✓</span></div>
|
||
<div class="rnode" style="left:232px; top:190px;"><span class="icotile" style="background:#fef3c7;">🧱</span><span class="t">更多示例</span><span class="st done">✓</span></div>
|
||
<div class="rnode" style="left:432px; top:110px;"><span class="icotile" style="background:#d1fae5;">📦</span><span class="t">更多</span><span class="st done">✓</span></div>
|
||
<div class="rnode" style="left:632px; top:110px;"><span class="icotile" style="background:#e0f2fe;">🔗</span><span class="t">全栈基础</span><span class="st lock">🔒</span></div>
|
||
<div class="rnode" style="left:632px; top:232px;"><span class="entry-badge" style="width:20px;height:20px;font-size:11px;">③</span><span class="icotile" style="background:#ede9fe;">🧠</span><span class="t">高级教程</span><span class="st done">✓</span></div>
|
||
<div style="position:absolute; right:12px; top:10px; font-size:11px; color:#6b6b6b;">分流岔口 ×1 · 曲线并线 ×2 · 站点 ×7</div>
|
||
</div>
|
||
|
||
<!-- 构件:线条组件六原语 -->
|
||
<div class="canvas" style="top: 462px; left: 40px; width: 880px; height: 272px;">
|
||
<div style="font-size:14px; font-weight:700; color:#1a1a1a; margin-bottom:10px;"><RouteLine /> 线条组件 · 六原语</div>
|
||
<div style="display:grid; grid-template-columns:repeat(3, 1fr); gap:12px;">
|
||
<div class="linecard">
|
||
<svg width="240" height="56" viewBox="0 0 240 56"><path class="edge" d="M 20 28 H 220"/><circle class="station" cx="20" cy="28" r="2.8"/><circle class="station" cx="220" cy="28" r="2.8"/></svg>
|
||
<div class="vlabel"><b>segment</b> · 直段</div>
|
||
</div>
|
||
<div class="linecard">
|
||
<svg width="240" height="56" viewBox="0 0 240 56"><path class="edge" d="M 20 44 H 105 Q 125 44 125 24 V 10"/><circle class="station" cx="20" cy="44" r="2.8"/></svg>
|
||
<div class="vlabel"><b>elbow</b> · 圆角转角</div>
|
||
</div>
|
||
<div class="linecard">
|
||
<svg width="240" height="56" viewBox="0 0 240 56"><path class="edge" d="M 15 42 C 60 4, 180 58, 225 16"/><circle class="station" cx="15" cy="42" r="2.8"/><circle class="station" cx="225" cy="16" r="2.8"/></svg>
|
||
<div class="vlabel"><b>curve</b> · 曲线</div>
|
||
</div>
|
||
<div class="linecard">
|
||
<svg width="240" height="56" viewBox="0 0 240 56"><path class="edge" d="M 20 28 H 80 C 100 28, 100 10, 118 10 H 200"/><path class="edge" d="M 80 28 C 100 28, 100 46, 118 46 H 200"/><circle class="station" cx="80" cy="28" r="2.8"/></svg>
|
||
<div class="vlabel"><b>fork</b> · 分流岔口</div>
|
||
</div>
|
||
<div class="linecard">
|
||
<svg width="240" height="56" viewBox="0 0 240 56"><path class="edge" d="M 20 10 H 95 C 113 10, 113 28, 130 28 H 220"/><path class="edge" d="M 20 46 H 95 C 113 46, 113 28, 130 28"/><circle class="station" cx="130" cy="28" r="2.8"/></svg>
|
||
<div class="vlabel"><b>merge</b> · 汇合并线</div>
|
||
</div>
|
||
<div class="linecard">
|
||
<svg width="240" height="56" viewBox="0 0 240 56"><path class="edge" d="M 20 28 H 220"/><circle class="station" cx="90" cy="28" r="2.8"/><circle class="station" cx="170" cy="28" r="2.8"/></svg>
|
||
<div class="vlabel"><b>station</b> · 站点(悬浮于卡间槽内)</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 138px; left: 948px; width: 292px;" class="panel">
|
||
<h3 style="margin-bottom:8px;">Args</h3>
|
||
<table class="spec tight">
|
||
<tr><th>Prop</th><th>类型</th><th>说明</th></tr>
|
||
<tr><td class="k"><code>path</code></td><td>Segment[]</td><td>直段/转角/曲线序列</td></tr>
|
||
<tr><td class="k"><code>forks</code></td><td>Fork[]</td><td>分流岔口(分出车道)</td></tr>
|
||
<tr><td class="k"><code>merges</code></td><td>Merge[]</td><td>曲线并线点</td></tr>
|
||
<tr><td class="k"><code>stations</code></td><td>Node[]</td><td>站点圆点,锚定卡间槽</td></tr>
|
||
<tr><td class="k"><code>status</code></td><td>无 prop</td><td>不在图上编码</td></tr>
|
||
</table>
|
||
</div>
|
||
<div style="position:absolute; top: 420px; left: 948px; width: 292px;" class="panel">
|
||
<h3 style="margin-bottom:6px;">设计原则</h3>
|
||
<div class="note" style="margin-bottom:4px;"><span class="idx">1</span><span class="txt"><b>线只管顺序</b>:状态交给卡片(✓ / 🔒)。</span></div>
|
||
<div class="note" style="margin-bottom:4px;"><span class="idx">2</span><span class="txt"><b>背景级线条</b>:灰绿 <code>#A3B5AF</code> · 1.2px · 划隙 6:3;站点 <code>#78928A</code> 深一档,直径 ≈ 4× 线宽。</span></div>
|
||
<div class="note" style="margin-bottom:4px;"><span class="idx">3</span><span class="txt"><b>岔口即分支</b>:快速开始分流出 React 线与示例线,在「更多」并线。</span></div>
|
||
<div class="note" style="margin-bottom:4px;"><span class="idx">4</span><span class="txt"><b>线条是构件</b>:六原语可拼任意路线。</span></div>
|
||
<div class="note" style="margin-bottom:0;"><span class="idx">5</span><span class="txt">顺序为<b>示例占位</b>,填 courses.ts 自动更新。</span></div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">07 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P8 EntryGuide 入口梳理 ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><EntryGuide /></span>
|
||
<h2>入口梳理 · 按读者画像推荐起点</h2>
|
||
<div class="desc">三类读者三种入口:路径是推荐不是强制;起点章节高亮,沿途章节排成路径 chips。</div>
|
||
</div>
|
||
|
||
<div class="canvas" style="top: 146px; left: 40px; width: 1200px; height: 300px;">
|
||
<div class="vrow" style="gap: 20px;">
|
||
<div class="profile-card">
|
||
<div class="ph"><span class="icotile" style="background:#e0e7ff;">🌱</span><span style="font-size:16px; font-weight:800; color:#1a1a1a;">零基础入门</span></div>
|
||
<div><span class="pill done" style="font-size:12px;">入口 ① 快速开始</span></div>
|
||
<div class="path-chips">
|
||
<span class="pchip start">快速开始</span><span class="arr">→</span>
|
||
<span class="pchip">React</span><span class="arr">→</span>
|
||
<span class="pchip">更多示例</span><span class="arr">→</span>
|
||
<span class="pchip">更多</span><span class="arr">→</span>
|
||
<span class="pchip">全栈基础</span><span class="arr">→</span>
|
||
<span class="pchip">高级教程</span>
|
||
</div>
|
||
<div style="font-size:12.5px; color:#555; line-height:1.65;">完整链按序走;每步先核对验收产物再前进,认知基础必须在真机跑通。</div>
|
||
</div>
|
||
<div class="profile-card">
|
||
<div class="ph"><span class="icotile" style="background:#fce7f3;">⚛️</span><span style="font-size:16px; font-weight:800; color:#1a1a1a;">写过页面 · 有前端经验</span></div>
|
||
<div><span class="pill done" style="font-size:12px;">入口 ② 快速开始 React</span></div>
|
||
<div class="path-chips">
|
||
<span class="pchip start">React</span><span class="arr">→</span>
|
||
<span class="pchip">更多</span><span class="arr">→</span>
|
||
<span class="pchip">全栈基础</span><span class="arr">→</span>
|
||
<span class="pchip">高级教程</span>
|
||
</div>
|
||
<div style="font-size:12.5px; color:#555; line-height:1.65;">「快速开始」降级为查漏清单:实践过的部分直接跳过,撞到陌生积木再回看。</div>
|
||
</div>
|
||
<div class="profile-card">
|
||
<div class="ph"><span class="icotile" style="background:#ede9fe;">🧠</span><span style="font-size:16px; font-weight:800; color:#1a1a1a;">在职补工程思维</span></div>
|
||
<div><span class="pill done" style="font-size:12px;">入口 ③ 高级教程</span></div>
|
||
<div class="path-chips">
|
||
<span class="pchip start">高级教程</span>
|
||
<span class="pchip">专题按需点读</span>
|
||
</div>
|
||
<div style="font-size:12.5px; color:#555; line-height:1.65;">数据流 / 纯函数 / CAP 按需取用;缺上下文时回看「全栈基础」,真机验收不可代劳。</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 480px; left: 40px; width: 590px;" class="panel">
|
||
<h3>Args</h3>
|
||
<table class="spec tight">
|
||
<tr><th>Prop</th><th>类型</th><th>说明</th></tr>
|
||
<tr><td class="k"><code>profiles[].name</code></td><td>string</td><td>读者画像名</td></tr>
|
||
<tr><td class="k"><code>profiles[].entry</code></td><td>courseId</td><td>起点章节,对应图中 ①②③</td></tr>
|
||
<tr><td class="k"><code>profiles[].path</code></td><td>courseId[]</td><td>推荐路径(可空 = 按需点读)</td></tr>
|
||
<tr><td class="k"><code>profiles[].note</code></td><td>string</td><td>跳读/回看策略一句话</td></tr>
|
||
</table>
|
||
</div>
|
||
<div style="position:absolute; top: 480px; left: 662px; width: 578px;" class="panel">
|
||
<h3>入口梳理原则</h3>
|
||
<div class="note"><span class="idx">1</span><span class="txt"><b>路径非强制</b>:推荐序列只做导航,不设锁——任何章节始终可进(skill 死原则)。</span></div>
|
||
<div class="note"><span class="idx">2</span><span class="txt"><b>与 CourseGraph 共用数据</b>:entries 与图上的入口徽标同源,改一处两处同步。</span></div>
|
||
<div class="note"><span class="idx">3</span><span class="txt">画像数据入 <b>entries.ts</b>;后续可由读者自选画像并高亮其路径。</span></div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">08 / 09</div>
|
||
</div>
|
||
|
||
<!-- ================= P7 Dashboard 组装 ================= -->
|
||
<div class="page">
|
||
<div class="story-head">
|
||
<span class="tag"><DashboardPage /></span>
|
||
<h2>组装 · 组件如何拼成页面</h2>
|
||
<div class="desc">页面 = TopBar + IconRail + 标题行(SearchPill) + StatsRow + CourseGrid(CourseCard × 6) + EventsPanel。</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 146px; left: 40px; width: 800px; height: 506px; background:#f0f0ef; border-radius:12px; box-shadow:0 8px 26px rgba(26,26,26,0.14);">
|
||
<div class="topbar" style="border-radius:12px 12px 0 0;">
|
||
<span class="logo">stack·idealjs</span>
|
||
<span class="menu"><span class="active">全栈教程 🎓</span><span>工具使用</span><span>博客</span></span>
|
||
<span class="bell">🔔</span><span class="ava">初</span>
|
||
</div>
|
||
<div style="display:flex; height:460px;">
|
||
<div class="rail" style="height:100%; border-radius:0 0 0 12px;"><span>🏠</span><span>📚</span><span>🧩</span><span>⚙️</span></div>
|
||
<div style="flex:1; padding:12px 12px 10px; display:flex; flex-direction:column; gap:10px;">
|
||
<div style="display:flex; align-items:center; justify-content:space-between;">
|
||
<div style="font-size:17px; font-weight:800; color:#1a1a1a;">全栈工程师教程 📚</div>
|
||
<div class="searchpill">Search…</div>
|
||
</div>
|
||
<div style="display:flex; gap:10px;">
|
||
<div class="stat" style="flex:1; background:#c9e7f7;"><span class="num" style="font-size:22px;">6</span><span class="lab">Total</span></div>
|
||
<div class="stat" style="flex:1; background:#d2f5df;"><span class="num" style="font-size:22px;">5</span><span class="lab">Completed 🎉</span></div>
|
||
<div class="stat" style="flex:1; background:#efe6fb;"><span class="num" style="font-size:22px;">1</span><span class="lab">Upcoming</span></div>
|
||
</div>
|
||
<div style="flex:1; display:grid; grid-template-columns:1fr 1fr; gap:10px;">
|
||
<div class="ccard media" style="--tint:#e0e7ff; width:auto;">
|
||
<div class="player" style="min-height:44px;"><div class="playbtn" style="width:38px; height:38px; font-size:14px;">▶</div></div>
|
||
<div class="ttl" style="font-size:12.5px;">快速开始</div>
|
||
</div>
|
||
<div class="ccard" style="width:auto;">
|
||
<div class="icorow"><span class="icotile" style="background:#fce7f3;">⚛️</span></div>
|
||
<div class="ttl" style="font-size:12.5px;">快速开始 React</div>
|
||
<div class="btm"><span class="pill done">✓ Completed</span><span class="cbtn" style="width:22px;height:22px;font-size:10px;">✓</span></div>
|
||
</div>
|
||
<div class="ccard" style="width:auto;">
|
||
<div class="icorow"><span class="icotile" style="background:#fef3c7;">🧱</span></div>
|
||
<div class="ttl" style="font-size:12.5px;">更多示例</div>
|
||
<div class="btm"><span class="pill done">✓ Completed</span><span class="cbtn" style="width:22px;height:22px;font-size:10px;">✓</span></div>
|
||
</div>
|
||
<div class="ccard" style="width:auto;">
|
||
<div class="icorow"><span class="icotile" style="background:#e0f2fe;">🔗</span></div>
|
||
<div class="ttl" style="font-size:12.5px;">全栈基础</div>
|
||
<div class="btm"><span class="pill wip">Upcoming</span><span class="cbtn" style="width:22px;height:22px;font-size:10px;">→</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="width: 190px; padding: 12px 12px 10px 4px; display:flex; flex-direction:column; gap:8px;">
|
||
<div style="font-size:13px; font-weight:700; color:#1a1a1a;">最近更新 😊</div>
|
||
<div class="ev" style="background:#c9e7f7; width:auto;">
|
||
<div class="r1"><span>新增 · Web</span><span class="date">OCT 02</span></div>
|
||
<div class="r2">「更多示例」补充一文</div>
|
||
</div>
|
||
<div class="ev" style="background:#e9c8f5; width:auto;">
|
||
<div class="r1"><span>章节 · 高级</span><span class="date">SEP 28</span></div>
|
||
<div class="r2">CAP 更新配图</div>
|
||
</div>
|
||
<div class="ev" style="background:#d2f5df; width:auto;">
|
||
<div class="r1"><span>讨论</span><span class="date">OCT 01</span></div>
|
||
<div class="r2">新增 3 帖</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 146px; left: 872px; width: 368px;">
|
||
<div class="panel">
|
||
<h3>组件树(实现映射)</h3>
|
||
<table class="spec tight">
|
||
<tr><th>设计组件</th><th>实现文件</th></tr>
|
||
<tr><td class="k">DashboardPage</td><td><code>pages/index.tsx</code></td></tr>
|
||
<tr><td class="k">TopBar</td><td>navbar 主题化 <code>docusaurus.config</code></td></tr>
|
||
<tr><td class="k">IconRail</td><td><code>CourseShelf/IconRail</code></td></tr>
|
||
<tr><td class="k">StatsRow</td><td><code>CourseShelf/StatsRow</code></td></tr>
|
||
<tr><td class="k">CourseCard(/Media)</td><td><code>CourseShelf/CourseCard</code></td></tr>
|
||
<tr><td class="k">EventsPanel</td><td><code>CourseShelf/EventsPanel</code></td></tr>
|
||
<tr><td class="k">CourseGraph / EntryGuide</td><td><code>CourseShelf/CourseGraph</code> 等</td></tr>
|
||
<tr><td class="k">数据</td><td><code>courses.ts / events.ts / entries.ts</code></td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="panel" style="margin-top: 12px;">
|
||
<h3>组装要点</h3>
|
||
<div class="note"><span class="idx">1</span><span class="txt">网格 <b>auto-fill minmax(280px, 1fr)</b>;本页示意 2 列,≥1140px 实为 3 列。</span></div>
|
||
<div class="note"><span class="idx">2</span><span class="txt">各组件可独立验收:本册 02–08 页即逐组件的验收清单。</span></div>
|
||
<div class="note"><span class="idx">3</span><span class="txt">关系图与入口梳理挂书架上方(默认折叠)或独立路由 /curriculum;整页效果见 course-shelf.pdf。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">组件设计稿 · Storybook 拆分 · stack idealjs</div>
|
||
<div class="pagenum">09 / 09</div>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|