dsh-panellist-collapse:折叠左侧栏「全局面板」列表,且不动皮肤动图

前言

DSH 的左侧栏上部是一块区块:orca-link 皮肤的动图,下面是「全局面板」列表(插件 / 任务看板 / 技能中心 / 智能体 / Git / SSH / 更多)。列表固定 7 项,内容多了之后侧栏纵向空间被吃掉不少,工作区往下推。

常见的改法是直接收起整列,或者改皮肤样式。前者一刀切,展开要再点一次;后者改的是皮肤文件,动图舞台的 margin-top 很容易被连带删掉,工作区顶上去盖住动图。下面介绍的 asdw159632/dsh-panellist-collapse 走的是第三条路:在列表后面插一条很薄的折叠条,折叠时只隐藏多余行、只收高度,动图位置完全不动。


这是什么

一个本地 harness 插件 bundle,包名 @local/dsh-panellist-collapse,维护者 asdw159632,分类为客户端。Host 半区是空的 apply(),Client 半区实现全部逻辑:折叠条的 DOM、折叠样式、body 属性同步、locale 字典,以及用 MutationObserver 维持注入节点位置。

解决的问题只有一个:侧栏「全局面板」列表太长,要一个展开/收起入口,按钮放在「工作区」上方,且折叠时不要动它上方的皮肤动图。

核心功能

折叠目标不是列表容器,而是列表内的行。折叠时只保留前 KEEP_ROWS 行,默认 1 行,也就是只剩「插件」按钮;其余 6 行隐藏。列表容器和它的 margin-top 完全不动。

折叠条插在面板列表之后、工作区之前。这个位置没有官方槽位,所以用 DOM 插入加 MutationObserver 观察 document.body:宿主重渲染把节点移除后自动重新插回,自身插入不会触发无变化循环。

保留列表的 margin-top 是这个插件最关键的一点。orca-link 皮肤的动图舞台靠列表这条 margin 撑出来:

margin-top: calc(var(--orca-stage) - 116px)

如果用 display:none 折叠列表,margin 会一起被删掉,动图舞台塌掉、工作区顶上去盖住动图。因此折叠改用 height: 0 + overflow: hidden 收高度,margin 保留,动图停留在原处。

折叠状态写入 localStorage['dsh.panellist.collapsed'],刷新或重启后保持。文案通过 Client locale 服务注册 zh / en 两种,tooltip 分别是「收起面板列表」「展开面板列表」。侧栏窄条(rail)模式下列表本就不可见,折叠条按列表宽度判断后自动隐藏。

想只放几个按钮时改 client.js 顶部的常量即可,刷新页面即生效:

const KEEP_ROWS = 1; // 1 = 只留「插件」;2 = 插件 + 任务看板;3 = 再加技能中心

目录内容

文件 作用
package.json bundle 清单:dsh.bundle.patch + dsh.client(platform: web、immediately)
cordis.patch.yml 插入一行 panellist-collapse(bundle 身份)
index.js Host 半区:export function apply() {}
client.js 全部实现:折叠条 DOM、折叠样式、body 属性同步、locale 字典、MutationObserver 维护位置
locale/en.json / locale/zh.json 插件管理界面里的标题/描述(meta.title / meta.description)
icon.svg 原创图标

package.json 中与运行相关的字段:

"dsh": {
  "bundle": { "patch": "./cordis.patch.yml" },
  "client": {
    "platform": "web",
    "immediately": true,
    "inject": ["@deepseek-ai/dsh-client-ui-sidebar"]
  }
}

安装与启用

README 提供的安装与卸载命令如下。注意这里 target 填的是本仓库目录的绝对路径,不是仓库名:

plugin_manager install_bundle target="<本仓库目录的绝对路径>"
plugin_manager remove_bundle target="@local/dsh-panellist-collapse"

本地目录使用 pnpm link。改完 client.js 后刷新页面即可生效,不需要重装。

安装后按 README 的验证记录检查两点:一条是 plugin_manager install_bundle 返回 application: applied、warnings: [],Host 组合里出现 include:panellist-collapse;另一条是浏览器里折叠条落在「更多」行下方、工作区标题上方,居中一个箭头。

典型用法

README 中记录了 2026-10-29 的一次实测,宿主 0.2.1-rc.3,皮肤 orca-link,访问 http://127.0.0.1:1344:

  1. 点击折叠条,只保留「插件」一行,其余 6 行隐藏;
  2. 动图停在原处不动,工作区紧接在剩余那一行下方;
  3. 再点一次展开,布局完全恢复原状;
  4. 折叠状态刷新后保持,控制台没有本插件的报错。

日常使用不需要改代码。默认行为就是折叠后只留「插件」一行。想多放一项就改 KEEP_ROWS,改成 2 就是「插件 + 任务看板」,改成 3 再加「技能中心」,以此类推。

实现上的坑

README 的迭代记录里记了四点,按发现顺序列在这里,方便评审和二次开发时避雷。

  1. 按钮位置:初版挂在侧栏底部扩展位 sidebar.footer.action,反馈说位置不对、离列表太远;同时初版用 display:none 折叠,把列表 margin 一起删了,动图舞台塌掉。后来按钮移到列表与工作区之间,折叠改为 height:0 + overflow:hidden 保留 margin。

  2. 折叠目标:[data-slot="sidebar.panellist"] 是逐面板项的座位,隐藏它只掉图标、文字还在,并不是列表容器。折叠目标改用 [class*="panelList"]。

  3. 导航选择器:nav[role="navigation"] 匹配不到,「navigation」是 <nav> 的隐式角色,元素上没有这个属性。选择器和 findNav() 都改成实际存在的 [class*="panelList"],兜底用 [data-dsh-surface="sidebar"] nav。

  4. 节点被重渲染移除:宿主 DOM 重渲染可能删掉注入节点,用 MutationObserver 观察 document.body,发现折叠条不在列表后面就重新插回。

适用场景与注意

适合这类情况:皮肤在侧栏上部放了一块依赖列表 margin 撑位置的内容,同时面板列表项多、侧栏纵向空间紧张。此时不适合直接收整列,也不适合改皮肤样式。

需要注意三点:

  1. 依赖宿主 DOM 结构。选择器用的都是语义片段([class*="panelList"]、[data-dsh-surface="sidebar"]、nav),没有用 hash 前缀,但上游若大幅调整侧栏结构,需要跟着改一行选择器。换其他皮肤不影响位置,折叠条跟着列表走。
  2. 动图不归它管。折叠或展开都不会改动画图的样式或位置,这是设计目标,不是遗漏。
  3. 插件以当前 dsh 进程权限运行。安装前应打开仓库确认源码内容,并确认许可证(本仓库为 MIT,Copyright (c) 2026 asdw159632)。另外这个仓库是从开发工作区 DSH-custom/mods/sidebar-panellist-collapse/ 发布的独立副本,改动以本仓库为准。

结尾

这个插件的价值不在功能多,而在一条边界处理得干净:折叠面板列表的同时不碰皮肤动图的舞台。对侧栏纵向空间紧张、又不想改皮肤文件的人来说,是一个可以本地装上、改一行常量自定义保留项的轻量方案。

  • 目录页:https://www.skillhub.cn/plugins/asdw159632/dsh-panellist-collapse
  • GitHub:https://github.com/asdw159632/dsh-panellist-collapse
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜