Files
Noah 45ab54ba90 fix(ui): 修复新 UI 侧栏被顶出与平台设置页导航重复 (#1706)
* fix(ui): 去掉 html/body 的 overflow-x: hidden,恢复侧栏与页头吸顶

#1704 引入的 bg-global.css 给 html、body 加了 overflow-x: hidden,任何非 visible
的 overflow 都会把 body 变成滚动容器,侧栏(layout.module.scss .sider)和
PageHeader 的 position: sticky 于是相对 body 而不是视口定位——主内容一长,
整页滚动就把左侧导航和「保存」按钮一起顶出视口。

- 删除 html/body 的 overflow-x: hidden,并在两处样式注明这条约束
- 两个 position: fixed 的背景层改用 inset: 0 铺满视口,不再依赖 100vw,
  也不会撑出横向滚动条

问题 1 of #1705(侧边导航被顶出)。

* fix(ui): 空间配置「平台设置」只保留左侧平台列表一套导航

#1704 把平台设置改成「左列平台列表 + 右栏 Collapse」后,右栏的手风琴仍然
为每个平台渲染一条带平台名的折叠栏,与左列重复(#1705 第二点)。

- 新增 app/ui/plugins/PlatformPanel.tsx:各平台插件的外壳,传入 bare 时只
  输出字段,否则保持原来的 Collapse.Panel(配置覆写弹窗仍在用)
- 10 个平台插件把 Collapse.Panel 换成 PlatformPanel,并透传 bare
- dashboard 右栏不再用 Collapse,改为每个平台一个 <section hidden>:所有
  字段始终挂载,只切换 hidden,保证 PUT /v1/configuration 整表覆盖时其他
  平台的参数与凭据不会因为字段卸载而丢失
- 左列平台列表在页头下方吸顶(position: sticky),右栏面板很长时列表不再
  随内容滚出视口;PageHeader 把自身高度写入 --page-header-height 供其取用;
  Tabs 关闭 tabPaneMotion 并放开 .semi-tabs-pane 的 overflow,否则 pane 会
  成为 sticky 的滚动容器。移动端横排 chip 行保持随内容滚动
- 左列按钮补 aria-pressed,nav 补 aria-label

Fixes #1705

* feat(ui): 空间配置保存校验失败时自动定位到第一个出错字段

平台设置的字段全部挂载、只切换 hidden,未选中的 Tab / 平台面板里的校验
错误用户看不到,表现为点「保存」没有任何反应。

- Form 加 onSubmitFail:把 Semi 的嵌套 errors 拍平成字段路径,按 DOM 顺序
  找到第一个出错字段,切到它所在的 Tab(Tabs 改为受控)与平台面板,再
  scrollIntoView 并聚焦,同时 Toast 提示未通过的项数
- TabPane 内容加 data-tab、平台 section 加 data-platform,供定位使用;
  不改插件接口

Refs #1705

* refactor(ui): 改用应用壳布局解决侧栏被顶出,移除 sticky 补救与 tabPaneMotion 取舍

按 review 意见(#1706)不再靠 position: sticky 解决问题一,改成简单的应用壳:

- layout.module.scss:.app 改为 height: 100vh(100dvh)+ overflow: hidden 的 flex 容器,
  页面本身不滚动;.sider 是固定宽度的普通子元素(撑满壳高,去掉 sticky/top/100vh);
  .main 加 min-height: 0 + overflow: auto,成为唯一的滚动容器。侧栏、页脚服务灯
  自然留在视口内,PageHeader 原有的 position: sticky 相对 .main 吸顶,无需改动
- 去掉为让平台列表在 Tab 面板内 sticky 而加的补救:.platformNav 的 sticky /
  --page-header-height / max-height、PageHeader 的 ResizeObserver、Tabs 的
  tabPaneMotion={false} 以及 .semi-tabs-pane 的 overflow 覆盖,Tab 切换动画恢复。
  平台列表改回随内容滚动
- bg-global.css:文档不再滚动,html/body 不需要 overflow 规则,注释改为说明现状;
  两个 fixed 背景层保持 inset: 0

验证:tsc 0 错误、next build 通过;13 页 × 浅色 / 深色 / 折叠 / 移动端 390 / 平板 760,
主区滚到底后 document.scrollHeight == innerHeight(文档不滚)、aside top 0、页脚
bottom == innerHeight、header top 0、main 无横向溢出;Semi Select 下拉(主区预滚 1.2k px
及打开后继续滚动)、Popconfirm、配置覆写 Modal 及其内部 Select、Toast 位置全部正确;
切遍 10 个平台后保存 PUT 73/73 键(3 次);校验失败自动定位三场景通过(2 轮)。

Refs #1705

* refactor(ui): 平台设置去掉外层嵌套卡片,改两栏独立滚动布局

按 review 第二条意见(#1706):平台列表不用 sticky,也不随内容滚走——去掉包在
「平台列表 + 面板」外面的嵌套卡片,让两栏并排、各自独立滚动。

- dashboard/page.tsx:删掉 dc.content / rootConfigPanel / main / content 四层包裹和
  平台设置里的 framePlatformConfig 卡片与重复的「平台设置」标题;页面主体改为
  .page(占满页头以下的剩余高度)→ Form → Tabs,每个 Tab 面板在自己内部滚动,
  页面本身不滚,页头「保存」始终可见。去掉底部两个 Space 占位
- dashboard.module.scss:重写。删除 #1704 之前遗留的整段 .rootConfigPanel 嵌套规则
  (其中 frameInside / group / lineStory 等类早已无人引用);Form / Tabs /
  semi-tabs-content / semi-tabs-pane(含开启动画时的 motion-overlay)改为
  flex: 1 + min-height: 0 的列容器,把高度让给当前面板,并补回
  .semi-tabs-pane-inactive 的 display: none(本模块选择器特异性更高)
- 平台设置:.platformLayout 两栏,.platformNav 160px、align-self: flex-start、
  max-height: 100% + overflow-y: auto(矮视口时列表自己滚),.platformBody
  flex: 1 + overflow-y: auto。右栏再长列表也不动
- 全局设置 / 开发者选项一致处理:frameDownload / frameUpload / frameDeveloper 不再是
  带边框和 50px 内边距的卡片,改为分区标题 + 分隔线的普通分区,面板 .pane 自身滚动
- 移动端(≤680px):两栏改为上下堆叠,平台列表是横向滑动的标签行,固定在面板顶部
  不随字段滚走
- 自定义背景开启时给两个滚动面板垫一层 75% 的 bg-1 半透明底色,保证文字可读

验证:tsc 0 错误、next build 通过;空间配置页在 1440 / 760 / 390 × 浅 / 深 / 折叠 /
520px 矮视口下:文档与 <main> 均不滚动,页头与「保存」始终在视口内,右栏滚到底
(哔哩哔哩面板 1223px)时平台列表位置不变,矮视口下列表自身可滚;全局设置面板独立
滚动;切遍 10 个平台后保存 PUT 73/73 键(4 次);校验失败自动定位三场景通过(3 轮,
scrollIntoView 在嵌套滚动容器内正常);Select 下拉在面板预滚 1k px 及滚动中跟随触发器,
Popconfirm / Modal / Toast 位置正确;其余 12 页布局探针与上一提交一致。

Refs #1705

* fix(ui): 更新日志页内容不再覆盖导航顶栏

应用壳布局下页头真正吸顶后暴露出来的问题(review 第三条,#1706):更新日志页把
PageHeader 又包在一层 position: sticky; z-index: 1 的 Semi Layout.Header 里,
形成一个层级只有 1 的 stacking context,PageHeader 自己的 z-index: 10 只在这层
内部生效;而版本卡片流 .feed 又设了 position: relative; z-index: 1,DOM 顺序在
后,滚动时就画在页头之上。

- changelog/page.tsx:去掉外层 Header,与其它页一样直接渲染 PageHeader
- changelog.module.scss:删掉 .feed / .center 的 position: relative; z-index: 1

验证:10 个带页头的页面滚到底后对页头内 6 个点做 elementFromPoint 命中测试,
全部命中页头自身(修前 /changelog 有 4 个点命中版本卡片头);/history 播放器
Modal 居中且在最上层;/logviewer、/status 等无层叠。

Refs #1705
2026-09-22 04:20:48 +00:00
..
2024-01-12 00:54:14 +08:00