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

36 lines
1.1 KiB
CSS
Raw Permalink 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.
/* 全局自定义背景:当 body 带 app-has-bg 时生效 */
/* 两个背景层用 position: fixed + inset: 0 铺满视口。页面滚动由应用壳的主内容区承担
(layout.module.scss .app / .main),文档本身不滚,这里不需要再给 html / body 设 overflow */
body.app-has-bg::before {
content: '';
position: fixed;
inset: 0;
z-index: -2;
background-image: var(--app-bg-image);
background-repeat: no-repeat;
background-size: cover;
background-position: center;
pointer-events: none;
}
/* 同色半透明遮罩,保证所有页面文字可读(明暗主题都跟随,透明度可调) */
body.app-has-bg::after {
content: '';
position: fixed;
inset: 0;
background: var(--semi-color-bg-0);
opacity: var(--app-bg-mask-opacity, 0.35);
z-index: -1;
pointer-events: none;
}
/* 让 Semi 顶层容器透出 body 背景(兼容旧布局) */
body.app-has-bg .semi-layout,
body.app-has-bg .semi-sider,
body.app-has-bg .semi-nav,
body.app-has-bg .semi-layout-content,
body.app-has-bg .semi-layout-header {
background: transparent !important;
}