dsh-sidebar-panel-buttons
把 dsh Web 侧边栏顶部的全局面板菜单(插件 / 扩展管理 / 定时任务 / IM …)从「竖向文字列表」 收起为一排横向图标按钮;要不要收起,是设置 → 通用里的一个选项, 侧边栏本身不再多出任何按钮。
| 之前:竖排文字列表 | 之后(默认):一行图标按钮 |
|---|---|
![]() |
![]() |
设置 → 通用(本插件的行排在「字号」之后):
┌──────────────────────────────────────────────────────────┐
│ 语言 / 主题 / 字号 │
│ ──────────────────────────────────────────────────────── │
│ 侧边栏面板菜单 ┌───────┬────────┐ │
│ 侧边栏顶部的全局面板菜单(插件、扩展 │ 按钮行 │ 列表 │ │
│ 管理、定时任务、IM 等)如何排列。 └───────┴────────┘ │
│ ──────────────────────────────────────────────────────── │
│ 链接打开方式 / 开发者工具 / 快捷键 … │
└──────────────────────────────────────────────────────────┘
效果
| 之前 | 之后(默认) | |
|---|---|---|
| 该区域 | 4 行「图标 + 文字」,每行 36px 高 | 一行 36×36 图标按钮,横向排列 |
| 文字 | 常显 | 隐藏,悬停显示同名 tooltip |
| 侧边栏窄条(rail) | 图标竖排 | 不变(插件在此阶段不写任何规则) |
| 侧边栏其它部分 | 工作区 / 会话列表 / 底部按钮一律不动,不加任何控件 | 同左 |
在设置 → 通用里选择「按钮行 / 列表」即可切换;选择记在浏览器 localStorage,
刷新后保持。默认是按钮行。
安装
方式 1:CLI(推荐,包/锁文件保持一致)
dsh plugin --profile core-020 add /Users/ruan/projects/dsh-home/dsh-sidebar-panel-buttons
# 若 dsh 不在 PATH 里:
node "/Users/ruan/Library/Application Support/dsh-tauri/dependencies/dsh/node_modules/@deepseek-ai/dsh/lib/bin.js" \
plugin --profile core-020 add /Users/ruan/projects/dsh-home/dsh-sidebar-panel-buttons
这条命令把本包以 link: 写进 profile 依赖、追加到 dsh.profile.bundles,并应用本包
cordis.patch.yml 里的挂载行——与 dsh-tauri-* 这些插件在本机的挂载方式完全一致。
方式 2:手动挂载(不碰 package.json / lockfile)
ln -s /Users/ruan/projects/dsh-home/dsh-sidebar-panel-buttons \
~/.dsh/profiles/core-020/node_modules/dsh-sidebar-panel-buttons
然后在 ~/.dsh/profiles/core-020/cordis.patch.yml 末尾追加:
- insert:
- id: sidebar-panel-buttons
name: dsh-sidebar-panel-buttons
这种方式在下次
pnpm install清理“多余”符号链接后会失效,届时启动会因为ERR_MODULE_NOT_FOUND报错——长期使用请走方式 1。
方式 3:图形界面
侧边栏「插件」页 → 添加插件 → 填上面的绝对路径。
生效
profile 配置默认可热重载,客户端插件变更会被推送到已打开的页面。没变化就刷新页面(⌘R), 再不行重启应用。
验证
curl -s http://127.0.0.1:3082/ | grep -c dsh-sidebar-panel-buttons # 宿主启动图里应出现本包
页面上:那排按钮出现、且侧边栏底部没有任何插件的按钮即安装成功; 设置(⌘,)→ 通用 里能看到「侧边栏面板菜单」这一行(排在「字号」之后)。 控制台里可以看到插件写的两个状态属性:
document.documentElement.dataset.dshPanelButtons // "row"(默认)或 "list"
document.documentElement.hasAttribute("data-dsh-panel-wide") // 侧边栏是否处于展开阶段
卸载 / 回滚
- 方式 1 装的:
dsh plugin --profile core-020 remove dsh-sidebar-panel-buttons - 方式 2 装的:删掉那行 patch 与符号链接
- 只想临时关掉:插件页禁用,或在 设置 → 通用 里切回「列表」(不动配置)
实现
- 目标区域是
sidebar.panellist,由@deepseek-ai/dsh-client-ui-sidebar渲染:一个nav里每个 slot 入口一个<button>(图标格 + 文字格)。该区域的几何没有 slot 扩展点 (slot 只喂每行的图标),所以插件走样式表 + DOM 打标:- 注入一张
<style>,每一条规则都由<html data-dsh-panel-buttons="row" data-dsh-panel-wide>把关——切到list或去掉属性, 侧边栏立刻恢复原样; - 在 DOM 扫描里给容器与行打自己的
data-dsh-panel-nav/data-dsh-panel-row/data-dsh-panel-label标签,样式表只认这些标签,不依赖 shell 的任何 hash 类名。
- 注入一张
- 依赖的“契约”只有稳定项:渲染器在每行里输出的
data-slot="sidebar.panellist"锚点,以及行上 原有的aria-label(本地化菜单名)。tooltip 就是content: attr(aria-label),不需要额外 DOM。 data-dsh-panel-wide只在“有文字标签”的展开阶段出现,所以窄条 rail 完全走 shell 原样式。- 扫描在稳态是 O(行数):定位到的
nav会缓存,只有离开文档才重新定位;MutationObserver负责「插件后注册面板」「侧边栏展开/收起」这些变化。 - 选项注册进 shell 自带的「通用」列表
settings.general.item(kind: list,order: 12, 排在「字号」11 与「链接打开方式」14 之间),所以插件不占设置导航的一页,也不再需要 自己的标题/说明;行就是列表的一项,控件用 shell 自己的SegmentedControl。 - 行几何是照 shell 的
DeveloperToolsRow.module.css原样复刻的(label 左 / 控件右 /gap:24px/padding:16px 0/0.5px分隔线 / 14px 标题 + 12px 灰字说明), 并且行根元素就是 slot host 的直接子节点——这样 shell 自己的[data-slot="settings.general.item"] > :last-child{border-bottom:none}会照常生效, 无论最后一行是不是本插件。
测试
npm test # 零依赖:桩 DOM 跑 apply / 扫描 / 通用设置行 / 卸载(44 项)
npm run check # 语法 + 清单(dsh.client、exports、bundle id、挂载行)
npm install --no-save happy-dom && npm run test:dom
# 真 DOM:把侧边栏与「通用」里的那一行都渲染出来,验证选择器命中、
# 级联生效、点选项真的切换并落盘(29 项)
test:dom 会加载本机 dsh 自带的侧边栏样式表一起算级联,确认是「覆盖赢了」,而不只是
「我们声明了」。伪元素(tooltip)与 border 简写里的 var() 在 happy-dom 里无法计算,
这部分只做声明级断言。
限制
- 上游若改写该区域结构(不再有
sidebar.panellist出口),样式会静默失效, 侧边栏回落到原生外观,不会报错或崩页。 - 只改这一处区域,不动工作区列表与窄条 rail;设置里只加一行,不新增页面、不改导航。
- 按钮尺寸(36px)、间距(4px)、tooltip 与设置行样式都在
lib/client.js的 CSS 字符串里,可直接调。 - 设置项存在浏览器
localStorage(键dsh-sidebar-panel-buttons:layout), 不进宿主settings.yaml:它是纯浏览器布局偏好,与侧边栏折叠状态同类。 - 需要 dsh
0.2.0-rc.1(dsh.compatibility已声明)。


No comments yet. Be the first to write one.