@deepseek-ai/dsh-client-ui-sidebar 0.1.6-alpha.1 → 0.1.7-alpha.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/README.i18n.yaml +2 -2
- package/README.md +8 -0
- package/README.zh.md +8 -0
- package/lib/client.js +118 -31
- package/lib/types/client/HeaderLeadingControls.d.ts +15 -0
- package/lib/types/client/contract/slots.d.ts +7 -1
- package/package.json +13 -13
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-sidebar/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 94bb3a70ca8c06b5838f41436bb0f2ba2751501e
|
|
6
|
+
README.zh.md: 86f54882ba1c96b9b50898993931757f7afef4e5
|
package/README.md
CHANGED
|
@@ -37,8 +37,16 @@ Plugins add an icon component to the root-scoped `sidebar.panellist` list with a
|
|
|
37
37
|
|
|
38
38
|
### Collapse behavior
|
|
39
39
|
|
|
40
|
+
The top expand button hosts the optional, non-interactive `sidebar.toggle.badge` slot while collapsed. Its occupant supplies status and tooltip content without adding another action or changing the button's navigation behavior.
|
|
41
|
+
|
|
40
42
|
During a live collapse, the expanded content fades out at its current width, the upper controls share one fade and leftward translation into the 56px rail, and the layout's column slide ends the motion. A page that starts collapsed renders the rail statically, and reduced-motion mode disables both transitions. The bottom-pinned `sidebar.settings` control shares the fade timing but has no horizontal translation.
|
|
41
43
|
|
|
44
|
+
On Windows Electron, `html[data-windows-titlebar]` fixes the sidebar toggle in the caption's top-left corner in both states, aligned with New Session's left edge only when expanded. The expanded brand sits below the caption and above New Session, with 8px of extra space above that button. Collapsing hides the brand and sidebar content and places New Session between the sidebar toggle and the Desktop-owned menus. The sidebar sets the root `--dsh-windows-menu-start` to 84px when collapsed; the Desktop preload uses it to position its menu after New Session and defaults to 48px when expanded. Caption icon buttons use centered 16px glyphs in 28px circular controls and exclude themselves from the window drag region. The sidebar toggle and New Session bubbles open below the caption, where the Desktop-owned menu text cannot cover them; an occupying `sidebar.toggle.badge` chooses its own bubble side.
|
|
45
|
+
|
|
46
|
+
### macOS desktop
|
|
47
|
+
|
|
48
|
+
Under `html[data-platform='darwin']` (set only by the desktop preload) the expanded column opens with a 52px top strip that clears the hiddenInset traffic lights and carries the collapse toggle; the frame's own drag band (ui-layout `.leadingBand`) covers that strip, and the logo row below extends the drag surface, so the brand wordmark is not a New Session shortcut there — the dedicated New Session button keeps the action — and collapsing hides the column entirely instead of leaving the rail. The package registers `HeaderLeadingControls` into the frame's `shell.leading` window-chrome seat (ui-layout), which mounts it — the open-sidebar and New Session controls beside the traffic lights — only while the column is hidden, over every main panel. Rationale and the window-integration contract: the [macOS hidden-titlebar Agent Note](../../../.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md).
|
|
49
|
+
|
|
42
50
|
### Scrollbars
|
|
43
51
|
|
|
44
52
|
Scrollbars in the column are a pointer affordance: the shell rebinds the scrollbar indirection to `transparent` whenever the pointer is outside the column and keeps the thumb drawn for 2s after the pointer leaves, so a list nobody is pointing at carries no bar. The reservation that keeps rows from moving belongs to the scrolling region (ui-workspace), so revealing a thumb never reflows.
|
package/README.zh.md
CHANGED
|
@@ -37,8 +37,16 @@ dsh Web 客户端的侧边栏让用户识别当前构建、启动新会话、将
|
|
|
37
37
|
|
|
38
38
|
### 折叠行为
|
|
39
39
|
|
|
40
|
+
侧栏收起时,顶部展开按钮承载可选、不可交互的 `sidebar.toggle.badge` slot。占用方提供状态和提示内容,不增加操作,也不改变按钮的导航行为。
|
|
41
|
+
|
|
40
42
|
实时收起时,展开内容在当前宽度淡出,上方控件共用同一段透明度渐变,并向左平移进入 56px 轨道,由布局的栏滑动结束整段动画。页面初始即为收起状态时会静态渲染轨道;减少动态效果模式会禁用两段过渡。固定在底部的 `sidebar.settings` 控件共用相同的透明度渐变时序,但不发生横向位移。
|
|
41
43
|
|
|
44
|
+
在 Windows Electron 中,`html[data-windows-titlebar]` 将两种状态下的侧栏开关固定在顶栏左上角,仅在展开态与新建会话按钮左边缘对齐。展开态品牌位于顶栏下方、新建会话按钮上方,按钮上方额外留出 8px。收起后,品牌和侧栏内容隐藏,新建会话按钮排在侧栏开关与 Desktop 菜单之间。侧栏在收起态将根元素的 `--dsh-windows-menu-start` 设为 84px;Desktop preload 使用它将菜单放在新建会话之后,展开态默认为 48px。顶栏图标按钮采用 28px 圆形控件中的居中 16px 图标,并从窗口拖拽区域中排除。侧栏开关与新建会话的悬停提示在顶栏下方展开,Desktop 菜单文字不会盖住它们;占用 `sidebar.toggle.badge` 的控件自行决定气泡展开方向。
|
|
45
|
+
|
|
46
|
+
### macOS 桌面
|
|
47
|
+
|
|
48
|
+
在 `html[data-platform='darwin']`(仅由桌面 preload 设置)下,展开的侧边栏列顶部有一条 52px 的顶部条:避开 hiddenInset 红绿灯并承载收起按钮;框架自身的拖拽带(ui-layout `.leadingBand`)覆盖这条顶部条,其下的 logo 行延伸这块拖拽面,因此品牌 wordmark 在 macOS 上不再是 New Session 快捷入口——专用的 New Session 按钮保留该操作;收起时整列隐藏而非保留轨道。本包向框架的 `shell.leading` 窗口 chrome 座(ui-layout)注册 `HeaderLeadingControls`——打开侧边栏与 New Session 两个控件,由框架仅在列隐藏时挂载于红绿灯旁,覆盖所有主面板。设计依据与窗口集成约定见 [macOS 隐藏标题栏 Agent Note](../../../.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.zh.md)。
|
|
49
|
+
|
|
42
50
|
### 滚动条
|
|
43
51
|
|
|
44
52
|
栏内的滚动条是一种指针可供性:只要指针不在栏内,外壳就把滚动条间接层重新绑定为 `transparent`;指针离开后滑块再保留 2 秒,因此没人指向的列表不会带着滚动条。避免行位移的空间预留属于滚动区域本身(ui-workspace),所以显示滑块不会引起重排。
|
package/lib/client.js
CHANGED
|
@@ -7,8 +7,65 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
8
8
|
let _deepseek_ai_dsh_client_ui_slots = require("@deepseek-ai/dsh-client-ui-slots");
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
-
let react = require("react");
|
|
11
10
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
11
|
+
let react = require("react");
|
|
12
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar/src/client/HeaderLeadingControls.module.css.mjs
|
|
13
|
+
const css$1 = ".IW6AQa_controls{align-items:center;gap:8px;display:flex}.IW6AQa_iconButton{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.IW6AQa_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}";
|
|
14
|
+
const tagId$1 = "@deepseek-ai/dsh-client-ui-sidebar/HeaderLeadingControls.module.css";
|
|
15
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
16
|
+
const tag = document.createElement("style");
|
|
17
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-sidebar";
|
|
18
|
+
tag.dataset.pluginCss = tagId$1;
|
|
19
|
+
tag.textContent = css$1;
|
|
20
|
+
document.head.appendChild(tag);
|
|
21
|
+
}
|
|
22
|
+
var HeaderLeadingControls_module_css_default = {
|
|
23
|
+
"controls": "IW6AQa_controls",
|
|
24
|
+
"iconButton": "IW6AQa_iconButton"
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region lib/types/client/HeaderLeadingControls.js
|
|
28
|
+
/** Window-chrome controls for the fully hidden sidebar (frame shell.leading seat). */
|
|
29
|
+
/**
|
|
30
|
+
* Sidebar-open and New Session controls in the frame's window-chrome seat.
|
|
31
|
+
* On macOS desktop a collapsed sidebar hides entirely (no rail), taking both
|
|
32
|
+
* controls off screen; this occupant puts them back beside the traffic
|
|
33
|
+
* lights. The frame mounts the seat only in that state and owns its
|
|
34
|
+
* placement, so the occupant renders unconditionally.
|
|
35
|
+
* @param props - Injected sidebar actions plus the sidebar locale seat.
|
|
36
|
+
* @returns the two window-chrome controls.
|
|
37
|
+
*/
|
|
38
|
+
function HeaderLeadingControls({ toggleSidebar, startSession, t }) {
|
|
39
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
40
|
+
className: HeaderLeadingControls_module_css_default.controls,
|
|
41
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
42
|
+
label: t("toggle.open"),
|
|
43
|
+
delayMs: 500,
|
|
44
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
45
|
+
type: "button",
|
|
46
|
+
className: HeaderLeadingControls_module_css_default.iconButton,
|
|
47
|
+
"aria-label": t("toggle.open"),
|
|
48
|
+
onClick: () => {
|
|
49
|
+
toggleSidebar();
|
|
50
|
+
},
|
|
51
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutlineRegular, { size: 16 })
|
|
52
|
+
})
|
|
53
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
54
|
+
label: t("session.new.label"),
|
|
55
|
+
delayMs: 500,
|
|
56
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
57
|
+
type: "button",
|
|
58
|
+
className: HeaderLeadingControls_module_css_default.iconButton,
|
|
59
|
+
"aria-label": t("session.new.label"),
|
|
60
|
+
onClick: () => {
|
|
61
|
+
startSession();
|
|
62
|
+
},
|
|
63
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutlineRegular, { size: 16 })
|
|
64
|
+
})
|
|
65
|
+
})]
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
12
69
|
//#region ../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
13
70
|
function r(e) {
|
|
14
71
|
var t, f, n = "";
|
|
@@ -25,7 +82,7 @@ window.__ModuleLoader__.load({
|
|
|
25
82
|
}
|
|
26
83
|
//#endregion
|
|
27
84
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar/src/client/SidebarRoot.module.css.mjs
|
|
28
|
-
const css = ".hHd-Xa_root{--dsh-sidebar-inline-padding:12px;height:100%;padding:6px var(--dsh-sidebar-inline-padding);box-sizing:border-box;background:var(--dsw-specific-sidebar-fill);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);flex-direction:column;font-size:14px;display:flex}.hHd-Xa_root.hHd-Xa_collapsed{padding:18px 10px 6px}.hHd-Xa_root.hHd-Xa_quietBars{--dsh-scrollbar-thumb:transparent;--dsh-scrollbar-thumb-hover:transparent}.hHd-Xa_fading>*{opacity:0;transition:opacity .15s var(--ds-ease-in-out)}.hHd-Xa_wide{animation:hHd-Xa_wide-in .2s var(--ds-ease-in-out)}@keyframes hHd-Xa_wide-in{0%{opacity:0}}.hHd-Xa_railIn .hHd-Xa_iconButton,.hHd-Xa_railIn .hHd-Xa_newSession,.hHd-Xa_railIn .hHd-Xa_panelList,.hHd-Xa_railIn .hHd-Xa_regionArea{animation:hHd-Xa_rail-in .15s var(--ds-ease-in-out) backwards}.hHd-Xa_railIn .hHd-Xa_footArea{animation:hHd-Xa_rail-fade-in .15s var(--ds-ease-in-out) backwards}@keyframes hHd-Xa_rail-in{0%{opacity:0;transform:translate(49px)}}@keyframes hHd-Xa_rail-fade-in{0%{opacity:0}}.hHd-Xa_logoRow{box-sizing:border-box;flex:none;justify-content:flex-end;align-items:center;gap:8px;height:60px;margin-bottom:
|
|
85
|
+
const css = ".hHd-Xa_root{--dsh-sidebar-inline-padding:12px;height:100%;padding:6px var(--dsh-sidebar-inline-padding);box-sizing:border-box;background:var(--dsw-specific-sidebar-fill);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);flex-direction:column;font-size:14px;display:flex}[data-platform=darwin] .hHd-Xa_root{background:0 0}.hHd-Xa_root.hHd-Xa_collapsed{padding:18px 10px 6px}[data-windows-titlebar] .hHd-Xa_root .hHd-Xa_logoRow{height:40px;margin:0;padding:0}[data-windows-titlebar] .hHd-Xa_toggle{top:calc((var(--dsh-windows-titlebar-height) - 28px) / 2);z-index:30;-webkit-app-region:no-drag;position:fixed;left:12px}[data-windows-titlebar] .hHd-Xa_root.hHd-Xa_collapsed .hHd-Xa_logoRow{height:0}[data-windows-titlebar] .hHd-Xa_root:not(.hHd-Xa_collapsed) .hHd-Xa_brand{padding-left:4px}[data-windows-titlebar] .hHd-Xa_brandIdentity{transform:translateY(1px)}[data-windows-titlebar] .hHd-Xa_brandMark{transform:translate(1px)}[data-windows-titlebar] .hHd-Xa_brandName{font-weight:400}[data-windows-titlebar] .hHd-Xa_root.hHd-Xa_collapsed{padding:0}[data-windows-titlebar] .hHd-Xa_root:not(.hHd-Xa_collapsed) .hHd-Xa_newSession{margin-top:8px;margin-left:0}[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_panelList,[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_regionArea,[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_footArea{display:none}html[data-windows-titlebar]:has([data-sidebar-collapsed=true]){--dsh-windows-menu-start:84px}[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_newSession{top:calc((var(--dsh-windows-titlebar-height) - 28px) / 2);z-index:30;-webkit-app-region:no-drag;border:none;margin:0;padding:0;position:fixed;left:48px}[data-windows-titlebar] .hHd-Xa_railIn .hHd-Xa_iconButton,[data-windows-titlebar] .hHd-Xa_railIn .hHd-Xa_newSession{animation:none}[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_toggle,[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_newSession{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-secondary);border-radius:50%}[data-windows-titlebar] .hHd-Xa_collapsed .hHd-Xa_toggle .hHd-Xa_panelIcon{display:inline}.hHd-Xa_root.hHd-Xa_quietBars{--dsh-scrollbar-thumb:transparent;--dsh-scrollbar-thumb-hover:transparent}.hHd-Xa_fading>*{opacity:0;transition:opacity .15s var(--ds-ease-in-out)}.hHd-Xa_wide{animation:hHd-Xa_wide-in .2s var(--ds-ease-in-out)}@keyframes hHd-Xa_wide-in{0%{opacity:0}}.hHd-Xa_railIn .hHd-Xa_iconButton,.hHd-Xa_railIn .hHd-Xa_newSession,.hHd-Xa_railIn .hHd-Xa_panelList,.hHd-Xa_railIn .hHd-Xa_regionArea{animation:hHd-Xa_rail-in .15s var(--ds-ease-in-out) backwards}.hHd-Xa_railIn .hHd-Xa_footArea{animation:hHd-Xa_rail-fade-in .15s var(--ds-ease-in-out) backwards}@keyframes hHd-Xa_rail-in{0%{opacity:0;transform:translate(49px)}}@keyframes hHd-Xa_rail-fade-in{0%{opacity:0}}.hHd-Xa_topStrip{box-sizing:border-box;height:52px;margin:-6px calc(-1 * var(--dsh-sidebar-inline-padding)) 0;flex:none;justify-content:flex-end;align-items:center;padding:0 12px 2px;display:flex}[data-fullscreen] .hHd-Xa_topStrip{justify-content:flex-start}.hHd-Xa_topStrip+.hHd-Xa_logoRow{margin-top:-12px}.hHd-Xa_logoRow{box-sizing:border-box;flex:none;justify-content:flex-end;align-items:center;gap:8px;height:60px;margin-bottom:4px;padding:8px 0 8px 4px;display:flex;overflow:hidden}.hHd-Xa_collapsed .hHd-Xa_logoRow{justify-content:flex-start;height:36px;margin-bottom:12px;padding:0}[data-platform=darwin] .hHd-Xa_logoRow{-webkit-app-region:drag}.hHd-Xa_brand{min-width:0;color:inherit;cursor:pointer;background:0 0;border:none;flex:1;align-items:center;padding:0;display:inline-flex;overflow:hidden}[data-platform=darwin] .hHd-Xa_brand{cursor:default}.hHd-Xa_brandIdentity{align-items:center;gap:8px;min-width:0;height:24px;display:inline-flex}.hHd-Xa_brandMark{flex:none;justify-content:center;align-items:center;display:inline-flex}.hHd-Xa_brandName{letter-spacing:.04em;align-items:center;gap:6px;min-width:0;height:24px;font-size:18px;font-weight:600;line-height:24px;display:inline-flex}.hHd-Xa_fallbackBrandName{letter-spacing:0;white-space:nowrap;font-size:17px}.hHd-Xa_localBuildBrand{white-space:nowrap;flex-direction:column;flex:none;justify-content:center;align-items:flex-start;gap:1px;height:24px;display:inline-flex}.hHd-Xa_localBuildTitle{letter-spacing:0;font-size:12px;line-height:13px}.hHd-Xa_iconButton{corner-shape:round;cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.hHd-Xa_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.hHd-Xa_collapsed .hHd-Xa_iconButton{border-radius:12px;width:36px;height:36px}.hHd-Xa_collapsed .hHd-Xa_toggle .hHd-Xa_panelIcon{display:none}.hHd-Xa_collapsed .hHd-Xa_toggle:hover .hHd-Xa_panelIcon{display:inline}.hHd-Xa_collapsed .hHd-Xa_toggle:hover .hHd-Xa_railMark{display:none}.hHd-Xa_railMark{justify-content:center;align-items:center;display:inline-flex}.hHd-Xa_collapsed .hHd-Xa_iconButton{color:var(--dsw-alias-label-primary)}.hHd-Xa_buildVersion{height:10px;color:var(--dsw-alias-label-primary-inverted);background:var(--dsw-alias-label-primary);font-family:var(--ds-font-family-code);white-space:nowrap;border-radius:2px;flex:none;align-items:center;padding:0 3px;font-size:6px;font-weight:500;line-height:10px;display:inline-flex}.hHd-Xa_newSession{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);background:var(--dsw-alias-button-elevated-fill);height:38px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:12px;flex:none;justify-content:center;align-items:center;gap:6px;margin:0 2px 12px;padding:8px 16px;font-size:14px;font-weight:500;line-height:22px;display:flex;overflow:hidden}.hHd-Xa_newSession:hover{background:var(--dsw-alias-button-floating-hover)}[data-platform=darwin] .hHd-Xa_newSession{background:#ffffff8c}[data-platform=darwin] .hHd-Xa_newSession:hover{background:#ffffff4d}[data-platform=darwin] [data-ds-dark-theme] .hHd-Xa_newSession{background:#ffffff26}[data-platform=darwin] [data-ds-dark-theme] .hHd-Xa_newSession:hover{background:#fff3}.hHd-Xa_collapsed .hHd-Xa_newSession{background:0 0;border-color:#0000;align-self:flex-start;gap:0;width:36px;height:36px;margin:0 0 12px;padding:0}.hHd-Xa_collapsed .hHd-Xa_newSession:hover{background:var(--dsw-alias-interactive-bg-hover)}.hHd-Xa_newSessionLabel{white-space:nowrap;max-width:200px;overflow:hidden}.hHd-Xa_collapsed .hHd-Xa_newSessionLabel{max-width:0}.hHd-Xa_panelList{flex-direction:column;flex:none;gap:4px;margin-bottom:8px;display:flex}.hHd-Xa_panelRow{box-sizing:border-box;min-height:36px;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;margin:0 2px;padding:7px 8px;line-height:22px;display:flex}.hHd-Xa_panelRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.hHd-Xa_panelRow.hHd-Xa_panelActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.hHd-Xa_panelRow:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.hHd-Xa_panelGlyph{flex:none;justify-content:center;align-items:center;display:inline-flex}.hHd-Xa_panelTitle{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.hHd-Xa_collapsed .hHd-Xa_panelList{gap:12px;margin-bottom:12px}.hHd-Xa_collapsed .hHd-Xa_panelRow{width:36px;height:36px;color:var(--dsw-alias-label-primary);justify-content:center;margin:0;padding:0}.hHd-Xa_regionArea{min-height:0;margin-left:-4px;margin-right:calc(-1 * var(--dsh-sidebar-inline-padding));flex-direction:column;flex:1;padding-left:4px;display:flex;overflow:hidden}.hHd-Xa_collapsed .hHd-Xa_regionArea{margin-left:0;margin-right:0;padding-left:0}.hHd-Xa_footArea{flex-direction:column;flex:none;display:flex}.hHd-Xa_settingsArea,.hHd-Xa_footerActions{flex:none;width:100%;min-width:0}.hHd-Xa_footerActions{display:flex}.hHd-Xa_collapsed .hHd-Xa_footArea{align-items:center}.hHd-Xa_collapsed .hHd-Xa_settingsArea,.hHd-Xa_collapsed .hHd-Xa_footerActions{justify-content:center;width:auto;display:flex}@media (prefers-reduced-motion:reduce){.hHd-Xa_wide,.hHd-Xa_fading>*,.hHd-Xa_railIn .hHd-Xa_iconButton,.hHd-Xa_railIn .hHd-Xa_newSession,.hHd-Xa_railIn .hHd-Xa_panelList,.hHd-Xa_railIn .hHd-Xa_footArea,.hHd-Xa_railIn .hHd-Xa_regionArea{transition:none;animation:none}}";
|
|
29
86
|
const tagId = "@deepseek-ai/dsh-client-ui-sidebar/SidebarRoot.module.css";
|
|
30
87
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
31
88
|
const tag = document.createElement("style");
|
|
@@ -66,6 +123,7 @@ window.__ModuleLoader__.load({
|
|
|
66
123
|
"root": "hHd-Xa_root",
|
|
67
124
|
"settingsArea": "hHd-Xa_settingsArea",
|
|
68
125
|
"toggle": "hHd-Xa_toggle",
|
|
126
|
+
"topStrip": "hHd-Xa_topStrip",
|
|
69
127
|
"wide": "hHd-Xa_wide",
|
|
70
128
|
"wide-in": "hHd-Xa_wide-in"
|
|
71
129
|
};
|
|
@@ -100,7 +158,7 @@ window.__ModuleLoader__.load({
|
|
|
100
158
|
const SCROLLBAR_LINGER_MS = 2e3;
|
|
101
159
|
/** Format complete-build metadata for the local brand badge. */
|
|
102
160
|
function localBuildVersion() {
|
|
103
|
-
return `0.1.
|
|
161
|
+
return `0.1.7-alpha.1-46bb4af` + ({}.DSH_CLIENT_GIT_DIRTY === "true" ? "-dirty" : "");
|
|
104
162
|
}
|
|
105
163
|
/** Each panel row subscribes only to its own selection state. */
|
|
106
164
|
function PanelRow({ id, label, wide, usePanelInfo, selectPanel, renderSlot }) {
|
|
@@ -151,7 +209,9 @@ window.__ModuleLoader__.load({
|
|
|
151
209
|
window.clearTimeout(timer);
|
|
152
210
|
};
|
|
153
211
|
}, [collapsed]);
|
|
154
|
-
const
|
|
212
|
+
const windowsTitlebar = document.documentElement.hasAttribute("data-windows-titlebar");
|
|
213
|
+
const wide = windowsTitlebar ? !collapsed : !collapsed || !settled;
|
|
214
|
+
const captionTooltipSide = windowsTitlebar ? "bottom" : "right";
|
|
155
215
|
const lastWideWidth = (0, react.useRef)(width);
|
|
156
216
|
if (!collapsed) lastWideWidth.current = width;
|
|
157
217
|
const everWide = (0, react.useRef)(!collapsed);
|
|
@@ -186,6 +246,32 @@ window.__ModuleLoader__.load({
|
|
|
186
246
|
};
|
|
187
247
|
}, [pointerInside]);
|
|
188
248
|
const buildVersion = localBuildVersion();
|
|
249
|
+
const darwinDesktop = (0, _deepseek_ai_dsh_client_ui_primitives.isDarwinDesktop)();
|
|
250
|
+
const toggle = (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
251
|
+
label: collapsed ? t("toggle.open") : t("toggle.collapse"),
|
|
252
|
+
delayMs: 500,
|
|
253
|
+
side: captionTooltipSide,
|
|
254
|
+
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
255
|
+
type: "button",
|
|
256
|
+
className: clsx(SidebarRoot_module_css_default.iconButton, SidebarRoot_module_css_default.toggle),
|
|
257
|
+
"aria-label": collapsed ? t("toggle.open") : t("toggle.collapse"),
|
|
258
|
+
onClick: () => {
|
|
259
|
+
toggleSidebar();
|
|
260
|
+
},
|
|
261
|
+
children: [
|
|
262
|
+
!wide && !windowsTitlebar && (0, react_jsx_runtime.jsx)("span", {
|
|
263
|
+
className: SidebarRoot_module_css_default.railMark,
|
|
264
|
+
"aria-hidden": "true",
|
|
265
|
+
children: renderSlot("sidebar.brand.mark", { size: 24 }, { fallback: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.FishLogo, { size: 24 }) })
|
|
266
|
+
}),
|
|
267
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutlineRegular, {
|
|
268
|
+
className: SidebarRoot_module_css_default.panelIcon,
|
|
269
|
+
size: wide || windowsTitlebar ? 16 : 18
|
|
270
|
+
}),
|
|
271
|
+
!wide && renderSlot("sidebar.toggle.badge", {})
|
|
272
|
+
]
|
|
273
|
+
})
|
|
274
|
+
});
|
|
189
275
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
190
276
|
ref: column,
|
|
191
277
|
className: clsx(SidebarRoot_module_css_default.root, !wide && SidebarRoot_module_css_default.collapsed, !wide && everWide.current && SidebarRoot_module_css_default.railIn, collapsed && wide && SidebarRoot_module_css_default.fading, !pointerInside && SidebarRoot_module_css_default.quietBars),
|
|
@@ -198,16 +284,14 @@ window.__ModuleLoader__.load({
|
|
|
198
284
|
armLinger();
|
|
199
285
|
},
|
|
200
286
|
children: [
|
|
287
|
+
darwinDesktop && (0, react_jsx_runtime.jsx)("div", {
|
|
288
|
+
className: SidebarRoot_module_css_default.topStrip,
|
|
289
|
+
children: toggle
|
|
290
|
+
}),
|
|
201
291
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
202
292
|
className: SidebarRoot_module_css_default.logoRow,
|
|
203
|
-
children: [wide && (
|
|
204
|
-
|
|
205
|
-
className: clsx(SidebarRoot_module_css_default.brand, SidebarRoot_module_css_default.wide),
|
|
206
|
-
"aria-label": t("session.new.label"),
|
|
207
|
-
onClick: () => {
|
|
208
|
-
startSession();
|
|
209
|
-
},
|
|
210
|
-
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
293
|
+
children: [wide && (() => {
|
|
294
|
+
const identity = (0, react_jsx_runtime.jsxs)("span", {
|
|
211
295
|
className: SidebarRoot_module_css_default.brandIdentity,
|
|
212
296
|
"aria-hidden": "true",
|
|
213
297
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
@@ -229,32 +313,26 @@ window.__ModuleLoader__.load({
|
|
|
229
313
|
})]
|
|
230
314
|
}) })
|
|
231
315
|
})]
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
316
|
+
});
|
|
317
|
+
return darwinDesktop ? (0, react_jsx_runtime.jsx)("span", {
|
|
318
|
+
className: clsx(SidebarRoot_module_css_default.brand, SidebarRoot_module_css_default.wide),
|
|
319
|
+
children: identity
|
|
320
|
+
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
237
321
|
type: "button",
|
|
238
|
-
className: clsx(SidebarRoot_module_css_default.
|
|
239
|
-
"aria-label":
|
|
322
|
+
className: clsx(SidebarRoot_module_css_default.brand, SidebarRoot_module_css_default.wide),
|
|
323
|
+
"aria-label": t("session.new.label"),
|
|
240
324
|
onClick: () => {
|
|
241
|
-
|
|
325
|
+
startSession();
|
|
242
326
|
},
|
|
243
|
-
children:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
children: renderSlot("sidebar.brand.mark", { size: 24 }, { fallback: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.FishLogo, { size: 24 }) })
|
|
247
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, {
|
|
248
|
-
className: SidebarRoot_module_css_default.panelIcon,
|
|
249
|
-
size: wide ? 16 : 18
|
|
250
|
-
})]
|
|
251
|
-
})
|
|
252
|
-
})]
|
|
327
|
+
children: identity
|
|
328
|
+
});
|
|
329
|
+
})(), !darwinDesktop && toggle]
|
|
253
330
|
}),
|
|
254
331
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
255
332
|
label: t("session.new.label"),
|
|
256
333
|
delayMs: 500,
|
|
257
334
|
disabled: wide,
|
|
335
|
+
side: captionTooltipSide,
|
|
258
336
|
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
259
337
|
type: "button",
|
|
260
338
|
className: SidebarRoot_module_css_default.newSession,
|
|
@@ -262,7 +340,7 @@ window.__ModuleLoader__.load({
|
|
|
262
340
|
onClick: () => {
|
|
263
341
|
startSession();
|
|
264
342
|
},
|
|
265
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
343
|
+
children: [wide ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutlineMedium, { size: 14 }) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutlineRegular, { size: windowsTitlebar ? 16 : 18 }), wide && (0, react_jsx_runtime.jsx)("span", {
|
|
266
344
|
className: clsx(SidebarRoot_module_css_default.newSessionLabel, SidebarRoot_module_css_default.wide),
|
|
267
345
|
children: t("session.new")
|
|
268
346
|
})]
|
|
@@ -384,6 +462,10 @@ window.__ModuleLoader__.load({
|
|
|
384
462
|
kind: "single",
|
|
385
463
|
scope: "root"
|
|
386
464
|
},
|
|
465
|
+
"sidebar.toggle.badge": {
|
|
466
|
+
kind: "single",
|
|
467
|
+
scope: "root"
|
|
468
|
+
},
|
|
387
469
|
"sidebar.panellist": {
|
|
388
470
|
kind: "list",
|
|
389
471
|
scope: "root"
|
|
@@ -403,6 +485,11 @@ window.__ModuleLoader__.load({
|
|
|
403
485
|
},
|
|
404
486
|
inject: injectProps
|
|
405
487
|
}, SidebarRoot));
|
|
488
|
+
ctx.slots.inject("shell.leading", () => ctx.slots.register({
|
|
489
|
+
name: "shell.leading",
|
|
490
|
+
locale: NS,
|
|
491
|
+
inject: injectProps
|
|
492
|
+
}, HeaderLeadingControls));
|
|
406
493
|
syncPanels();
|
|
407
494
|
}
|
|
408
495
|
//#endregion
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { SidebarRootInjected } from './contract/slots.ts';
|
|
3
|
+
/** Full props of the shell.leading occupant. */
|
|
4
|
+
export type HeaderLeadingControlsProps = PropsRuntime<'shell.leading'> & InjectFace<SidebarRootInjected> & PropsLocale<'sidebar'>;
|
|
5
|
+
/**
|
|
6
|
+
* Sidebar-open and New Session controls in the frame's window-chrome seat.
|
|
7
|
+
* On macOS desktop a collapsed sidebar hides entirely (no rail), taking both
|
|
8
|
+
* controls off screen; this occupant puts them back beside the traffic
|
|
9
|
+
* lights. The frame mounts the seat only in that state and owns its
|
|
10
|
+
* placement, so the occupant renders unconditionally.
|
|
11
|
+
* @param props - Injected sidebar actions plus the sidebar locale seat.
|
|
12
|
+
* @returns the two window-chrome controls.
|
|
13
|
+
*/
|
|
14
|
+
export declare function HeaderLeadingControls({ toggleSidebar, startSession, t }: HeaderLeadingControlsProps): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=HeaderLeadingControls.d.ts.map
|
|
@@ -13,6 +13,12 @@ import type { WorkspaceId } from '@deepseek-ai/dsh-api-workspace-controller/clie
|
|
|
13
13
|
import type { MainPanelId } from '@deepseek-ai/dsh-client-ui-layout/client';
|
|
14
14
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
15
15
|
interface SlotMap {
|
|
16
|
+
/** Non-interactive notification inside the collapsed sidebar expand button. */
|
|
17
|
+
'sidebar.toggle.badge': {
|
|
18
|
+
kind: 'single';
|
|
19
|
+
scope: 'root';
|
|
20
|
+
owner: Record<never, never>;
|
|
21
|
+
};
|
|
16
22
|
/**
|
|
17
23
|
* Brand mark rendered in the expanded brand row and collapsed rail.
|
|
18
24
|
* Declared by this package's `sidebar` entry; deployments may replace
|
|
@@ -147,5 +153,5 @@ export type SidebarRootInjected = {
|
|
|
147
153
|
* render shares, this package's injected callbacks, and the standard locale
|
|
148
154
|
* seat. Panel metadata arrives through an injected observable.
|
|
149
155
|
*/
|
|
150
|
-
export type SidebarRootComponentProps = PropsRuntime<'sidebar'> & PropsRenderSlots<'sidebar.brand.mark' | 'sidebar.brand.name' | 'sidebar.panellist' | 'sidebar.workspaces' | 'sidebar.settings' | 'sidebar.footer.action'> & InjectFace<SidebarRootInjected> & PropsLocale<'sidebar'>;
|
|
156
|
+
export type SidebarRootComponentProps = PropsRuntime<'sidebar'> & PropsRenderSlots<'sidebar.brand.mark' | 'sidebar.brand.name' | 'sidebar.toggle.badge' | 'sidebar.panellist' | 'sidebar.workspaces' | 'sidebar.settings' | 'sidebar.footer.action'> & InjectFace<SidebarRootInjected> & PropsLocale<'sidebar'>;
|
|
151
157
|
//# sourceMappingURL=slots.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-sidebar",
|
|
3
3
|
"description": "Sidebar plugin: session multi-level tree, search, grouping, state dots",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.7-alpha.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -40,23 +40,23 @@
|
|
|
40
40
|
},
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
43
|
+
"@deepseek-ai/cordis": "^4.0.3"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/react": "~18.3.1",
|
|
47
47
|
"react": "^18.2.0",
|
|
48
48
|
"clsx": "^2.0.0",
|
|
49
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-client-test-runtime": "^0.1.
|
|
53
|
-
"@deepseek-ai/dsh-client-ui-
|
|
54
|
-
"@deepseek-ai/dsh-client-ui-
|
|
55
|
-
"@deepseek-ai/dsh-client-ui-
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-
|
|
57
|
-
"@deepseek-ai/
|
|
58
|
-
"@deepseek-ai/
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-session": "^0.1.
|
|
49
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.7-alpha.1",
|
|
50
|
+
"@deepseek-ai/dsh-client-store": "^0.1.7-alpha.1",
|
|
51
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.7-alpha.1",
|
|
52
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.7-alpha.1",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-alpha.1",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-alpha.1",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.1.7-alpha.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-alpha.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-workspace": "^0.1.7-alpha.1",
|
|
58
|
+
"@deepseek-ai/cordis": "^4.0.3",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.7-alpha.1"
|
|
60
60
|
},
|
|
61
61
|
"files": [
|
|
62
62
|
"lib/index.js",
|