From 0a48d5e830781a1aa6f2c3e946e06d78c8fb7e48 Mon Sep 17 00:00:00 2001 From: Charliechen114514 <725610365@qq.com> Date: Tue, 1 Sep 2026 01:11:07 +0800 Subject: [PATCH] fix: sidebar session --- site/.vitepress/config/shared.ts | 9 +- .../theme/components/ResizableSidebar.vue | 162 ++++++------- .../theme/components/SidebarRail.vue | 91 ++++++++ site/.vitepress/theme/custom.css | 213 +++++++++++++++++- site/.vitepress/theme/index.ts | 4 +- 5 files changed, 373 insertions(+), 106 deletions(-) create mode 100644 site/.vitepress/theme/components/SidebarRail.vue diff --git a/site/.vitepress/config/shared.ts b/site/.vitepress/config/shared.ts index 2a417a1..f122d7d 100644 --- a/site/.vitepress/config/shared.ts +++ b/site/.vitepress/config/shared.ts @@ -48,13 +48,14 @@ export const sharedBase = { {}, `(function(){var m={xxsmall:'0.88',small:'0.94',normal:'1',large:'1.08',xxlarge:'1.16'};try{var s=localStorage.getItem('awesomeqt-font-size');document.documentElement.style.setProperty('--aq-font-scale',m[s]||'1');}catch(e){}})()`, ], - // 可拖拽侧栏首屏防闪:hydration 前从 localStorage 还原左右栏宽度 CSS 变量。 - // 左栏 272 只是近似值——挂载后 ResizableSidebar 会按当前卷最长条目自适应实测(未存过宽度时)。 - // 与 theme/components/ResizableSidebar.vue 的 CONF(key=vp-sidebar-width/vp-aside-width)一致。 + // 可拖拽抽屉侧栏首屏防闪:hydration 前从 localStorage 还原宽度 CSS 变量。 + // 272 只是近似值——挂载后 ResizableSidebar 会按当前卷最长条目自适应实测(未存过宽度时)。 + // 与 theme/components/ResizableSidebar.vue 的 CONF(key=vp-sidebar-width)一致。 + // (右大纲栏拖拽已砍,TOC 固定 256,不再注入 --vp-aside-width。) [ 'script', {}, - `(function(){try{var w=parseInt(localStorage.getItem('vp-sidebar-width'));if(!w||w<200||w>480){w=272;}document.documentElement.style.setProperty('--vp-sidebar-width',w+'px');var a=parseInt(localStorage.getItem('vp-aside-width'));if(!a||a<180||a>360){a=256;}document.documentElement.style.setProperty('--vp-aside-width',a+'px');}catch(e){}})()`, + `(function(){try{var w=parseInt(localStorage.getItem('vp-sidebar-width'));if(!w||w<200||w>480){w=272;}document.documentElement.style.setProperty('--vp-sidebar-width',w+'px');}catch(e){}})()`, ], ], } diff --git a/site/.vitepress/theme/components/ResizableSidebar.vue b/site/.vitepress/theme/components/ResizableSidebar.vue index 28c0d60..acf2cc7 100644 --- a/site/.vitepress/theme/components/ResizableSidebar.vue +++ b/site/.vitepress/theme/components/ResizableSidebar.vue @@ -1,133 +1,111 @@ + + + + diff --git a/site/.vitepress/theme/custom.css b/site/.vitepress/theme/custom.css index 92e0812..15bcc49 100644 --- a/site/.vitepress/theme/custom.css +++ b/site/.vitepress/theme/custom.css @@ -506,12 +506,12 @@ kbd { ================================================================ */ :root { --vp-sidebar-width: 272px; - --vp-aside-width: 256px; } +/* 右大纲栏(TOC)固定宽:右栏拖拽功能已砍(抽屉化改版后右侧拖拽条被打回),不再消费变量 */ .VPDoc.has-aside .aside { - width: var(--vp-aside-width); - max-width: var(--vp-aside-width); + width: 256px; + max-width: 256px; } .rs-handle { @@ -520,7 +520,8 @@ kbd { bottom: 0; width: 6px; cursor: col-resize; - z-index: 50; + /* 抽屉 z-index 60:handle 要在抽屉右缘之上才可拖(仅 open 时显示,平时无感) */ + z-index: 65; background: transparent; transition: background 0.2s ease, opacity 0.2s ease; } @@ -535,14 +536,6 @@ kbd { opacity: 0.65; } -.rs-handle--right { - position: absolute; - top: 0; - right: -3px; - bottom: 0; - width: 6px; -} - body.rs-resizing { user-select: none; cursor: col-resize; @@ -558,6 +551,202 @@ body.rs-resizing * { } } +/* ================================================================ + 全视口抽屉侧栏(issue #20,2026-09) + 桌面/平板不再常驻避让:撤销 theme-default 对 --vp-sidebar-width 的 + 全链路 padding 消费,侧栏统一回到移动端抽屉形态——平时收起在左缘外, + 拉出后悬浮覆盖正文(不挤压内容,长标题自适应宽度也无害)。 + 开关:左缘窄条 SidebarRail.vue(≥960)+ VPLocalNav 菜单按钮(<1280)。 + ⚠ 本段全部是对 theme-default scoped 样式的覆盖(双类写法补特异性, + 依赖 custom.css 晚于组件样式加载),升级 vitepress 需回归本段。 + ================================================================ */ + +/* 1. 侧栏本体:全视口统一「浮起圆角 panel」几何——四边留缝 + 圆角 + 大阴影, + 不再是贴死左缘的全高竖条。宽度上限与 ResizableSidebar CONF.left.max 一致 */ +.VPSidebar.VPSidebar { + top: calc(var(--vp-layout-top-height, 0px) + 10px); + bottom: 10px; + left: 10px; + width: calc(100vw - 20px); + max-width: 480px; + border-radius: 14px; + border: 1px solid var(--vp-c-border); + box-shadow: 0 16px 48px rgba(0, 0, 0, 0.22); +} + +/* ≥960px 撤销常驻/居中容器宽,回到抽屉态(滑入滑出同移动端) */ +@media (min-width: 960px) { + :root:root { + /* 桌面常驻态会降为 25(低于遮罩 50),抽屉必须盖住正文与遮罩 */ + --vp-z-index-sidebar: 60; + } + + .VPSidebar.VPSidebar { + opacity: 0; + visibility: hidden; + transform: translateX(-100%); + transition: opacity 0.5s, transform 0.25s ease; + } + + .VPSidebar.VPSidebar.open { + opacity: 1; + visibility: visible; + transform: translateX(0); + transition: opacity 0.25s, + transform 0.5s cubic-bezier(0.19, 1, 0.22, 1); + } + + /* curtain 是常驻态把侧栏背景垫到顶栏下的补丁,抽屉模式用不上 */ + .VPSidebar .curtain { + display: none; + } +} + +/* ≥1440px 常驻态会把内容推到居中线,撤销大留白 padding */ +@media (min-width: 1440px) { + .VPSidebar.VPSidebar { + padding-left: 32px; + } +} + +/* 2. 遮罩:≥1280px theme-default 会整个隐藏遮罩,放开让点击外部可关闭 */ +@media (min-width: 1280px) { + .VPBackdrop.VPBackdrop { + display: block; + } +} +:root:root { + /* 默认 0.6 太重,抽屉是轻量浮层,压到 0.3 */ + --vp-backdrop-bg-color: rgba(0, 0, 0, 0.3); +} + +/* 3. 正文避让清零:侧栏不再占位,VPContent 恢复无侧栏的居中布局 */ +.VPContent.VPContent.has-sidebar { + margin: var(--vp-layout-top-height, 0px) auto 0; +} + +@media (min-width: 960px) { + .VPContent.VPContent.has-sidebar { + padding-left: 0; + } +} + +@media (min-width: 1440px) { + .VPContent.VPContent.has-sidebar { + padding-left: 0; + padding-right: 0; + } +} + +/* 正文行宽:常驻态行宽靠 VPContent 的 padding-left 控制,清零后正文可用全屏。 + 侧栏已悬浮不占位,行宽从原版 752/784 放宽到 864/896(中文 ~54 字/行), + 并解除 has-aside 页 688px 的二次收紧。只限 content、不动 container—— + container 在 ≥1280 是 flex(正文+右大纲栏),压它的 max-width 会让 + 两个 width:100% 的 flex 子项互相挤压,正文塌成 0px(实测)。 */ +@media (min-width: 960px) { + .VPDoc.VPDoc.has-sidebar .content.content { + max-width: 864px; + } +} + +@media (min-width: 1440px) { + .VPDoc.VPDoc.has-sidebar .content.content { + max-width: 896px; + } +} + +.VPDoc.VPDoc.has-aside .content-container.content-container { + max-width: 848px; +} + +@media (min-width: 1440px) { + .VPDoc.VPDoc.has-aside .content-container.content-container { + max-width: 880px; + } +} + +/* 4. 顶栏避让清零:logo 区从 absolute 叠在侧栏上方恢复回正常文档流 */ +@media (min-width: 960px) { + /* theme-default ≥960 让整条 navbar 透明、白底靠常驻侧栏+右侧 content-body 垫; + 侧栏悬浮后没有东西垫底,logo 区透出页面灰底——navbar 自己给整条背景, + 并撤掉 content-body 的垫底(避免双层) */ + .VPNavBar.VPNavBar:not(.home) { + background-color: var(--vp-nav-bg-color); + } + + .VPNavBar.VPNavBar:not(.home.top) .content-body.content-body { + background-color: transparent; + } + + .VPNavBar.VPNavBar.has-sidebar .wrapper.wrapper { + padding: 0 32px; + } + + .VPNavBar.VPNavBar.has-sidebar .container.container { + max-width: calc(var(--vp-layout-max-width) - 64px); + } + + .VPNavBar.VPNavBar.has-sidebar .title.title { + position: static; + padding: 0; + width: auto; + height: auto; + } + + .VPNavBar.VPNavBar.has-sidebar .content.content { + position: static; + padding-right: 32px; + padding-left: 0; + } + + .VPNavBar.VPNavBar.has-sidebar .divider.divider { + padding-left: 0; + } +} + +@media (min-width: 1440px) { + .VPNavBar.VPNavBar.has-sidebar .title.title { + padding: 0; + width: auto; + } + + .VPNavBar.VPNavBar.has-sidebar .content.content { + padding-right: calc((100vw - var(--vp-layout-max-width)) / 2 + 32px); + padding-left: 0; + } + + .VPNavBar.VPNavBar.has-sidebar .divider.divider { + padding-left: 0; + } +} + +/* 文档页顶栏 logo("AwesomeQt 教程")收起:品牌已由 AppTitleBar(IDE 标题栏) + 承载,navbar 再挂一行属于信息重复;且侧栏常驻时代它叠在侧栏上方、视觉有归属, + 抽屉化后独占顶栏钉在左上角显得突兀(issue #20 改版反馈)。首页不动。 */ +@media (min-width: 960px) { + .VPNavBar.VPNavBar:not(.home) .title.title { + display: none; + } +} + +/* 5. 本地导航条(960~1279 显示):撤销侧栏避让,「菜单」按钮即抽屉开关 */ +@media (min-width: 960px) { + .VPLocalNav.VPLocalNav.has-sidebar { + padding-left: 0; + } +} + +@media (min-width: 1440px) { + .VPLocalNav.VPLocalNav.has-sidebar { + padding-left: 0; + } + + /* outline 下拉原本定位在常驻侧栏右侧,改回左缘 */ + .VPLocalNavOutlineDropdown .items.items { + left: 32px; + } +} + /* ================================================================ code-group tabs —— hover 着色(借 anatomy_gui) ================================================================ */ diff --git a/site/.vitepress/theme/index.ts b/site/.vitepress/theme/index.ts index 70cee75..f95aaf7 100644 --- a/site/.vitepress/theme/index.ts +++ b/site/.vitepress/theme/index.ts @@ -12,6 +12,7 @@ import CardGrid from './components/CardGrid.vue' import CardLink from './components/CardLink.vue' import FontSizeSwitcher from './components/FontSizeSwitcher.vue' import ResizableSidebar from './components/ResizableSidebar.vue' +import SidebarRail from './components/SidebarRail.vue' import ReadingProgress from './components/ReadingProgress.vue' import ModuleCard from './components/ModuleCard.vue' import ChapterHero from './components/ChapterHero.vue' @@ -24,7 +25,8 @@ export default { return h(DefaultTheme.Layout, null, { // 工作台外壳:网站 = 一个 Qt 桌面应用。标题栏经 --vp-layout-top-height // 由 VitePress 原生机制全链避让;状态栏 fixed 钉底(.Layout 已留 26px)。 - 'layout-top': () => [h(ReadingProgress), h(AppTitleBar), h(ResizableSidebar)], + // SidebarRail:左缘窄条,抽屉侧栏的桌面开关(issue #20) + 'layout-top': () => [h(ReadingProgress), h(AppTitleBar), h(ResizableSidebar), h(SidebarRail)], 'layout-bottom': () => h(StatusBar), // 首页 = Welcome 欢迎屏(index.md 零 hero/features frontmatter,零覆盖战): // 交互演示(signal→slot 真控件复刻)→ 三层卡 → 示例画廊 → 编译输出 → 生态行。