@deepseek-ai/dsh-client-ui-layout 0.0.1-rc.2 → 0.0.1-rc.3
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 +1 -1
- package/README.zh.md +1 -1
- package/lib/client.js +17 -7
- package/lib/types/client/AppFrame.d.ts +1 -1
- package/lib/types/client/columns.d.ts +2 -2
- package/lib/types/client/index.d.ts +46 -1
- package/lib/types/client/service.d.ts +2 -2
- package/package.json +10 -10
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-layout/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 7c9d64b9ca7a5fada492c37200a283904466c36d
|
|
6
|
+
README.zh.md: a2604d865977c495d2a3d2362b25f05e34142c97
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Shell plugin: three-column AppFrame (drag handles and concession chain) plus the
|
|
|
6
6
|
|
|
7
7
|
AppFrame always mounts the conversation and details columns; a connected Session renders through `SessionProvider`. The transient layout store starts the sidebar at its default width and details closed, and it never reads or writes `localStorage`. Hero and other unselected states also derive a zero rendered details width without changing that stored preference. AppFrame retains the last non-blank Session id across those states: the first Session remains closed, an explicit details action opens the contract default width, returning to the same Session restores its unchanged width, and selecting a different Session closes details before paint. The conversation owner share is empty, while the sidebar owner share contains only `collapsed` and `width`; registrants obtain business data from standard hooks and actions from their own inject faces.
|
|
8
8
|
|
|
9
|
-
The `/client` exports are the plugin body (`apply`/`inject`), `
|
|
9
|
+
The `/client` exports are the plugin body (`apply`/`inject`), `LayoutController`, and the four owner-share interfaces. AppFrame, the panel store, and the concession solver remain package-internal.
|
|
10
10
|
|
|
11
11
|
## Model Experience
|
|
12
12
|
|
package/README.zh.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
AppFrame 始终挂载会话栏和详情栏;已连接 Session 通过 `SessionProvider` 渲染。布局 store 是瞬时状态,侧边栏以默认宽度启动,详情栏则保持关闭,且该 store 从不读写 `localStorage`。hero 和其他未选中状态也会将详情栏的渲染宽度派生为零,但不会改变存储的宽度偏好。AppFrame 会跨越这些状态保留最后一个非 blank 会话 id:首个会话保持关闭;显式打开详情栏的操作会使用约定默认宽度;返回同一会话时恢复其未改变的宽度;选择不同会话时,详情栏会在绘制前关闭。会话 owner share 为空,侧边栏 owner share 只包含 `collapsed` 和 `width`;注册方通过标准钩子获取业务数据,并从各自的 inject 接口获取操作。
|
|
8
8
|
|
|
9
|
-
`/client` 导出表层包含插件主体(`apply`/`inject`)、`
|
|
9
|
+
`/client` 导出表层包含插件主体(`apply`/`inject`)、`LayoutController` 和四个 owner-share 接口。AppFrame、面板 store 与让步求解器仍属于包内部。
|
|
10
10
|
|
|
11
11
|
## 模型体验
|
|
12
12
|
|
package/lib/client.js
CHANGED
|
@@ -32,7 +32,7 @@ window.__ModuleLoader__.load({
|
|
|
32
32
|
* @returns resolved widths; details 0 means visually closed (never unmounted), while a closed sidebar keeps its compact rail.
|
|
33
33
|
*/
|
|
34
34
|
function computeColumns(viewport, sidebar, details) {
|
|
35
|
-
const s = sidebar === 0 ? 56 : clampWidth(sidebar,
|
|
35
|
+
const s = sidebar === 0 ? 56 : clampWidth(sidebar, 264, 420);
|
|
36
36
|
const d0 = details === 0 ? 0 : clampWidth(details, 300, 520);
|
|
37
37
|
if (s + d0 + 640 <= viewport) return {
|
|
38
38
|
sidebar: s,
|
|
@@ -53,7 +53,7 @@ window.__ModuleLoader__.load({
|
|
|
53
53
|
}
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-layout/src/client/AppFrame.module.css.mjs
|
|
56
|
-
const css = ".pI_x6G_frame{background:var(--dsw-alias-bg-base);height:100%;transition:grid-template-columns var(--ds-transition-duration-slow) var(--ds-ease-in-out);grid-template-rows:100%;display:grid;position:relative;overflow:hidden}.pI_x6G_frame[data-dragging]{transition:none}@media (prefers-reduced-motion:reduce){.pI_x6G_frame{transition:none}}.pI_x6G_sidebarCol{background:var(--dsw-specific-sidebar-fill);border-right:1px solid var(--dsw-alias-border-l1);min-width:0;overflow:hidden}.pI_x6G_centerCol{flex-direction:column;min-width:0;display:flex;overflow:hidden}.pI_x6G_detailsCol{border-left:1px solid var(--dsw-alias-border-l2);min-width:0;overflow:hidden}.pI_x6G_frame[data-details-collapsed] .pI_x6G_detailsCol{border-left:none}.pI_x6G_handle{cursor:col-resize;z-index:2;touch-action:none;width:8px;transition:left var(--ds-transition-duration-slow) var(--ds-ease-in-out);margin-left:-4px;position:absolute;top:0;bottom:0}.pI_x6G_frame[data-dragging] .pI_x6G_handle{transition:none}@media (prefers-reduced-motion:reduce){.pI_x6G_handle{transition:none}}.pI_x6G_handle[data-side=details]:after{content:\"\";box-sizing:border-box;background:var(--dsw-alias-button-floating-fill);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);opacity:0;width:12px;height:32px;transition:opacity var(--ds-transition-duration-slow) var(--ds-ease-in-out), background var(--ds-transition-duration-slow) var(--ds-ease-in-out);border-radius:10px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.pI_x6G_detailsCol:hover~.pI_x6G_handle[data-side=details]:after,.pI_x6G_handle[data-side=details]:hover:after,.pI_x6G_handle[data-side=details][data-dragging=true]:after{opacity:1}.pI_x6G_handle[data-side=details]:hover:after,.pI_x6G_handle[data-side=details][data-dragging=true]:after{background:var(--dsw-alias-button-floating-hover);border-color:var(--dsw-alias-border-l3)}";
|
|
56
|
+
const css = ".pI_x6G_frame{background:var(--dsw-alias-bg-base);height:100%;transition:grid-template-columns var(--ds-transition-duration-slow) var(--ds-ease-in-out);grid-template-rows:100%;display:grid;position:relative;overflow:hidden}.pI_x6G_frame[data-dragging]{transition:none}@media (prefers-reduced-motion:reduce){.pI_x6G_frame{transition:none}}.pI_x6G_sidebarCol{background:var(--dsw-specific-sidebar-fill);border-right:1px solid var(--dsw-alias-border-l1);min-width:0;overflow:hidden}.pI_x6G_centerCol{flex-direction:column;min-width:0;display:flex;overflow:hidden}.pI_x6G_detailsCol{border-left:1px solid var(--dsw-alias-border-l2);min-width:0;overflow:hidden}.pI_x6G_frame[data-details-collapsed] .pI_x6G_detailsCol{border-left:none}.pI_x6G_handle{cursor:col-resize;z-index:2;touch-action:none;width:8px;transition:left var(--ds-transition-duration-slow) var(--ds-ease-in-out);margin-left:-4px;position:absolute;top:0;bottom:0}.pI_x6G_frame[data-dragging] .pI_x6G_handle{transition:none}@media (prefers-reduced-motion:reduce){.pI_x6G_handle{transition:none}}.pI_x6G_handle[data-side=details]:after{content:\"\";box-sizing:border-box;background:var(--dsw-alias-button-floating-fill);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);opacity:0;width:12px;height:32px;transition:opacity var(--ds-transition-duration-slow) var(--ds-ease-in-out), background var(--ds-transition-duration-slow) var(--ds-ease-in-out);border-radius:10px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.pI_x6G_detailsCol:hover~.pI_x6G_handle[data-side=details]:after,.pI_x6G_handle[data-side=details]:hover:after,.pI_x6G_handle[data-side=details][data-dragging=true]:after{opacity:1}.pI_x6G_handle[data-side=details]:hover:after,.pI_x6G_handle[data-side=details][data-dragging=true]:after{background:var(--dsw-alias-button-floating-hover);border-color:var(--dsw-alias-border-l3)}.pI_x6G_overlayLayer{z-index:20;pointer-events:none;position:absolute;inset:0}.pI_x6G_overlayLayer>*{pointer-events:auto}";
|
|
57
57
|
const tagId = "@deepseek-ai/dsh-client-ui-layout/AppFrame.module.css";
|
|
58
58
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
59
59
|
const tag = document.createElement("style");
|
|
@@ -63,9 +63,10 @@ window.__ModuleLoader__.load({
|
|
|
63
63
|
document.head.appendChild(tag);
|
|
64
64
|
}
|
|
65
65
|
var AppFrame_module_css_default = {
|
|
66
|
-
"frame": "pI_x6G_frame",
|
|
67
66
|
"sidebarCol": "pI_x6G_sidebarCol",
|
|
67
|
+
"frame": "pI_x6G_frame",
|
|
68
68
|
"centerCol": "pI_x6G_centerCol",
|
|
69
|
+
"overlayLayer": "pI_x6G_overlayLayer",
|
|
69
70
|
"detailsCol": "pI_x6G_detailsCol",
|
|
70
71
|
"handle": "pI_x6G_handle"
|
|
71
72
|
};
|
|
@@ -230,6 +231,11 @@ window.__ModuleLoader__.load({
|
|
|
230
231
|
})
|
|
231
232
|
}),
|
|
232
233
|
(0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(CenterColumn, { children: renderSlot("conversation", {}) }), (0, react_jsx_runtime.jsx)(DetailsColumn, { children: renderSlot("details", {}) })] }),
|
|
234
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
235
|
+
className: AppFrame_module_css_default.overlayLayer,
|
|
236
|
+
"data-shell-overlay": true,
|
|
237
|
+
children: renderSlot("shell.overlay", {})
|
|
238
|
+
}),
|
|
233
239
|
!sidebarCollapsed && (0, react_jsx_runtime.jsx)(DragHandle, {
|
|
234
240
|
side: "sidebar",
|
|
235
241
|
left: cols.sidebar,
|
|
@@ -278,7 +284,7 @@ window.__ModuleLoader__.load({
|
|
|
278
284
|
}),
|
|
279
285
|
actions: {
|
|
280
286
|
setSidebar: (d, px) => {
|
|
281
|
-
d.sidebar = clampWidth(px,
|
|
287
|
+
d.sidebar = clampWidth(px, 264, 420);
|
|
282
288
|
},
|
|
283
289
|
setDetails: (d, px) => {
|
|
284
290
|
d.details = clampWidth(px, 300, 520);
|
|
@@ -304,7 +310,7 @@ window.__ModuleLoader__.load({
|
|
|
304
310
|
//#endregion
|
|
305
311
|
//#region lib/types/client/service.js
|
|
306
312
|
/** Cross-plugin panel-action face (ctx.layout). */
|
|
307
|
-
var
|
|
313
|
+
var LayoutController = class {
|
|
308
314
|
#panels;
|
|
309
315
|
/**
|
|
310
316
|
* Adopt the root entry's bound store actions. Called from the root
|
|
@@ -393,7 +399,7 @@ window.__ModuleLoader__.load({
|
|
|
393
399
|
* @param ctx - client root context.
|
|
394
400
|
*/
|
|
395
401
|
function apply(ctx) {
|
|
396
|
-
const layout = new
|
|
402
|
+
const layout = new LayoutController();
|
|
397
403
|
ctx.effect(() => {
|
|
398
404
|
const disposeService = ctx.reflect.provide("layout", layout);
|
|
399
405
|
const disposeRegistration = ctx.slots.register({
|
|
@@ -410,6 +416,10 @@ window.__ModuleLoader__.load({
|
|
|
410
416
|
"details": {
|
|
411
417
|
kind: "single",
|
|
412
418
|
scope: "session"
|
|
419
|
+
},
|
|
420
|
+
"shell.overlay": {
|
|
421
|
+
kind: "list",
|
|
422
|
+
scope: "root"
|
|
413
423
|
}
|
|
414
424
|
},
|
|
415
425
|
store: createLayoutStore,
|
|
@@ -436,7 +446,7 @@ window.__ModuleLoader__.load({
|
|
|
436
446
|
}, "ui-layout: theme presenter");
|
|
437
447
|
}
|
|
438
448
|
//#endregion
|
|
439
|
-
exports.
|
|
449
|
+
exports.LayoutController = LayoutController;
|
|
440
450
|
exports.apply = apply;
|
|
441
451
|
exports.inject = inject;
|
|
442
452
|
return module.exports;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PropsRenderSlots, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
2
|
import type { createLayoutStore } from './stores.ts';
|
|
3
3
|
/** Full composed props: runtime share + child-slot render share + store share. */
|
|
4
|
-
export type AppFrameProps = PropsRuntime<'root'> & PropsRenderSlots<'sidebar' | 'conversation' | 'details'> & PropsStore<ReturnType<typeof createLayoutStore>>;
|
|
4
|
+
export type AppFrameProps = PropsRuntime<'root'> & PropsRenderSlots<'sidebar' | 'conversation' | 'details' | 'shell.overlay'> & PropsStore<ReturnType<typeof createLayoutStore>>;
|
|
5
5
|
/** The three-column frame (see module doc). */
|
|
6
6
|
export declare function AppFrame({ useStore, useSessions, actions, renderSlot, }: AppFrameProps): import("react").JSX.Element;
|
|
7
7
|
//# sourceMappingURL=AppFrame.d.ts.map
|
|
@@ -21,10 +21,10 @@ export interface Columns {
|
|
|
21
21
|
/** Center column floor; only the final fallback may go below it. */
|
|
22
22
|
export declare const CENTER_MIN = 640;
|
|
23
23
|
/** Sidebar drag clamp floor. */
|
|
24
|
-
export declare const SIDEBAR_MIN =
|
|
24
|
+
export declare const SIDEBAR_MIN = 264;
|
|
25
25
|
/** Sidebar drag clamp ceiling. */
|
|
26
26
|
export declare const SIDEBAR_MAX = 420;
|
|
27
|
-
/** Sidebar width before any user drag
|
|
27
|
+
/** Sidebar width before any user drag. */
|
|
28
28
|
export declare const SIDEBAR_DEFAULT = 280;
|
|
29
29
|
/** Closed-sidebar rail: a 24px icon column between 16px horizontal paddings. */
|
|
30
30
|
export declare const SIDEBAR_COLLAPSED = 56;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* presenter, which projects ctx.theme snapshots onto document.body.
|
|
9
9
|
*/
|
|
10
10
|
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
11
|
-
export {
|
|
11
|
+
export { LayoutController } from './service.ts';
|
|
12
12
|
export type { ILayout } from './service.ts';
|
|
13
13
|
declare module '@deepseek-ai/cordis' {
|
|
14
14
|
interface Context {
|
|
@@ -18,21 +18,66 @@ declare module '@deepseek-ai/cordis' {
|
|
|
18
18
|
}
|
|
19
19
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
20
20
|
interface SlotMap {
|
|
21
|
+
/**
|
|
22
|
+
* The whole left column. OCCUPIED by ui-sidebar's SidebarRoot, which
|
|
23
|
+
* declares the workspace and settings seats inside it — registering here
|
|
24
|
+
* replaces the navigation column outright rather than adding to it, and
|
|
25
|
+
* the seats it declares disappear with it. To add something to the
|
|
26
|
+
* sidebar, register into one of those inner seats instead.
|
|
27
|
+
*
|
|
28
|
+
* The occupant receives the frame's live column state (collapsed, width)
|
|
29
|
+
* and is expected to render the compact control rail while collapsed.
|
|
30
|
+
*/
|
|
21
31
|
'sidebar': {
|
|
22
32
|
kind: 'single';
|
|
23
33
|
scope: 'root';
|
|
24
34
|
owner: SidebarOwnerProps;
|
|
25
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* The whole center column, across both the no-session hero and a live
|
|
38
|
+
* conversation. OCCUPIED by ui-conversation's ConversationRoot, which
|
|
39
|
+
* declares the session body, composer, and input seats inside it —
|
|
40
|
+
* registering here replaces the entire conversation surface (and removes
|
|
41
|
+
* every seat it declares) rather than adding to it.
|
|
42
|
+
*
|
|
43
|
+
* Current-session-optional: the occupant owns both states without
|
|
44
|
+
* changing its React identity, so it keeps its own state across a session
|
|
45
|
+
* switch. It receives no owner props; session facts arrive through the
|
|
46
|
+
* framework hooks of the `session-maybe` scope.
|
|
47
|
+
*/
|
|
26
48
|
'conversation': {
|
|
27
49
|
kind: 'single';
|
|
28
50
|
scope: 'session-maybe';
|
|
29
51
|
owner: ConvOwnerProps;
|
|
30
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* The right details column, shown when the layout opens it. OCCUPIED by
|
|
55
|
+
* ui-conversation's DetailsPanel, which declares the tool-details seat
|
|
56
|
+
* inside it — registering here replaces the column and takes that seat
|
|
57
|
+
* with it. Absent an occupant the column renders nothing.
|
|
58
|
+
*
|
|
59
|
+
* No owner props: the framework injects the session id and hooks for the
|
|
60
|
+
* `session` scope, and `ctx.layout` owns whether the column is open.
|
|
61
|
+
*/
|
|
31
62
|
'details': {
|
|
32
63
|
kind: 'single';
|
|
33
64
|
scope: 'session';
|
|
34
65
|
owner: DetailsOwnerProps;
|
|
35
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Frame-wide floating layer, above every column and outside their scroll
|
|
69
|
+
* containers. Deliberately generic and unowned by any feature: a badge, a
|
|
70
|
+
* toast stack or a status pill all belong here, and entries order among
|
|
71
|
+
* themselves. The layer itself is click-through — entries opt back into
|
|
72
|
+
* pointer events — so an occupant never blocks the app underneath.
|
|
73
|
+
*
|
|
74
|
+
* This is the additive seat for a frame-wide surface of your own: a fresh
|
|
75
|
+
* `id` is added beside the shipped entries instead of replacing them.
|
|
76
|
+
*/
|
|
77
|
+
'shell.overlay': {
|
|
78
|
+
kind: 'list';
|
|
79
|
+
scope: 'root';
|
|
80
|
+
};
|
|
36
81
|
}
|
|
37
82
|
}
|
|
38
83
|
/** Sidebar owner share: live column state from the frame's concession solve. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* LayoutController: the cross-plugin panel-action face behind ctx.layout.
|
|
3
3
|
* Panel geometry itself lives in the root entry's layout store (stores.ts);
|
|
4
4
|
* the current-session selection lives with the runtime sessions service, and
|
|
5
5
|
* the per-session active view dissolved into ui-conversation's session store
|
|
@@ -27,7 +27,7 @@ export interface ILayout {
|
|
|
27
27
|
closeDetails(): void;
|
|
28
28
|
}
|
|
29
29
|
/** Cross-plugin panel-action face (ctx.layout). */
|
|
30
|
-
export declare class
|
|
30
|
+
export declare class LayoutController implements ILayout {
|
|
31
31
|
#private;
|
|
32
32
|
/**
|
|
33
33
|
* Adopt the root entry's bound store actions. Called from the root
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-layout",
|
|
3
3
|
"description": "Shell plugin: three-column AppFrame with drag handles, ctx.layout viewing-state service (navigation + panels)",
|
|
4
|
-
"version": "0.0.1-rc.
|
|
4
|
+
"version": "0.0.1-rc.3",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "restricted"
|
|
7
7
|
},
|
|
@@ -41,20 +41,20 @@
|
|
|
41
41
|
"license": "BSD-3-Clause",
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"react": "^18.2.0",
|
|
44
|
-
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.
|
|
45
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.
|
|
46
|
-
"@deepseek-ai/dsh-client-ui-theme": "^0.0.1-rc.
|
|
47
|
-
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.
|
|
44
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.3",
|
|
45
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.3",
|
|
46
|
+
"@deepseek-ai/dsh-client-ui-theme": "^0.0.1-rc.3",
|
|
47
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.3",
|
|
48
48
|
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/react": "~18.3.1",
|
|
52
52
|
"react": "^18.2.0",
|
|
53
|
-
"@deepseek-ai/dsh-client-
|
|
54
|
-
"@deepseek-ai/dsh-client-
|
|
55
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-theme": "^0.0.1-rc.
|
|
57
|
-
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.
|
|
53
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.3",
|
|
54
|
+
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.3",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.3",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-theme": "^0.0.1-rc.3",
|
|
57
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.3",
|
|
58
58
|
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
59
59
|
},
|
|
60
60
|
"files": [
|