dsh-composer-ux 0.29.0 → 0.29.2
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 +46 -0
- package/README.md +5 -2
- package/dsh-plugin.json +1 -1
- package/lib/client.js +48 -39
- package/lib/client.js.map +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.29.2] — 2026-10-29(展开时把「账号与其他 ▴」缩进到账号行右端)
|
|
6
|
+
|
|
7
|
+
用户 2026-10-29(截图圈住「方文」右侧的空白):「这个展开时,把这个账号和其他和收缩按钮放到这个位置」。
|
|
8
|
+
|
|
9
|
+
**改了什么**
|
|
10
|
+
|
|
11
|
+
- **展开态**:那行「账号与其他 ▴」不再单独占一整行,缩进到账号那一块(`settingsArea`)的**右端**,
|
|
12
|
+
绝对定位、不占布局高度 —— 也就是你框的那个空白位置。
|
|
13
|
+
- **收起态**:仍是底部容器前面那一整条「账号与其他 ▾」(这时账号行被一起藏了,没有别的落脚点)。
|
|
14
|
+
|
|
15
|
+
**实现**:同一个按钮在两种状态下换父节点(收起 → 容器前面的兄弟节点;展开 → 账号块内的绝对定位),
|
|
16
|
+
只动我们自己那一个按钮的 parent/属性;账号块只加一个 `position: relative`(做包含块),
|
|
17
|
+
宿主与别的插件的节点照旧一个不碰。
|
|
18
|
+
|
|
19
|
+
**顺手修了测试桩的一个失真**:桩的 `appendChild/insertBefore` 之前不会把节点从旧父节点摘下来
|
|
20
|
+
(真 DOM 会),于是"移动按钮"这件事在测试里会变成两个按钮。桩已按真实语义修正。
|
|
21
|
+
|
|
22
|
+
**测试**:`test/sidebar-footer.mjs` 新增第 6 节(9 条);变异新增 TE(展开时还在老位置占一行)。
|
|
23
|
+
|
|
24
|
+
## [0.29.1] — 2026-10-29(「账号与其他」+ 收起状态不再记忆:打开就收起)
|
|
25
|
+
|
|
26
|
+
用户 2026-10-29 两条:
|
|
27
|
+
|
|
28
|
+
1. 「账号与用量改为账号与其他」;
|
|
29
|
+
2. 「收起与否改为默认收起」—— 追问后选定**改行为**:每次打开 DSH 都强制收起、**不记住展开**,
|
|
30
|
+
两处(顶部「全局面板」+ 底部区)一起。
|
|
31
|
+
|
|
32
|
+
**行为变了(这条最容易察觉)**
|
|
33
|
+
|
|
34
|
+
- 以前:点开折叠条 → 状态写进 `composer-ux-nav-fold.json` → 下次打开还是展开的。
|
|
35
|
+
- 现在:点开只在**本次会话**有效;重开 DSH 一律回到收起。
|
|
36
|
+
文件里只留**形态**(`mode`:收成一条 / 只留图标 / 不折叠);老文件里的 `collapsed: false`
|
|
37
|
+
会被**忽略**,不会把"上次点开过"带过来。
|
|
38
|
+
|
|
39
|
+
**界面上的连带改动**
|
|
40
|
+
|
|
41
|
+
- 底部细条文字:`账号与用量` → **`账号与其他`**(连带 title「展开/收起账号与其他」)。
|
|
42
|
+
- 设置页「侧边栏」组:两个"现在收起"开关删掉(一个不落盘的开关是骗人的),
|
|
43
|
+
换成一行状态说明「打开时:总是收起(不记住展开):点折叠条可临时展开」+ 当前是收起/临时展开。
|
|
44
|
+
|
|
45
|
+
**为什么拆了个新文件**:把纯状态(`NavFoldState` / `sanitizeNavFold` / `persistableNavFold`)从
|
|
46
|
+
`nav-fold-store.ts` 挪到 `nav-fold-state.ts` —— store 里带 React hook,测试要 bundle 它就得拉 react;
|
|
47
|
+
拆开之后"强制收起"和"只有形态落盘"这两条能像其它纯函数一样逐条钉住。
|
|
48
|
+
|
|
49
|
+
**测试**:`test/sidebar-nav.mjs` 新增第 7 节(6 条);变异新增 TC / TD(又记住展开 / 收起状态被写盘)。
|
|
50
|
+
|
|
5
51
|
## [0.29.0] — 2026-10-29(侧边栏**底部区**也能收:整块收成一行「账号与用量」)
|
|
6
52
|
|
|
7
53
|
用户 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 # 手动跑:变异测试,证明那套护栏真的在咬人(206 条,须单独跑)
|
|
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,8 @@ 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
|
|
2948
|
+
var FOOTER_HEAD_INLINE_ATTR = "data-ux-footer-inline";
|
|
2949
|
+
var FOOTER_HEAD_TEXT = "\u8D26\u53F7\u4E0E\u5176\u4ED6";
|
|
2944
2950
|
var ACCOUNT_LABELS = ["\u8D26\u53F7\u83DC\u5355", "Account menu", "\u8D26\u6237\u83DC\u5355"];
|
|
2945
2951
|
var FOOTER_FOLD_CSS = `
|
|
2946
2952
|
[${FOOTER_FOLD_ATTR}='folded'] { display: none !important; }
|
|
@@ -2961,6 +2967,17 @@ var FOOTER_FOLD_CSS = `
|
|
|
2961
2967
|
cursor: pointer;
|
|
2962
2968
|
}
|
|
2963
2969
|
[${FOOTER_HEAD_ATTR}]:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-secondary); }
|
|
2970
|
+
/* \u5C55\u5F00\u6001\uFF1A\u8D34\u5728\u8D26\u53F7\u90A3\u4E00\u884C\u7684\u53F3\u7AEF\uFF0C\u4E0D\u5360\u5E03\u5C40\u9AD8\u5EA6\uFF08\u7EDD\u5BF9\u5B9A\u4F4D\u5728\u8D26\u53F7\u5757\u91CC\uFF09\u3002 */
|
|
2971
|
+
[${FOOTER_HEAD_ATTR}][${FOOTER_HEAD_INLINE_ATTR}] {
|
|
2972
|
+
position: absolute;
|
|
2973
|
+
right: 6px;
|
|
2974
|
+
top: 50%;
|
|
2975
|
+
transform: translateY(-50%);
|
|
2976
|
+
width: auto;
|
|
2977
|
+
max-width: 55%;
|
|
2978
|
+
padding: 2px 6px;
|
|
2979
|
+
z-index: 1;
|
|
2980
|
+
}
|
|
2964
2981
|
[${FOOTER_HEAD_ATTR}]:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: -2px; }
|
|
2965
2982
|
[${FOOTER_HEAD_ATTR}] > span[data-ux-footer-fold-chevron] { margin-left: auto; opacity: .7; }
|
|
2966
2983
|
`;
|
|
@@ -2996,11 +3013,23 @@ function ensureHeader2(doc, footer, state3, onToggle) {
|
|
|
2996
3013
|
head = doc.createElement("button");
|
|
2997
3014
|
head.type = "button";
|
|
2998
3015
|
head.setAttribute(FOOTER_HEAD_ATTR, "");
|
|
2999
|
-
|
|
3016
|
+
}
|
|
3017
|
+
const accountArea = footer.lastElementChild;
|
|
3018
|
+
const inline = !state3.collapsed && accountArea !== null;
|
|
3019
|
+
const parent = inline ? accountArea : footer.parentElement;
|
|
3020
|
+
if (parent !== null && head.parentElement !== parent) {
|
|
3021
|
+
if (inline) parent.appendChild(head);
|
|
3022
|
+
else parent.insertBefore(head, footer);
|
|
3023
|
+
}
|
|
3024
|
+
if (inline && accountArea !== null) {
|
|
3025
|
+
if (accountArea.style.position !== "relative") accountArea.style.position = "relative";
|
|
3026
|
+
if (!head.hasAttribute(FOOTER_HEAD_INLINE_ATTR)) head.setAttribute(FOOTER_HEAD_INLINE_ATTR, "");
|
|
3027
|
+
} else if (head.hasAttribute(FOOTER_HEAD_INLINE_ATTR)) {
|
|
3028
|
+
head.removeAttribute(FOOTER_HEAD_INLINE_ATTR);
|
|
3000
3029
|
}
|
|
3001
3030
|
const open = !state3.collapsed;
|
|
3002
3031
|
head.setAttribute("aria-expanded", open ? "true" : "false");
|
|
3003
|
-
head.setAttribute("title", open ? "\u6536\u8D77\u8D26\u53F7\u4E0E\
|
|
3032
|
+
head.setAttribute("title", open ? "\u6536\u8D77\u8D26\u53F7\u4E0E\u5176\u4ED6" : "\u5C55\u5F00\u8D26\u53F7\u4E0E\u5176\u4ED6");
|
|
3004
3033
|
head.textContent = "";
|
|
3005
3034
|
const label = doc.createElement("span");
|
|
3006
3035
|
label.textContent = FOOTER_HEAD_TEXT;
|
|
@@ -6993,38 +7022,18 @@ function SettingsSection({ useLive, useBook, useBookStatus, useWriteNotice, acti
|
|
|
6993
7022
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6994
7023
|
Row,
|
|
6995
7024
|
{
|
|
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
|
-
)
|
|
7025
|
+
title: "\u6253\u5F00\u65F6",
|
|
7026
|
+
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",
|
|
7027
|
+
first: false,
|
|
7028
|
+
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
7029
|
}
|
|
7011
7030
|
),
|
|
7012
7031
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7013
7032
|
Row,
|
|
7014
7033
|
{
|
|
7015
7034
|
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
|
-
)
|
|
7035
|
+
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",
|
|
7036
|
+
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
7037
|
}
|
|
7029
7038
|
)
|
|
7030
7039
|
]
|