@deepseek-ai/dsh-client-ui-theme 0.1.0-rc.8 → 0.1.1-rc.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.i18n.yaml +1 -1
- package/README.zh.md +3 -3
- package/lib/index.js +22 -23
- package/lib/types/boot-theme.d.ts +9 -10
- package/lib/types/index.d.ts +4 -3
- package/package.json +20 -20
package/README.i18n.yaml
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
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-theme/README.md
|
|
5
5
|
README.md: a9f0eb428789bc117e2fcbbdd2366066e0b994cc
|
|
6
|
-
README.zh.md:
|
|
6
|
+
README.zh.md: 1447536c3e12a415c3ca241e4fe04a636ecaa6fd
|
package/README.zh.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 中文
|
|
4
4
|
|
|
5
|
-
主题插件:基于 --dsw-* token 基础样式表(静态尺度 + 别名语义层)的 ThemeRuntime。该服务拥有实时主题偏好(`light`/`dark`/`system`),将 `system` 通过 `prefers-color-scheme` 解析为实际主题,并发布不可变的 `ThemeSnapshot`,通过 `theme/change` 事件通知变化;它绝不接触 DOM:ui-layout 的呈现器会应用解析后的快照(`html { color-scheme }`、`body[data-ds-dark-theme]`,以及主题的别名 token 内联变量)。来自回环地址的浏览器会先以 `system` 立即提供该服务,随后在后台加载 `ui-theme.preference`,并将每次内置主题选择通过 Host settings API 写入;其本地提供方默认将设置存入 `$DSH_HOME/settings.yaml`。收到推送的 settings 变更时或重连后,浏览器都会重新拉取该设置;连续快速选择会按操作顺序携带 namespace revision 串行写入,最新写入被拒时则重新加载持久化值。远程浏览器无法访问特权 settings API,因此它的选择仅保留在进程内。已注册的第三方主题 id 仍是进程内扩展,不会跨越内置 settings schema;移除其中任意一个都绝不会覆盖最后一个持久化的内置偏好。该持久化边界由[Host settings 支撑的偏好决策](../../../.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.md)拥有。
|
|
5
|
+
主题插件:基于 --dsw-* token 基础样式表(静态尺度 + 别名语义层)的 ThemeRuntime。该服务拥有实时主题偏好(`light`/`dark`/`system`),将 `system` 通过 `prefers-color-scheme` 解析为实际主题,并发布不可变的 `ThemeSnapshot`,通过 `theme/change` 事件通知变化;它绝不接触 DOM:ui-layout 的呈现器会应用解析后的快照(`html { color-scheme }`、`body[data-ds-dark-theme]`,以及主题的别名 token 内联变量)。来自回环地址的浏览器会先以 `system` 立即提供该服务,随后在后台加载 `ui-theme.preference`,并将每次内置主题选择通过 Host settings API 写入;其本地提供方默认将设置存入 `$DSH_HOME/settings.yaml`。收到推送的 settings 变更时或重连后,浏览器都会重新拉取该设置;连续快速选择会按操作顺序携带 namespace revision 串行写入,最新写入被拒时则重新加载持久化值。远程浏览器无法访问特权 settings API,因此它的选择仅保留在进程内。已注册的第三方主题 id 仍是进程内扩展,不会跨越内置 settings schema;移除其中任意一个都绝不会覆盖最后一个持久化的内置偏好。该持久化边界由[Host settings 支撑的偏好决策](../../../.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.zh.md)拥有。
|
|
6
6
|
|
|
7
7
|
当主机组合包含 HTTP 服务器时,主机侧紧接 `<body>` 起始标签注入同步引导代码。每份 index 响应会嵌入已注册的 Host 设置 `ui-theme.preference`,没有 settings provider 时则嵌入 `system`;浏览器按操作系统配色解析 `system`,随后在外壳加载页面渲染前设置 `color-scheme` 和 `body[data-ds-dark-theme]`。不含 HTTP 服务器的组合不受影响,插件树激活后,ThemeRuntime 与 ui-layout 仍分别是客户端状态和后续 DOM 更新的权威来源。
|
|
8
8
|
|
|
9
9
|
`src/styles/` 下有五张样式表,由 ui-theme 的动态客户端 entry 依次导入:`base.css`、`design-platform.css`、`scrollbar.css`、`gradient-shadow-text.css` 与 `shiki.css`。客户端 bundle 将其编译并注入为插件持有的全局样式,因此卸载与 HMR 会随 ui-theme 一同移除这些样式,而不会把主题 CSS 留在静态 Web 外壳中。`scrollbar.css` 是 `--dsw-alias-scrollbar-*` token 的唯一消费方,必须排在声明这些 token 的 `design-platform.css` 之后。
|
|
10
10
|
|
|
11
|
-
滚动条重新绑定约定:`scrollbar.css` 在 `body` 上把 `--dsh-scrollbar-thumb` 与 `--dsh-scrollbar-thumb-hover` 绑定到 l1(基础表面)token,两条渲染路径都读取这一组变量。高层级表面(菜单、浮层、对话框)在自己的容器上设置 `--dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2)` 与 `--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2)`;一次重新绑定即可为引擎实际走的那条路径换色。这组变量的另一个合法目标是 `transparent`,即完全不绘制滑块——[ui-sidebar](../ui-sidebar/README.md) 在指针不在栏内时就这样重新绑定自己的列。绑回 l1 那组不算重新绑定,它只是重述基础表面的默认值。`--dsh-scrollbar-width` 镜像 WebKit 滚动条的布局宽度,供需要与占布局宽度的滚动条对齐的表面使用——[ui-conversation](../ui-conversation/README.md) 用它作为覆盖 composer 座位 `right` 偏移——scrollbar-styles 规格把它与镜像规则及消费者配对检查。
|
|
11
|
+
滚动条重新绑定约定:`scrollbar.css` 在 `body` 上把 `--dsh-scrollbar-thumb` 与 `--dsh-scrollbar-thumb-hover` 绑定到 l1(基础表面)token,两条渲染路径都读取这一组变量。高层级表面(菜单、浮层、对话框)在自己的容器上设置 `--dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2)` 与 `--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2)`;一次重新绑定即可为引擎实际走的那条路径换色。这组变量的另一个合法目标是 `transparent`,即完全不绘制滑块——[ui-sidebar](../ui-sidebar/README.zh.md) 在指针不在栏内时就这样重新绑定自己的列。绑回 l1 那组不算重新绑定,它只是重述基础表面的默认值。`--dsh-scrollbar-width` 镜像 WebKit 滚动条的布局宽度,供需要与占布局宽度的滚动条对齐的表面使用——[ui-conversation](../ui-conversation/README.zh.md) 用它作为覆盖 composer 座位 `right` 偏移——scrollbar-styles 规格把它与镜像规则及消费者配对检查。
|
|
12
12
|
|
|
13
|
-
两条路径在构造上互斥。`scrollbar-width`/`scrollbar-color` 写在 `@supports not selector(::-webkit-scrollbar)` 之内,因为这两个属性中的任一个只要取非 `auto` 值,Chromium 与 Safari 就会丢弃该元素上的全部 `::-webkit-scrollbar*` 规则,`::-webkit-scrollbar-thumb:hover` 也在其中——若无条件地同时声明,`--dsh-scrollbar-thumb-hover` 在任何引擎上都不会被渲染。因此 Firefox 走标准属性,WebKit 系引擎走伪元素,hover token 只经由伪元素这条路径渲染。相关原理与实测计算值见[滚动条 Agent Note](../../../.agents/notes/implemented/bug-fix/2026-07-28-themed-scrollbars-and-reserved-gutter.md)。
|
|
13
|
+
两条路径在构造上互斥。`scrollbar-width`/`scrollbar-color` 写在 `@supports not selector(::-webkit-scrollbar)` 之内,因为这两个属性中的任一个只要取非 `auto` 值,Chromium 与 Safari 就会丢弃该元素上的全部 `::-webkit-scrollbar*` 规则,`::-webkit-scrollbar-thumb:hover` 也在其中——若无条件地同时声明,`--dsh-scrollbar-thumb-hover` 在任何引擎上都不会被渲染。因此 Firefox 走标准属性,WebKit 系引擎走伪元素,hover token 只经由伪元素这条路径渲染。相关原理与实测计算值见[滚动条 Agent Note](../../../.agents/notes/implemented/bug-fix/2026-07-28-themed-scrollbars-and-reserved-gutter.zh.md)。
|
|
14
14
|
|
|
15
15
|
## 模型体验
|
|
16
16
|
|
package/lib/index.js
CHANGED
|
@@ -19,14 +19,14 @@ const ThemeSettingsSchema = z.object({ [THEME_PREFERENCE_FIELD]: z.union([...THE
|
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region lib/types/boot-theme.js
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* Theme bootstrap row for the browser's pre-plugin interval. Each index
|
|
23
|
+
* render embeds the current durable built-in preference; the browser resolves
|
|
24
|
+
* only `system`, then writes the same DOM fields ui-layout's ThemePresenter
|
|
25
|
+
* owns after the client plugin tree activates.
|
|
26
26
|
*/
|
|
27
|
-
/** Build the inline script for one schema-validated built-in preference. */
|
|
27
|
+
/** Build the inline script body for one schema-validated built-in preference. */
|
|
28
28
|
function bootThemeScript(preference) {
|
|
29
|
-
return
|
|
29
|
+
return `(() => {
|
|
30
30
|
const preference = ${JSON.stringify(preference)}
|
|
31
31
|
const systemDark = preference === 'system'
|
|
32
32
|
&& typeof matchMedia !== 'undefined'
|
|
@@ -34,22 +34,20 @@ function bootThemeScript(preference) {
|
|
|
34
34
|
const dark = preference === 'dark' || systemDark
|
|
35
35
|
document.documentElement.style.colorScheme = dark ? 'dark' : 'light'
|
|
36
36
|
document.body.toggleAttribute('data-ds-dark-theme', dark)
|
|
37
|
-
})()
|
|
37
|
+
})()`;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
* the shell mount and module script.
|
|
42
|
-
* end, where the HTML parser has already synthesized a body.
|
|
43
|
-
* @param html - Raw application index HTML.
|
|
40
|
+
* The theme bootstrap as an injection row: an inline script immediately after
|
|
41
|
+
* the opening body tag, before the shell mount and module script.
|
|
44
42
|
* @param preference - Current Host-backed built-in preference.
|
|
45
|
-
* @returns
|
|
43
|
+
* @returns the body script row.
|
|
46
44
|
*/
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
function bootThemeInjection(preference = DEFAULT_PREFERENCE) {
|
|
46
|
+
return {
|
|
47
|
+
kind: "script",
|
|
48
|
+
placement: "body",
|
|
49
|
+
text: bootThemeScript(preference)
|
|
50
|
+
};
|
|
53
51
|
}
|
|
54
52
|
//#endregion
|
|
55
53
|
//#region lib/types/index.js
|
|
@@ -64,16 +62,17 @@ function readPreference(ctx) {
|
|
|
64
62
|
return section.preference;
|
|
65
63
|
}
|
|
66
64
|
/**
|
|
67
|
-
* Register the durable theme section
|
|
68
|
-
*
|
|
69
|
-
*
|
|
65
|
+
* Register the durable theme section when the optional settings service is
|
|
66
|
+
* composed, and answer every index injection collection with the current
|
|
67
|
+
* theme bootstrap row.
|
|
68
|
+
* @param ctx - Host context that may acquire the settings service.
|
|
70
69
|
*/
|
|
71
70
|
function apply(ctx) {
|
|
72
71
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
73
72
|
settingsCtx.settings.register(THEME_NAMESPACE, ThemeSettingsSchema);
|
|
74
73
|
});
|
|
75
|
-
ctx.
|
|
76
|
-
|
|
74
|
+
ctx.on("webserver/index-inject", (table) => {
|
|
75
|
+
table.push(bootThemeInjection(readPreference(ctx)));
|
|
77
76
|
});
|
|
78
77
|
}
|
|
79
78
|
//#endregion
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Theme bootstrap row for the browser's pre-plugin interval. Each index
|
|
3
|
+
* render embeds the current durable built-in preference; the browser resolves
|
|
4
|
+
* only `system`, then writes the same DOM fields ui-layout's ThemePresenter
|
|
5
|
+
* owns after the client plugin tree activates.
|
|
6
6
|
*/
|
|
7
|
+
import type { IndexInjection } from '@deepseek-ai/dsh-host-webserver';
|
|
7
8
|
import { type ThemePreference } from './theme-settings.ts';
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
-
* the shell mount and module script.
|
|
11
|
-
* end, where the HTML parser has already synthesized a body.
|
|
12
|
-
* @param html - Raw application index HTML.
|
|
10
|
+
* The theme bootstrap as an injection row: an inline script immediately after
|
|
11
|
+
* the opening body tag, before the shell mount and module script.
|
|
13
12
|
* @param preference - Current Host-backed built-in preference.
|
|
14
|
-
* @returns
|
|
13
|
+
* @returns the body script row.
|
|
15
14
|
*/
|
|
16
|
-
export declare function
|
|
15
|
+
export declare function bootThemeInjection(preference?: ThemePreference): IndexInjection;
|
|
17
16
|
//# sourceMappingURL=boot-theme.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
3
3
|
export { DEFAULT_PREFERENCE, THEME_PREFERENCE_FIELD, THEME_PREFERENCES, THEME_SETTINGS_NAMESPACE, type ThemePreference, type ThemeSettings, } from './theme-settings.ts';
|
|
4
4
|
/**
|
|
5
|
-
* Register the durable theme section
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Register the durable theme section when the optional settings service is
|
|
6
|
+
* composed, and answer every index injection collection with the current
|
|
7
|
+
* theme bootstrap row.
|
|
8
|
+
* @param ctx - Host context that may acquire the settings service.
|
|
8
9
|
*/
|
|
9
10
|
export declare function apply(ctx: Context): void;
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-theme",
|
|
3
3
|
"description": "Theme plugin: Host bootstrap for the pre-plugin palette; DOM-free ThemeRuntime for light/dark/system state; --dsw-* token styles and Appearance settings row",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.1-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -45,30 +45,30 @@
|
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
48
|
-
"@deepseek-ai/dsh-api-remotes": "^0.1.
|
|
49
|
-
"@deepseek-ai/dsh-client-connection": "^0.1.
|
|
50
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.
|
|
51
|
-
"@deepseek-ai/dsh-client-runtime": "^0.1.
|
|
52
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-settings": "^0.1.
|
|
48
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.2",
|
|
49
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2",
|
|
50
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
|
|
51
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
|
|
53
|
+
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
54
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
|
|
55
|
+
"@deepseek-ai/dsh-settings": "^0.1.1-rc.2"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/react": "~18.3.1",
|
|
59
59
|
"react": "^18.2.0",
|
|
60
|
-
"@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.8",
|
|
61
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.8",
|
|
62
|
-
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.8",
|
|
63
|
-
"@deepseek-ai/dsh-client-test-runtime": "^0.1.0-rc.8",
|
|
64
60
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/dsh-client-
|
|
67
|
-
"@deepseek-ai/dsh-client-
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
69
|
-
"@deepseek-ai/dsh-
|
|
70
|
-
"@deepseek-ai/dsh-
|
|
71
|
-
"@deepseek-ai/dsh-client-
|
|
61
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.1-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-settings": "^0.1.1-rc.2"
|
|
72
72
|
},
|
|
73
73
|
"files": [
|
|
74
74
|
"lib/index.js",
|