dsh-composer-ux 0.29.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +5 -2
- package/dsh-plugin.json +1 -1
- package/lib/client.js +23 -38
- package/lib/client.js.map +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.29.1] — 2026-10-29(「账号与其他」+ 收起状态不再记忆:打开就收起)
|
|
6
|
+
|
|
7
|
+
用户 2026-10-29 两条:
|
|
8
|
+
|
|
9
|
+
1. 「账号与用量改为账号与其他」;
|
|
10
|
+
2. 「收起与否改为默认收起」—— 追问后选定**改行为**:每次打开 DSH 都强制收起、**不记住展开**,
|
|
11
|
+
两处(顶部「全局面板」+ 底部区)一起。
|
|
12
|
+
|
|
13
|
+
**行为变了(这条最容易察觉)**
|
|
14
|
+
|
|
15
|
+
- 以前:点开折叠条 → 状态写进 `composer-ux-nav-fold.json` → 下次打开还是展开的。
|
|
16
|
+
- 现在:点开只在**本次会话**有效;重开 DSH 一律回到收起。
|
|
17
|
+
文件里只留**形态**(`mode`:收成一条 / 只留图标 / 不折叠);老文件里的 `collapsed: false`
|
|
18
|
+
会被**忽略**,不会把"上次点开过"带过来。
|
|
19
|
+
|
|
20
|
+
**界面上的连带改动**
|
|
21
|
+
|
|
22
|
+
- 底部细条文字:`账号与用量` → **`账号与其他`**(连带 title「展开/收起账号与其他」)。
|
|
23
|
+
- 设置页「侧边栏」组:两个"现在收起"开关删掉(一个不落盘的开关是骗人的),
|
|
24
|
+
换成一行状态说明「打开时:总是收起(不记住展开):点折叠条可临时展开」+ 当前是收起/临时展开。
|
|
25
|
+
|
|
26
|
+
**为什么拆了个新文件**:把纯状态(`NavFoldState` / `sanitizeNavFold` / `persistableNavFold`)从
|
|
27
|
+
`nav-fold-store.ts` 挪到 `nav-fold-state.ts` —— store 里带 React hook,测试要 bundle 它就得拉 react;
|
|
28
|
+
拆开之后"强制收起"和"只有形态落盘"这两条能像其它纯函数一样逐条钉住。
|
|
29
|
+
|
|
30
|
+
**测试**:`test/sidebar-nav.mjs` 新增第 7 节(6 条);变异新增 TC / TD(又记住展开 / 收起状态被写盘)。
|
|
31
|
+
|
|
5
32
|
## [0.29.0] — 2026-10-29(侧边栏**底部区**也能收:整块收成一行「账号与用量」)
|
|
6
33
|
|
|
7
34
|
用户 2026-10-29(截图圈住左下角「今日消耗金额」卡片 + 下面那行账号):
|
package/README.md
CHANGED
|
@@ -135,7 +135,10 @@ dsh plugin --profile web add <你克隆或解压出来的目录>
|
|
|
135
135
|
### 侧边栏底部区(0.29.0)
|
|
136
136
|
|
|
137
137
|
左下角那一块(账号行 + 插件塞在这里的卡片,比如「今日消耗金额」)也能收:**整块收成一行
|
|
138
|
-
|
|
138
|
+
「账号与其他 ▾」**,点一下展开。设置 → 输入体验 →「设置面板」卡 →「侧边栏」组可以看到当前状态。
|
|
139
|
+
|
|
140
|
+
**两处都是"打开就收起、不记住展开"**(0.29.1):点折叠条只在本次会话有效,重开 DSH 一律回到收起;
|
|
141
|
+
文件里只记"形态"这一项偏好。
|
|
139
142
|
|
|
140
143
|
做法是**整块藏/显**:只在最外层容器挂一个属性,**不碰里面任何一个节点** —— 所以别的插件往这个插槽里
|
|
141
144
|
放什么都不会被我们改坏(用量卡片就是 `@kenz1117/dsh-ui-usage-billing` 放在 `sidebar.footer.action` 里的)。
|
|
@@ -681,7 +684,7 @@ node build.mjs # 产出 lib/index.js + lib/client.js
|
|
|
681
684
|
# 里同版本的 npm 包(两者逐字节相同)——CI 上走的就是退路
|
|
682
685
|
npm test # 30 个套件;当前 2621 passed, 0 failed(2026-10-28 实测;CI 三平台同样全绿)
|
|
683
686
|
# 走 scripts/run-tests.mjs:顺带把"多少套件/多少条"记进 test/.last-run.json
|
|
684
|
-
npm run test:mutations # 手动跑:变异测试,证明那套护栏真的在咬人(
|
|
687
|
+
npm run test:mutations # 手动跑:变异测试,证明那套护栏真的在咬人(205 条,须单独跑)
|
|
685
688
|
# 同样记录结果,供下面的文档门禁核对
|
|
686
689
|
npm run gates # 发版门禁三条一起跑:tag 指向 / 包内容 / 文档数字
|
|
687
690
|
npm run check:tag # ① tag 名里的版本 == 该 tag 所指提交里的 package.json 版本
|
package/dsh-plugin.json
CHANGED
package/lib/client.js
CHANGED
|
@@ -2715,12 +2715,24 @@ var import_react3 = require("react");
|
|
|
2715
2715
|
|
|
2716
2716
|
// src/client/nav-fold-store.ts
|
|
2717
2717
|
var import_react2 = require("react");
|
|
2718
|
+
|
|
2719
|
+
// src/client/nav-fold-state.ts
|
|
2718
2720
|
var NAV_FOLD_MODES = [
|
|
2719
2721
|
{ id: "off", label: "\u4E0D\u6298\u53E0" },
|
|
2720
2722
|
{ id: "bar", label: "\u6536\u6210\u4E00\u6761" },
|
|
2721
2723
|
{ id: "icons", label: "\u53EA\u7559\u56FE\u6807" }
|
|
2722
2724
|
];
|
|
2723
2725
|
var DEFAULT_NAV_FOLD = { mode: "bar", collapsed: true, footerCollapsed: true };
|
|
2726
|
+
function sanitizeNavFold(value) {
|
|
2727
|
+
const raw = value ?? {};
|
|
2728
|
+
const mode = raw.mode === "off" || raw.mode === "icons" || raw.mode === "bar" ? raw.mode : DEFAULT_NAV_FOLD.mode;
|
|
2729
|
+
return { mode, collapsed: true, footerCollapsed: true };
|
|
2730
|
+
}
|
|
2731
|
+
function persistableNavFold(patch) {
|
|
2732
|
+
return patch.mode === void 0 ? {} : { mode: patch.mode };
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
// src/client/nav-fold-store.ts
|
|
2724
2736
|
var state2 = DEFAULT_NAV_FOLD;
|
|
2725
2737
|
var listeners = /* @__PURE__ */ new Set();
|
|
2726
2738
|
function subscribeNavFold(listener) {
|
|
@@ -2735,15 +2747,6 @@ function setLocal(next) {
|
|
|
2735
2747
|
state2 = merged;
|
|
2736
2748
|
for (const listener of listeners) listener();
|
|
2737
2749
|
}
|
|
2738
|
-
function sanitizeNavFold(value) {
|
|
2739
|
-
const raw = value ?? {};
|
|
2740
|
-
const mode = raw.mode === "off" || raw.mode === "icons" || raw.mode === "bar" ? raw.mode : DEFAULT_NAV_FOLD.mode;
|
|
2741
|
-
return {
|
|
2742
|
-
mode,
|
|
2743
|
-
collapsed: typeof raw.collapsed === "boolean" ? raw.collapsed : DEFAULT_NAV_FOLD.collapsed,
|
|
2744
|
-
footerCollapsed: typeof raw.footerCollapsed === "boolean" ? raw.footerCollapsed : DEFAULT_NAV_FOLD.footerCollapsed
|
|
2745
|
-
};
|
|
2746
|
-
}
|
|
2747
2750
|
async function loadNavFold() {
|
|
2748
2751
|
try {
|
|
2749
2752
|
const response = await fetch(NAV_FOLD_API_PATH, { headers: { accept: "application/json" } });
|
|
@@ -2755,11 +2758,13 @@ async function loadNavFold() {
|
|
|
2755
2758
|
}
|
|
2756
2759
|
async function saveNavFold(patch) {
|
|
2757
2760
|
setLocal(patch);
|
|
2761
|
+
const body = persistableNavFold(patch);
|
|
2762
|
+
if (body.mode === void 0) return "";
|
|
2758
2763
|
try {
|
|
2759
2764
|
const response = await fetch(NAV_FOLD_API_PATH, {
|
|
2760
2765
|
method: "POST",
|
|
2761
2766
|
headers: { "content-type": "application/json" },
|
|
2762
|
-
body: JSON.stringify(
|
|
2767
|
+
body: JSON.stringify(body)
|
|
2763
2768
|
});
|
|
2764
2769
|
if (!response.ok) return `\u4FDD\u5B58\u6298\u53E0\u72B6\u6001\u5931\u8D25\uFF1A\u5BBF\u4E3B\u8FD4\u56DE HTTP ${response.status}`;
|
|
2765
2770
|
const payload = await response.json();
|
|
@@ -2940,7 +2945,7 @@ function applyNavFold(doc, state3, onToggle) {
|
|
|
2940
2945
|
var FOOTER_FOLD_ATTR = "data-ux-footer-fold";
|
|
2941
2946
|
var FOOTER_HEAD_ATTR = "data-ux-footer-fold-head";
|
|
2942
2947
|
var FOOTER_FOLD_STYLE_ATTR = "data-ux-footer-fold-style";
|
|
2943
|
-
var FOOTER_HEAD_TEXT = "\u8D26\u53F7\u4E0E\
|
|
2948
|
+
var FOOTER_HEAD_TEXT = "\u8D26\u53F7\u4E0E\u5176\u4ED6";
|
|
2944
2949
|
var ACCOUNT_LABELS = ["\u8D26\u53F7\u83DC\u5355", "Account menu", "\u8D26\u6237\u83DC\u5355"];
|
|
2945
2950
|
var FOOTER_FOLD_CSS = `
|
|
2946
2951
|
[${FOOTER_FOLD_ATTR}='folded'] { display: none !important; }
|
|
@@ -3000,7 +3005,7 @@ function ensureHeader2(doc, footer, state3, onToggle) {
|
|
|
3000
3005
|
}
|
|
3001
3006
|
const open = !state3.collapsed;
|
|
3002
3007
|
head.setAttribute("aria-expanded", open ? "true" : "false");
|
|
3003
|
-
head.setAttribute("title", open ? "\u6536\u8D77\u8D26\u53F7\u4E0E\
|
|
3008
|
+
head.setAttribute("title", open ? "\u6536\u8D77\u8D26\u53F7\u4E0E\u5176\u4ED6" : "\u5C55\u5F00\u8D26\u53F7\u4E0E\u5176\u4ED6");
|
|
3004
3009
|
head.textContent = "";
|
|
3005
3010
|
const label = doc.createElement("span");
|
|
3006
3011
|
label.textContent = FOOTER_HEAD_TEXT;
|
|
@@ -6993,38 +6998,18 @@ function SettingsSection({ useLive, useBook, useBookStatus, useWriteNotice, acti
|
|
|
6993
6998
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6994
6999
|
Row,
|
|
6995
7000
|
{
|
|
6996
|
-
title: "\
|
|
6997
|
-
desc: navFold.mode === "off" ? "\u5F62\u6001\u662F\u300C\u4E0D\u6298\u53E0\u300D\uFF0C\u8FD9\
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
{
|
|
7001
|
-
small: true,
|
|
7002
|
-
label: "\u73B0\u5728\u6536\u8D77\u5168\u5C40\u9762\u677F",
|
|
7003
|
-
checked: navFold.collapsed,
|
|
7004
|
-
disabled: navFold.mode === "off",
|
|
7005
|
-
onChange: (next) => {
|
|
7006
|
-
void saveNavFold({ collapsed: next });
|
|
7007
|
-
}
|
|
7008
|
-
}
|
|
7009
|
-
)
|
|
7001
|
+
title: "\u6253\u5F00\u65F6",
|
|
7002
|
+
desc: navFold.mode === "off" ? "\u5F62\u6001\u662F\u300C\u4E0D\u6298\u53E0\u300D\uFF0C\u8FD9\u91CC\u4E0D\u8D77\u4F5C\u7528" : "\u603B\u662F\u6536\u8D77\uFF08\u4E0D\u8BB0\u4F4F\u5C55\u5F00\uFF09\uFF1A\u70B9\u6298\u53E0\u6761\u53EF\u4E34\u65F6\u5C55\u5F00\uFF0C\u91CD\u5F00 DSH \u53C8\u56DE\u5230\u6536\u8D77",
|
|
7003
|
+
first: false,
|
|
7004
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { fontSize: 12, opacity: 0.75 }, children: navFold.collapsed ? "\u6536\u8D77\u4E2D" : "\u5DF2\u4E34\u65F6\u5C55\u5F00\uFF08\u4EC5\u672C\u6B21\uFF09" })
|
|
7010
7005
|
}
|
|
7011
7006
|
),
|
|
7012
7007
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7013
7008
|
Row,
|
|
7014
7009
|
{
|
|
7015
7010
|
title: "\u5E95\u90E8\u533A",
|
|
7016
|
-
desc: "\u8D26\u53F7\u884C\u4E0E\u63D2\u4EF6\u585E\u5728\u8FD9\u91CC\u7684\u5361\u7247\uFF08\u6BD4\u5982\u4ECA\u65E5\u6D88\u8017\u91D1\u989D\uFF09",
|
|
7017
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7018
|
-
Switch,
|
|
7019
|
-
{
|
|
7020
|
-
small: true,
|
|
7021
|
-
label: "\u73B0\u5728\u6536\u8D77\u4FA7\u8FB9\u680F\u5E95\u90E8\u533A",
|
|
7022
|
-
checked: navFold.footerCollapsed,
|
|
7023
|
-
onChange: (next) => {
|
|
7024
|
-
void saveNavFold({ footerCollapsed: next });
|
|
7025
|
-
}
|
|
7026
|
-
}
|
|
7027
|
-
)
|
|
7011
|
+
desc: "\u8D26\u53F7\u884C\u4E0E\u63D2\u4EF6\u585E\u5728\u8FD9\u91CC\u7684\u5361\u7247\uFF08\u6BD4\u5982\u4ECA\u65E5\u6D88\u8017\u91D1\u989D\uFF09\uFF1B\u6253\u5F00\u65F6\u603B\u662F\u6536\u8D77\uFF0C\u70B9\u300C\u8D26\u53F7\u4E0E\u5176\u4ED6\u300D\u53EF\u4E34\u65F6\u5C55\u5F00",
|
|
7012
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { fontSize: 12, opacity: 0.75 }, children: navFold.footerCollapsed ? "\u6536\u8D77\u4E2D" : "\u5DF2\u4E34\u65F6\u5C55\u5F00\uFF08\u4EC5\u672C\u6B21\uFF09" })
|
|
7028
7013
|
}
|
|
7029
7014
|
)
|
|
7030
7015
|
]
|