From 3a59edc79a983a472ca6a063c1b95533c8a56f10 Mon Sep 17 00:00:00 2001 From: wait4xx Date: Sun, 25 Oct 2026 22:47:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(nav):=20=E4=B9=A6=E6=9E=B6=E8=BF=9B?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=EF=BC=88=E8=BD=A6=E9=81=93=20G=EF=BC=89?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=9B=BE=E6=A0=87=E9=92=AE=E5=87=BA=E8=88=B1?= =?UTF-8?q?=E9=92=89=E6=AD=BB=E5=8F=B3=E4=BE=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 评估实数:第 6 项增量 zh +34-44/en +49-51px,旧结构 en 达 102-125px 滚区且主题钮出首屏——收纳策略=搜索/语言/主题三钮 移出 nav 滚动区钉死 .nav-actions 常驻右侧,内滚只波及文本项, 任何宽度三功能钮可见(搜索是移动端主发现路径不可藏) - nav 序:开源 · 文章 · 书架 · 图库 · 瞬间 · 关于(书架=阅读轨 延伸紧跟文章);ui.ts +nav_books/kbd_gs_books - Keyboard g-chord 增 s 键(g s→书架,双轨前缀路由),帮助表 按既有 kbd_* 词条模式接入 - E2E en 导航断言扩为 ≥6 且含 /en/books/ - 已知余量:en 390-430 文本区滚 ~114px(词条已最短化,再省需砍 语义留观);zh 全宽段 1-16px 基本无感 车道:op-gitea(八格扫描+E2E 33/33);收编验收:序/双轨 href/ 三宽度三功能钮可见性/g s 实跳全过 验证: pnpm astro build exit 0;本地 dist 六项 playwright 全过; E2E 33/33(推送后 staging 复验) Spec: none (导航扩容+出舱策略,车道级交付) Co-authored-by: GLM-5.3 --- src/components/Header.astro | 65 ++++++++++++++++++------------ src/components/geek/Keyboard.astro | 2 + src/i18n/ui.ts | 2 + tests/e2e.mjs | 2 +- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/components/Header.astro b/src/components/Header.astro index 5d028d9..cbd5d0a 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -10,10 +10,11 @@ const prefix = curLocale === 'en' ? '/en' : ''; const isCurrent = (href: string) => path === href || path === href.replace(/\/$/, '') || path.startsWith(href); -// 顺序:开源 · 文章 · 图库 · 瞬间 · 关于(瞬间新进,开源前置) +// 顺序:开源 · 文章 · 书架 · 图库 · 瞬间 · 关于(书架=阅读轨延伸紧跟文章;瞬间新进,开源前置) const nav = [ { href: `${prefix}/opensource/`, label: t('nav_opensource', curLocale) }, { href: `${prefix}/archives/`, label: t('nav_posts', curLocale) }, + { href: `${prefix}/books/`, label: t('nav_books', curLocale) }, { href: `${prefix}/gallery/`, label: t('nav_gallery', curLocale) }, { href: `${prefix}/moments/`, label: t('nav_moments', curLocale) }, { href: `${prefix}/about/`, label: t('nav_about', curLocale) }, @@ -26,8 +27,9 @@ const switchLabel = curLocale === 'zh' ? 'EN' : '中'; @@ -110,6 +108,21 @@ const switchLabel = curLocale === 'zh' ? 'EN' : '中'; padding: 0; margin: 0; } + /* nav-side:导航+功能钮右聚;nav 可收缩(min-width:0)——内滚只发生在文本区 */ + .nav-side { + display: flex; + align-items: center; + gap: clamp(2px, 0.8vw, 8px); + min-width: 0; + margin-left: auto; + } + nav { min-width: 0; } + .nav-actions { + display: flex; + align-items: center; + gap: clamp(2px, 0.8vw, 8px); + flex: none; + } .nav-link { font-size: 15px; color: var(--ink-3); diff --git a/src/components/geek/Keyboard.astro b/src/components/geek/Keyboard.astro index bada4da..9b92194 100644 --- a/src/components/geek/Keyboard.astro +++ b/src/components/geek/Keyboard.astro @@ -10,6 +10,7 @@ const pre = locale === 'en' ? '/en' : ''; const routes: Record = { h: `${pre}/`, a: `${pre}/archives/`, + s: `${pre}/books/`, g: `${pre}/gallery/`, m: `${pre}/moments/`, b: `${pre}/about/`, @@ -25,6 +26,7 @@ const routes: Record = { ?{t('kbd_this_help', locale)} g h{t('kbd_gh_home', locale)} g a{t('kbd_ga_posts', locale)} + g s{t('kbd_gs_books', locale)} g g{t('kbd_gg_gallery', locale)} g m{t('kbd_gm_moments', locale)} /terminal{t('kbd_terminal', locale)} diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index cdb1d0b..909adb2 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -11,6 +11,8 @@ const dict = { nav_gallery: { zh: '图库', en: 'Gallery' }, nav_about: { zh: '关于', en: 'About' }, nav_opensource: { zh: '开源', en: 'Projects' }, // en 用短词:390-430px 尾部主题钮免内滚(用户拍板) + nav_books: { zh: '书架', en: 'Books' }, + kbd_gs_books: { zh: '书架', en: 'Books' }, search_label: { zh: '搜索', en: 'Search' }, search_placeholder: { zh: '搜索文章…(Esc 关闭)', en: 'Search posts… (Esc to close)' }, search_hint: { zh: '索引由 Pagefind 构建期生成 · 静态站零后端', en: 'Index built by Pagefind · zero-backend static site' }, diff --git a/tests/e2e.mjs b/tests/e2e.mjs index 05342ec..52101b3 100644 --- a/tests/e2e.mjs +++ b/tests/e2e.mjs @@ -83,7 +83,7 @@ ok('en 图库可达', page.url().includes('/en/gallery')); // E 车道回归:en 页导航必须整轨 /en/(用户实测"切语言后点导航回中文"的防线) const enNavHrefs = await page.$$eval('nav a[href^="/"]:not(.nav-lang)', (as) => as.map((a) => a.getAttribute('href'))); const enNavBad = await page.$$eval('nav a[href^="/"]:not(.nav-lang)', (as) => as.filter((a) => !(a.getAttribute('href') ?? '').startsWith('/en/')).map((a) => a.outerHTML.slice(0, 140))); -ok('en 导航全轨 /en/ 前缀', enNavBad.length === 0 && enNavHrefs.length >= 5, enNavBad.join(' ; ') || enNavHrefs.join(' ')); +ok('en 导航全轨 /en/ 前缀', enNavBad.length === 0 && enNavHrefs.length >= 6 && enNavHrefs.includes('/en/books/'), enNavBad.join(' ; ') || enNavHrefs.join(' ')); const enBrand = await page.getAttribute('a.brand', 'href'); ok('en 品牌链接指 /en/', enBrand === '/en/', String(enBrand));