@lihengxi20/dsh-tabs 0.1.0 → 0.1.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/README.md +3 -2
- package/lib/client.js +120 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,9 +20,10 @@ DSH(DeepSeek Harness)Web GUI 的**顶部会话标签页**插件:在会话
|
|
|
20
20
|
- **标签文案**:`工作区 / 会话标题`;工作区取侧边栏的工作区标题(缺省回退目录名),空白会话显示 `工作区 / 新会话`。
|
|
21
21
|
- **切换与关闭**:点击切换;悬停出现 `×`(单个标签也可关闭);中键点击关闭。关闭只移除标签,不归档、不停止任务;关闭最后一个标签会回到「未选中会话」的空白页。
|
|
22
22
|
- **右键菜单**:重命名 / 关闭 / 关闭其他 (n) / 全部关闭 (n);重命名走 Host 的 `session/rename`,空白会话禁用。
|
|
23
|
+
- **固定标签**:鼠标移入标签时,关闭按钮左侧出现图钉;点击可固定/取消固定。固定标签始终排在标签栏最左侧(按固定先后排列),刷新后保留;固定只影响显示顺序,不改变关闭语义。
|
|
23
24
|
- **状态圆点**:运行中(蓝/脉冲)、等待审批或回答(橙)、完成未读(绿)。
|
|
24
25
|
- **持久化**:标签顺序、活动标签、标题与工作区缓存存在浏览器 `localStorage`(键 `dsh-session-tabs.v1`),刷新/重开客户端后恢复。
|
|
25
|
-
-
|
|
26
|
+
- **跟随主题**:文字、边框、背景、右键菜单与重命名弹层全部使用 DSH 主题变量;标签文字浅色下纯黑、深色下纯白;激活标签下划线深色为暖金 `#E6CCA0`,浅色自动换成对比度更高的 `#A67C2E`。
|
|
26
27
|
|
|
27
28
|
标签是导航状态:DSH 同一时刻仍只渲染一个会话,后台任务照常运行。
|
|
28
29
|
|
|
@@ -36,7 +37,7 @@ DSH(DeepSeek Harness)Web GUI 的**顶部会话标签页**插件:在会话
|
|
|
36
37
|
通过 DSH 自带插件管理器添加:
|
|
37
38
|
|
|
38
39
|
```sh
|
|
39
|
-
# npm
|
|
40
|
+
# npm
|
|
40
41
|
dsh plugin --profile desktop add @lihengxi20/dsh-tabs
|
|
41
42
|
|
|
42
43
|
# 或直接从 GitHub 仓库安装(始终跟最新代码)
|
package/lib/client.js
CHANGED
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
"menu.close": "关闭",
|
|
60
60
|
"menu.closeOthers": "关闭其他",
|
|
61
61
|
"menu.closeAll": "全部关闭",
|
|
62
|
+
"pin": "固定标签",
|
|
63
|
+
"unpin": "取消固定标签",
|
|
62
64
|
"rename.title": "重命名会话",
|
|
63
65
|
"rename.placeholder": "输入会话标题",
|
|
64
66
|
"rename.cancel": "取消",
|
|
@@ -76,6 +78,8 @@
|
|
|
76
78
|
"menu.close": "Close",
|
|
77
79
|
"menu.closeOthers": "Close Others",
|
|
78
80
|
"menu.closeAll": "Close All",
|
|
81
|
+
"pin": "Pin tab",
|
|
82
|
+
"unpin": "Unpin tab",
|
|
79
83
|
"rename.title": "Rename session",
|
|
80
84
|
"rename.placeholder": "Session title",
|
|
81
85
|
"rename.cancel": "Cancel",
|
|
@@ -90,6 +94,7 @@
|
|
|
90
94
|
// ─────────────────────────────────────────────────────────────────────
|
|
91
95
|
var state = {
|
|
92
96
|
tabs: [], // session ids, opening order
|
|
97
|
+
pinned: [], // session ids, pinned order (shown first, left side)
|
|
93
98
|
titles: {}, // sessionId -> last known durable title
|
|
94
99
|
wsTitles: {}, // sessionId -> workspace display title
|
|
95
100
|
currentId: null, // the session the header is actually showing
|
|
@@ -119,7 +124,7 @@
|
|
|
119
124
|
var lastPersisted = null;
|
|
120
125
|
function persist() {
|
|
121
126
|
try {
|
|
122
|
-
var payload = JSON.stringify({ tabs: state.tabs, titles: state.titles, wsTitles: state.wsTitles, active: state.active });
|
|
127
|
+
var payload = JSON.stringify({ tabs: state.tabs, pinned: state.pinned, titles: state.titles, wsTitles: state.wsTitles, active: state.active });
|
|
123
128
|
if (payload === lastPersisted) return;
|
|
124
129
|
root.localStorage.setItem(LS_KEY, payload);
|
|
125
130
|
lastPersisted = payload;
|
|
@@ -149,8 +154,15 @@
|
|
|
149
154
|
if (typeof value === "string") wsTitles[id] = value;
|
|
150
155
|
});
|
|
151
156
|
}
|
|
157
|
+
var pinned = [];
|
|
158
|
+
if (Array.isArray(parsed.pinned)) {
|
|
159
|
+
parsed.pinned.forEach(function (id) {
|
|
160
|
+
if (typeof id === "string" && tabs.indexOf(id) >= 0 && pinned.indexOf(id) < 0) pinned.push(id);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
152
163
|
state = Object.assign({}, state, {
|
|
153
164
|
tabs: tabs,
|
|
165
|
+
pinned: pinned,
|
|
154
166
|
titles: titles,
|
|
155
167
|
wsTitles: wsTitles,
|
|
156
168
|
active: typeof parsed.active === "string" ? parsed.active : null
|
|
@@ -178,6 +190,29 @@
|
|
|
178
190
|
return "";
|
|
179
191
|
}
|
|
180
192
|
|
|
193
|
+
/** Visible tab order: pinned group (pin order) first, then unpinned tabs (open order). */
|
|
194
|
+
function displayOrder(tabs, pinned) {
|
|
195
|
+
var pinnedIds = [];
|
|
196
|
+
(pinned || []).forEach(function (id) {
|
|
197
|
+
if (tabs.indexOf(id) >= 0 && pinnedIds.indexOf(id) < 0) pinnedIds.push(id);
|
|
198
|
+
});
|
|
199
|
+
return pinnedIds.concat(tabs.filter(function (id) { return pinnedIds.indexOf(id) < 0; }));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Enforce MAX_TABS by trimming the oldest unpinned tabs; pinned tabs survive. */
|
|
203
|
+
function trimTabs(tabs) {
|
|
204
|
+
if (tabs.length <= MAX_TABS) return tabs;
|
|
205
|
+
var pinnedSet = {};
|
|
206
|
+
(state.pinned || []).forEach(function (id) { pinnedSet[id] = true; });
|
|
207
|
+
var out = tabs.slice();
|
|
208
|
+
var i = 0;
|
|
209
|
+
while (out.length > MAX_TABS && i < out.length) {
|
|
210
|
+
if (pinnedSet[out[i]] === true) i++;
|
|
211
|
+
else out.splice(i, 1);
|
|
212
|
+
}
|
|
213
|
+
return out.length > MAX_TABS ? out.slice(out.length - MAX_TABS) : out;
|
|
214
|
+
}
|
|
215
|
+
|
|
181
216
|
function syncFromList(list) {
|
|
182
217
|
if (!list) return;
|
|
183
218
|
var tabs = state.tabs.slice();
|
|
@@ -207,19 +242,22 @@
|
|
|
207
242
|
|
|
208
243
|
// Prune tabs whose session vanished (deleted / archived away / no
|
|
209
244
|
// longer catalogued). Never prune the currently open session.
|
|
245
|
+
var pinned = state.pinned.slice();
|
|
210
246
|
if (ready) {
|
|
211
247
|
var kept = tabs.filter(function (id) {
|
|
212
248
|
return id === current || Object.prototype.hasOwnProperty.call(byId, id);
|
|
213
249
|
});
|
|
214
250
|
if (kept.length !== tabs.length) { tabs = kept; changed = true; }
|
|
215
251
|
}
|
|
252
|
+
var validPinned = pinned.filter(function (id) { return tabs.indexOf(id) >= 0; });
|
|
253
|
+
if (validPinned.length !== pinned.length) { pinned = validPinned; changed = true; }
|
|
216
254
|
|
|
217
255
|
// Opening a session (sidebar / search / new session / tab click) adds
|
|
218
256
|
// it. The current session is always present, so even the first session
|
|
219
257
|
// of a fresh window gets exactly one tab.
|
|
220
258
|
if (current && tabs.indexOf(current) < 0 && !isSuppressed(current)) {
|
|
221
259
|
tabs.push(current);
|
|
222
|
-
|
|
260
|
+
tabs = trimTabs(tabs);
|
|
223
261
|
changed = true;
|
|
224
262
|
}
|
|
225
263
|
|
|
@@ -229,6 +267,7 @@
|
|
|
229
267
|
state = Object.assign({}, state, {
|
|
230
268
|
list: list,
|
|
231
269
|
tabs: tabs,
|
|
270
|
+
pinned: pinned,
|
|
232
271
|
titles: titles,
|
|
233
272
|
active: active,
|
|
234
273
|
ready: state.ready || ready
|
|
@@ -293,7 +332,7 @@
|
|
|
293
332
|
var titles = Object.assign({}, state.titles);
|
|
294
333
|
if (id && tabs.indexOf(id) < 0 && !isSuppressed(id)) {
|
|
295
334
|
tabs.push(id);
|
|
296
|
-
|
|
335
|
+
tabs = trimTabs(tabs);
|
|
297
336
|
}
|
|
298
337
|
state = Object.assign({}, state, {
|
|
299
338
|
currentId: id,
|
|
@@ -354,10 +393,15 @@
|
|
|
354
393
|
tabs.splice(idx, 1);
|
|
355
394
|
var titles = Object.assign({}, state.titles);
|
|
356
395
|
delete titles[id];
|
|
396
|
+
var pinned = state.pinned.filter(function (pid) { return pid !== id; });
|
|
357
397
|
var wasCurrent = (state.currentId || currentSessionId(state.list)) === id;
|
|
358
|
-
var
|
|
398
|
+
var order = displayOrder(state.tabs, state.pinned);
|
|
399
|
+
var orderIdx = order.indexOf(id);
|
|
400
|
+
var remaining = order.filter(function (tid) { return tid !== id; });
|
|
401
|
+
var nextActive = remaining[Math.min(Math.max(orderIdx, 0), remaining.length - 1)] || null;
|
|
359
402
|
state = Object.assign({}, state, {
|
|
360
403
|
tabs: tabs,
|
|
404
|
+
pinned: pinned,
|
|
361
405
|
titles: titles,
|
|
362
406
|
active: nextActive,
|
|
363
407
|
closed: { id: id, at: Date.now() }
|
|
@@ -372,8 +416,10 @@
|
|
|
372
416
|
openSession(ctx, keepId);
|
|
373
417
|
var titles = {};
|
|
374
418
|
if (state.titles[keepId]) titles[keepId] = state.titles[keepId];
|
|
419
|
+
var pinned = state.pinned.indexOf(keepId) >= 0 ? [keepId] : [];
|
|
375
420
|
state = Object.assign({}, state, {
|
|
376
421
|
tabs: [keepId],
|
|
422
|
+
pinned: pinned,
|
|
377
423
|
titles: titles,
|
|
378
424
|
active: keepId,
|
|
379
425
|
currentId: keepId,
|
|
@@ -387,6 +433,7 @@
|
|
|
387
433
|
if (state.tabs.length === 0) return;
|
|
388
434
|
state = Object.assign({}, state, {
|
|
389
435
|
tabs: [],
|
|
436
|
+
pinned: [],
|
|
390
437
|
titles: {},
|
|
391
438
|
active: null,
|
|
392
439
|
currentId: null,
|
|
@@ -405,6 +452,17 @@
|
|
|
405
452
|
}
|
|
406
453
|
}
|
|
407
454
|
|
|
455
|
+
function togglePin(ctx, id) {
|
|
456
|
+
if (state.tabs.indexOf(id) < 0) return;
|
|
457
|
+
var pinned = state.pinned.slice();
|
|
458
|
+
var idx = pinned.indexOf(id);
|
|
459
|
+
if (idx >= 0) pinned.splice(idx, 1);
|
|
460
|
+
else pinned.push(id);
|
|
461
|
+
state = Object.assign({}, state, { pinned: pinned });
|
|
462
|
+
persist();
|
|
463
|
+
emit();
|
|
464
|
+
}
|
|
465
|
+
|
|
408
466
|
function renameSession(ctx, id, title) {
|
|
409
467
|
var sessions = null;
|
|
410
468
|
try { sessions = ctx.get("sessions"); } catch (e) { sessions = null; }
|
|
@@ -441,6 +499,16 @@
|
|
|
441
499
|
}));
|
|
442
500
|
}
|
|
443
501
|
|
|
502
|
+
function PinIcon(pinned) {
|
|
503
|
+
return h("svg", {
|
|
504
|
+
width: 11, height: 11, viewBox: "0 0 24 24", fill: pinned ? "currentColor" : "none",
|
|
505
|
+
"aria-hidden": "true"
|
|
506
|
+
}, h("path", {
|
|
507
|
+
d: "M12 17v5M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z",
|
|
508
|
+
stroke: "currentColor", strokeWidth: 1.6, strokeLinejoin: "round", strokeLinecap: "round"
|
|
509
|
+
}));
|
|
510
|
+
}
|
|
511
|
+
|
|
444
512
|
// ─────────────────────────────────────────────────────────────────────
|
|
445
513
|
// components
|
|
446
514
|
// ─────────────────────────────────────────────────────────────────────
|
|
@@ -480,6 +548,9 @@
|
|
|
480
548
|
event.stopPropagation();
|
|
481
549
|
closeTab(props.ctx, props.id);
|
|
482
550
|
},
|
|
551
|
+
onAuxClick: function (event) {
|
|
552
|
+
event.stopPropagation();
|
|
553
|
+
},
|
|
483
554
|
onContextMenu: function (event) {
|
|
484
555
|
event.preventDefault();
|
|
485
556
|
event.stopPropagation();
|
|
@@ -487,6 +558,30 @@
|
|
|
487
558
|
}, CloseIcon());
|
|
488
559
|
}
|
|
489
560
|
|
|
561
|
+
function PinButton(props) {
|
|
562
|
+
var pinned = props.pinned === true;
|
|
563
|
+
var label = props.t(pinned ? "unpin" : "pin");
|
|
564
|
+
return h("button", {
|
|
565
|
+
type: "button",
|
|
566
|
+
className: "dshst-pin",
|
|
567
|
+
title: label,
|
|
568
|
+
"aria-label": label,
|
|
569
|
+
"aria-pressed": pinned ? "true" : "false",
|
|
570
|
+
"data-pinned": pinned ? "true" : "false",
|
|
571
|
+
onClick: function (event) {
|
|
572
|
+
event.stopPropagation();
|
|
573
|
+
togglePin(props.ctx, props.id);
|
|
574
|
+
},
|
|
575
|
+
onAuxClick: function (event) {
|
|
576
|
+
event.stopPropagation();
|
|
577
|
+
},
|
|
578
|
+
onContextMenu: function (event) {
|
|
579
|
+
event.preventDefault();
|
|
580
|
+
event.stopPropagation();
|
|
581
|
+
}
|
|
582
|
+
}, PinIcon(pinned));
|
|
583
|
+
}
|
|
584
|
+
|
|
490
585
|
function useMenuPosition(x, y, width, height) {
|
|
491
586
|
var ref = React.useRef(null);
|
|
492
587
|
var posState = React.useState({ x: x, y: y });
|
|
@@ -721,6 +816,8 @@
|
|
|
721
816
|
var store = props.store;
|
|
722
817
|
var list = store.list || { byId: {} };
|
|
723
818
|
var tabs = store.tabs || [];
|
|
819
|
+
var pinned = store.pinned || [];
|
|
820
|
+
var displayTabs = displayOrder(tabs, pinned);
|
|
724
821
|
var ctx = props.ctx;
|
|
725
822
|
var t = props.t;
|
|
726
823
|
var current = store.currentId || currentSessionId(list) || store.active;
|
|
@@ -743,7 +840,7 @@
|
|
|
743
840
|
className: "dshst-tabs",
|
|
744
841
|
role: "tablist",
|
|
745
842
|
"aria-label": t("tabs.aria")
|
|
746
|
-
},
|
|
843
|
+
}, displayTabs.map(function (id) {
|
|
747
844
|
var row = list.byId ? list.byId[id] : undefined;
|
|
748
845
|
var label;
|
|
749
846
|
if (row && row.blank) label = t("newSession");
|
|
@@ -752,6 +849,7 @@
|
|
|
752
849
|
else label = t("untitled");
|
|
753
850
|
var workspace = workspaceTitleFor(store, id, row);
|
|
754
851
|
var active = id === current;
|
|
852
|
+
var isPinned = pinned.indexOf(id) >= 0;
|
|
755
853
|
var status = row ? statusOf(store, row) : "idle";
|
|
756
854
|
var title = (workspace ? workspace + " / " : "") + label + (row && row.cwd ? "\n" + row.cwd : "");
|
|
757
855
|
return h("div", {
|
|
@@ -761,6 +859,7 @@
|
|
|
761
859
|
tabIndex: active ? 0 : -1,
|
|
762
860
|
"aria-selected": active ? "true" : "false",
|
|
763
861
|
"data-active": active ? "true" : "false",
|
|
862
|
+
"data-pinned": isPinned ? "true" : "false",
|
|
764
863
|
"data-status": status,
|
|
765
864
|
"data-session-id": id,
|
|
766
865
|
"data-menu-target": menu !== null && menu.id === id ? "true" : "false",
|
|
@@ -785,6 +884,7 @@
|
|
|
785
884
|
? h("span", { className: "dshst-sep", "aria-hidden": "true" }, "/")
|
|
786
885
|
: null,
|
|
787
886
|
h("span", { className: "dshst-label" }, label),
|
|
887
|
+
h(PinButton, { ctx: ctx, id: id, t: t, pinned: isPinned }),
|
|
788
888
|
h(CloseButton, { ctx: ctx, id: id, t: t })
|
|
789
889
|
);
|
|
790
890
|
}));
|
|
@@ -917,20 +1017,22 @@
|
|
|
917
1017
|
// styles
|
|
918
1018
|
// ─────────────────────────────────────────────────────────────────────
|
|
919
1019
|
var CSS = [
|
|
1020
|
+
"body{--dshst-tab-accent:#a67c2e;--dshst-tab-text:#000;--dshst-tab-text-hover:#000}",
|
|
1021
|
+
"body[data-ds-dark-theme]{--dshst-tab-accent:#e6cca0;--dshst-tab-text:#fff;--dshst-tab-text-hover:#fff}",
|
|
920
1022
|
".dshst-leading{display:inline-flex;align-items:center;gap:6px;min-width:0;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:20px;-webkit-app-region:no-drag}",
|
|
921
1023
|
".dshst-icon{flex:none;opacity:.9}",
|
|
922
1024
|
".dshst-ws{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
|
|
923
1025
|
".dshst-leading .dshst-ws{max-width:180px}",
|
|
924
1026
|
".dshst-sep{color:var(--dsw-alias-label-caption);flex:none}",
|
|
925
|
-
".dshst-row{
|
|
1027
|
+
".dshst-row{grid-column:1/-1;min-width:0;padding-left:8px;margin-top:0;display:flex;align-items:flex-start;-webkit-app-region:no-drag}",
|
|
926
1028
|
"header:has(> [data-dsh-session-tabs]){padding-bottom:0}",
|
|
927
1029
|
".dshst-tabs{display:flex;align-items:center;gap:0;min-width:0;width:100%;overflow-x:auto;scrollbar-width:none;padding:0}",
|
|
928
1030
|
".dshst-tabs::-webkit-scrollbar{display:none}",
|
|
929
|
-
".dshst-tab{display:inline-flex;align-items:center;gap:6px;flex:none;max-width:300px;min-width:0;min-height:24px;padding:4px 10px 7px;border:0;border-radius:6px;background:transparent;color:var(--
|
|
1031
|
+
".dshst-tab{display:inline-flex;align-items:center;gap:6px;flex:none;max-width:300px;min-width:0;min-height:24px;padding:4px 10px 7px;border:0;border-radius:6px;background:transparent;color:var(--dshst-tab-text);font:inherit;font-size:13px;font-weight:500;line-height:16px;cursor:pointer;position:relative;-webkit-app-region:no-drag}",
|
|
930
1032
|
".dshst-tab:before{content:\"\";position:absolute;inset:0;border:1px solid transparent;border-bottom:0;border-radius:6px 6px 0 0;pointer-events:none}",
|
|
931
|
-
".dshst-tab .dshst-ws{max-width:110px;flex:none;color:var(--
|
|
932
|
-
".dshst-tab .dshst-sep{font-size:12px;opacity:.
|
|
933
|
-
"@media (hover:hover){.dshst-tab:hover{color:var(--
|
|
1033
|
+
".dshst-tab .dshst-ws{max-width:110px;flex:none;color:var(--dshst-tab-text);opacity:.65;font-size:12px;font-weight:500;line-height:16px}",
|
|
1034
|
+
".dshst-tab .dshst-sep{color:var(--dshst-tab-text);font-size:12px;opacity:.6}",
|
|
1035
|
+
"@media (hover:hover){.dshst-tab:hover{color:var(--dshst-tab-text-hover)}.dshst-tab:hover:before{border-color:var(--dsw-alias-border-l3)}}",
|
|
934
1036
|
".dshst-tab:focus-visible:before{border-color:var(--dsw-alias-border-l3)}",
|
|
935
1037
|
".dshst-tab[data-active=\"true\"]{color:var(--dsw-alias-state-business-primary)}",
|
|
936
1038
|
".dshst-tab[data-active=\"true\"]:before{border-color:var(--dsw-alias-border-l4)}",
|
|
@@ -945,15 +1047,18 @@
|
|
|
945
1047
|
".dshst-close{display:inline-flex;align-items:center;justify-content:center;flex:none;width:14px;height:14px;margin-left:2px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;opacity:0}",
|
|
946
1048
|
".dshst-tab:hover .dshst-close,.dshst-tab:focus-within .dshst-close{opacity:1}",
|
|
947
1049
|
"@media (hover:hover){.dshst-close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}}",
|
|
1050
|
+
".dshst-pin{display:inline-flex;align-items:center;justify-content:center;flex:none;width:14px;height:14px;margin-left:2px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;opacity:0}",
|
|
1051
|
+
".dshst-tab:hover .dshst-pin,.dshst-tab:focus-within .dshst-pin{opacity:1}",
|
|
1052
|
+
".dshst-tab[data-pinned=\"true\"] .dshst-pin{opacity:1;color:var(--dsw-alias-label-secondary)}",
|
|
1053
|
+
"@media (hover:hover){.dshst-pin:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.dshst-tab[data-pinned=\"true\"] .dshst-pin:hover{color:var(--dshst-tab-text)}}",
|
|
948
1054
|
"@media (prefers-reduced-motion:reduce){.dshst-tab[data-status=\"running\"] .dshst-dot{animation:none}}",
|
|
949
1055
|
".dshst-tab[data-menu-target=\"true\"]{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
950
|
-
".dshst-menu{position:fixed;z-index:1200;min-width:180px;box-sizing:border-box;padding:4px;border-radius:
|
|
951
|
-
".dshst-menu-item{display:flex;align-items:center;justify-content:space-between;gap:18px;height:
|
|
1056
|
+
".dshst-menu{position:fixed;z-index:1200;min-width:180px;box-sizing:border-box;padding:4px;border:0;border-radius:var(--dsw-radius-lg);background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);outline:none;-webkit-app-region:no-drag}",
|
|
1057
|
+
".dshst-menu-item{display:flex;align-items:center;justify-content:space-between;gap:18px;min-height:34px;padding:6px 10px;border-radius:var(--dsw-radius-md);color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px;cursor:pointer;white-space:nowrap;user-select:none}",
|
|
952
1058
|
".dshst-menu-item[data-hovered=\"true\"]{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
953
|
-
".dshst-menu-item[data-disabled=\"true\"]{
|
|
1059
|
+
".dshst-menu-item[data-disabled=\"true\"]{opacity:.4;cursor:default;background:transparent}",
|
|
954
1060
|
".dshst-menu-count{color:var(--dsw-alias-label-caption);font-size:12px;font-variant-numeric:tabular-nums}",
|
|
955
|
-
".dshst-
|
|
956
|
-
".dshst-rename{position:fixed;z-index:1201;width:280px;box-sizing:border-box;padding:12px;border-radius:10px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);box-shadow:0 12px 32px rgba(0,0,0,.4);-webkit-app-region:no-drag}",
|
|
1061
|
+
".dshst-rename{position:fixed;z-index:1201;width:280px;box-sizing:border-box;padding:14px;border:0;border-radius:var(--dsw-radius-lg);background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);-webkit-app-region:no-drag}",
|
|
957
1062
|
".dshst-rename-title{margin-bottom:8px;color:var(--dsw-alias-label-caption);font-size:12px;line-height:16px}",
|
|
958
1063
|
".dshst-rename-input{width:100%;box-sizing:border-box;height:32px;padding:0 9px;border:1px solid var(--dsw-alias-border-l3);border-radius:6px;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;outline:none}",
|
|
959
1064
|
".dshst-rename-input:focus{border-color:var(--dsw-alias-state-business-primary)}",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lihengxi20/dsh-tabs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Session tabs in the DSH conversation header: switch, close, rename and persist open sessions, with workspace/title labels and live status.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|