@qilin-agent/client-ui-theme 3.1.4 → 3.1.6
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 +17 -14
- package/README.md +12 -8
- package/README.zh.md +12 -8
- package/lib/client.js +671 -220
- package/lib/index.js +155 -42
- package/lib/types/boot-theme.d.ts +11 -11
- package/lib/types/client/FontFamilyRow.d.ts +19 -0
- package/lib/types/client/FontSettingsGroup.d.ts +19 -0
- package/lib/types/client/FontSizeRow.d.ts +20 -5
- package/lib/types/client/font-size-shortcuts.d.ts +13 -0
- package/lib/types/client/index.d.ts +40 -18
- package/lib/types/client/locales.d.ts +41 -9
- package/lib/types/client/settings-store.d.ts +15 -13
- package/lib/types/index.d.ts +49 -7
- package/lib/types/theme-settings.d.ts +102 -0
- package/package.json +17 -15
package/lib/index.js
CHANGED
|
@@ -21,20 +21,115 @@ const FONT_SIZE_MIN = 10;
|
|
|
21
21
|
const FONT_SIZE_MAX = 22;
|
|
22
22
|
/** Content font size when the user-settings document has no override (px). */
|
|
23
23
|
const DEFAULT_FONT_SIZE = 14;
|
|
24
|
-
/**
|
|
25
|
-
const
|
|
24
|
+
/** Independently configurable font roles. */
|
|
25
|
+
const FONT_ROLES = [
|
|
26
|
+
"text",
|
|
27
|
+
"code",
|
|
28
|
+
"terminal"
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Font sizes by role. `text` is the conversation content size; `code` is the
|
|
32
|
+
* code-block size (inline code stays 1px larger); `terminal` is the sidebar
|
|
33
|
+
* terminal cell font size.
|
|
34
|
+
*/
|
|
35
|
+
const FONT_SIZE_SPECS = {
|
|
36
|
+
text: {
|
|
37
|
+
field: FONT_SIZE_FIELD,
|
|
38
|
+
variable: "--qilin-content-font-size",
|
|
39
|
+
min: 10,
|
|
40
|
+
max: 22,
|
|
41
|
+
default: 14
|
|
42
|
+
},
|
|
43
|
+
code: {
|
|
44
|
+
field: "codeFontSize",
|
|
45
|
+
variable: "--qilin-code-font-size",
|
|
46
|
+
min: 10,
|
|
47
|
+
max: 16,
|
|
48
|
+
default: 11
|
|
49
|
+
},
|
|
50
|
+
terminal: {
|
|
51
|
+
field: "terminalFontSize",
|
|
52
|
+
variable: "--qilin-terminal-font-size",
|
|
53
|
+
min: 10,
|
|
54
|
+
max: 20,
|
|
55
|
+
default: 13
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
/** Default font sizes by role. */
|
|
59
|
+
const DEFAULT_FONT_SIZES = Object.freeze({
|
|
60
|
+
text: FONT_SIZE_SPECS.text.default,
|
|
61
|
+
code: FONT_SIZE_SPECS.code.default,
|
|
62
|
+
terminal: FONT_SIZE_SPECS.terminal.default
|
|
63
|
+
});
|
|
64
|
+
/** Settings field carrying each role's font-family list. */
|
|
65
|
+
const FONT_FAMILY_FIELDS = {
|
|
66
|
+
text: "textFontFamily",
|
|
67
|
+
code: "codeFontFamily",
|
|
68
|
+
terminal: "terminalFontFamily"
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Body variable carrying one role's normalized font list; the token sheet
|
|
72
|
+
* places it ahead of that role's built-in stack.
|
|
73
|
+
* @param kind - font role.
|
|
74
|
+
* @returns the CSS custom property name.
|
|
75
|
+
*/
|
|
76
|
+
function fontFamilyVariable(kind) {
|
|
77
|
+
return `--qilin-font-family-${kind}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Integer px schema for one role's font size.
|
|
81
|
+
* @param spec - the role's range and default.
|
|
82
|
+
* @returns the validated number schema.
|
|
83
|
+
*/
|
|
84
|
+
function fontSizeSchema(spec) {
|
|
85
|
+
return z.number().step(1).min(spec.min).max(spec.max).default(spec.default);
|
|
86
|
+
}
|
|
87
|
+
z.object({
|
|
26
88
|
[THEME_PREFERENCE_FIELD]: z.union([...THEME_PREFERENCES]).default(DEFAULT_PREFERENCE),
|
|
27
|
-
[FONT_SIZE_FIELD]:
|
|
89
|
+
[FONT_SIZE_FIELD]: fontSizeSchema(FONT_SIZE_SPECS.text),
|
|
90
|
+
[FONT_SIZE_SPECS.code.field]: fontSizeSchema(FONT_SIZE_SPECS.code),
|
|
91
|
+
[FONT_SIZE_SPECS.terminal.field]: fontSizeSchema(FONT_SIZE_SPECS.terminal),
|
|
92
|
+
[FONT_FAMILY_FIELDS.text]: z.string().default(""),
|
|
93
|
+
[FONT_FAMILY_FIELDS.code]: z.string().default(""),
|
|
94
|
+
[FONT_FAMILY_FIELDS.terminal]: z.string().default("")
|
|
28
95
|
});
|
|
96
|
+
/** CSS Fonts generic and system family keywords, which must stay unquoted. */
|
|
97
|
+
const GENERIC_FAMILIES = new Set([
|
|
98
|
+
"serif",
|
|
99
|
+
"sans-serif",
|
|
100
|
+
"monospace",
|
|
101
|
+
"cursive",
|
|
102
|
+
"fantasy",
|
|
103
|
+
"system-ui",
|
|
104
|
+
"ui-serif",
|
|
105
|
+
"ui-sans-serif",
|
|
106
|
+
"ui-monospace",
|
|
107
|
+
"ui-rounded",
|
|
108
|
+
"emoji",
|
|
109
|
+
"math",
|
|
110
|
+
"fangsong",
|
|
111
|
+
"-apple-system",
|
|
112
|
+
"blinkmacsystemfont"
|
|
113
|
+
]);
|
|
114
|
+
/**
|
|
115
|
+
* Normalize user input into a CSS font-family list. Names are comma separated;
|
|
116
|
+
* quotes, backslashes, angle brackets, and control characters are dropped, and
|
|
117
|
+
* every non-generic name is double-quoted, so the result is always a valid list
|
|
118
|
+
* safe to embed in inline CSS and boot scripts. Normalizing a result returns it unchanged.
|
|
119
|
+
* @param value - user-entered or stored font list.
|
|
120
|
+
* @returns the normalized list, or `''` when no family name remains.
|
|
121
|
+
*/
|
|
122
|
+
function normalizeFontFamily(value) {
|
|
123
|
+
return value.split(",").map((name) => name.replace(/["'\\<>\u0000-\u001f\u007f]/gu, "").replace(/\s+/gu, " ").trim()).filter((name) => name !== "").map((name) => GENERIC_FAMILIES.has(name.toLowerCase()) ? name : `"${name}"`).join(", ");
|
|
124
|
+
}
|
|
29
125
|
//#endregion
|
|
30
126
|
//#region lib/types/boot-theme.js
|
|
31
127
|
/**
|
|
32
128
|
* Theme bootstrap row for the browser's pre-plugin interval. Each index
|
|
33
|
-
* render embeds the current durable built-in preference,
|
|
34
|
-
*
|
|
35
|
-
* execution; the body script installs the palette selector and
|
|
36
|
-
*
|
|
37
|
-
* activates.
|
|
129
|
+
* render embeds the current durable built-in preference, font sizes, and
|
|
130
|
+
* font-family lists. Head CSS colors the document canvas before script
|
|
131
|
+
* execution; the body script installs the palette selector and font variables
|
|
132
|
+
* that the client presenters adopt.
|
|
38
133
|
*/
|
|
39
134
|
const LIGHT_BACKGROUND = "#fff";
|
|
40
135
|
const DARK_BACKGROUND = "#151517";
|
|
@@ -46,8 +141,13 @@ function bootThemeStyle(preference) {
|
|
|
46
141
|
if (preference === "dark") return dark;
|
|
47
142
|
return `${light}@media(prefers-color-scheme:dark){${dark}}`;
|
|
48
143
|
}
|
|
49
|
-
/** Build the body script that installs the palette selector
|
|
50
|
-
function bootThemeBodyScript(preference,
|
|
144
|
+
/** Build the body script that installs the palette selector and font variables. */
|
|
145
|
+
function bootThemeBodyScript(preference, fontSizes, fontFamilies) {
|
|
146
|
+
const sizes = FONT_ROLES.map((role) => `\n document.body.style.setProperty(${JSON.stringify(FONT_SIZE_SPECS[role].variable)}, ${JSON.stringify(`${fontSizes[role]}px`)})`).join("");
|
|
147
|
+
const families = FONT_ROLES.flatMap((kind) => {
|
|
148
|
+
const list = normalizeFontFamily(fontFamilies[kind]);
|
|
149
|
+
return list === "" ? [] : [`\n document.body.style.setProperty(${JSON.stringify(fontFamilyVariable(kind))}, ${JSON.stringify(list)})`];
|
|
150
|
+
}).join("");
|
|
51
151
|
return `(() => {
|
|
52
152
|
const preference = ${JSON.stringify(preference)}
|
|
53
153
|
const systemDark = preference === 'system'
|
|
@@ -55,58 +155,71 @@ function bootThemeBodyScript(preference, fontSize) {
|
|
|
55
155
|
&& matchMedia('(prefers-color-scheme: dark)').matches
|
|
56
156
|
const dark = preference === 'dark' || systemDark
|
|
57
157
|
document.documentElement.dataset.dsThemeSource = preference
|
|
58
|
-
document.body.toggleAttribute('data-ds-dark-theme', dark)
|
|
59
|
-
document.body.style.setProperty('--qilin-content-font-size', ${JSON.stringify(`${fontSize}px`)})
|
|
158
|
+
document.body.toggleAttribute('data-ds-dark-theme', dark)${sizes}${families}
|
|
60
159
|
})()`;
|
|
61
160
|
}
|
|
62
161
|
/**
|
|
63
162
|
* Theme bootstrap rows: head CSS colors the document canvas before
|
|
64
|
-
* first paint, then the body script installs the palette selector and
|
|
65
|
-
*
|
|
163
|
+
* first paint, then the body script installs the palette selector and font
|
|
164
|
+
* size and font families before the shell mount and module script.
|
|
66
165
|
* @param preference - Current Host-backed built-in preference.
|
|
67
|
-
* @param
|
|
68
|
-
* @
|
|
166
|
+
* @param fontSizes - Current Host-backed font sizes in px by role.
|
|
167
|
+
* @param fontFamilies - Current Host-backed font lists; each is normalized before embedding.
|
|
168
|
+
* @returns head and body script rows in execution order.
|
|
69
169
|
*/
|
|
70
|
-
function bootThemeInjections(preference = DEFAULT_PREFERENCE,
|
|
170
|
+
function bootThemeInjections(preference = DEFAULT_PREFERENCE, fontSizes = DEFAULT_FONT_SIZES, fontFamilies = {
|
|
171
|
+
text: "",
|
|
172
|
+
code: "",
|
|
173
|
+
terminal: ""
|
|
174
|
+
}) {
|
|
71
175
|
return [{
|
|
72
176
|
kind: "style",
|
|
73
177
|
text: bootThemeStyle(preference)
|
|
74
178
|
}, {
|
|
75
179
|
kind: "script",
|
|
76
180
|
placement: "body",
|
|
77
|
-
text: bootThemeBodyScript(preference,
|
|
181
|
+
text: bootThemeBodyScript(preference, fontSizes, fontFamilies)
|
|
78
182
|
}];
|
|
79
183
|
}
|
|
80
184
|
//#endregion
|
|
81
185
|
//#region lib/types/index.js
|
|
82
|
-
/** Host registration for the browser theme preference and pre-plugin palette. */
|
|
83
|
-
const THEME_NAMESPACE = THEME_SETTINGS_NAMESPACE;
|
|
84
|
-
/** Read the registered theme section or the schema defaults without a settings provider. */
|
|
85
|
-
function readSection(ctx) {
|
|
86
|
-
const fallback = {
|
|
87
|
-
preference: DEFAULT_PREFERENCE,
|
|
88
|
-
fontSize: 14
|
|
89
|
-
};
|
|
90
|
-
const settings = ctx.get("settings");
|
|
91
|
-
if (settings === void 0) return fallback;
|
|
92
|
-
const section = settings.get(THEME_NAMESPACE);
|
|
93
|
-
if (section === void 0) return fallback;
|
|
94
|
-
return section;
|
|
95
|
-
}
|
|
96
186
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
|
|
187
|
+
* Font-family lists read from the live config, keyed by role.
|
|
188
|
+
* @param families - the detached per-role lists.
|
|
189
|
+
* @returns the frozen per-role font-family lists.
|
|
190
|
+
*/
|
|
191
|
+
function sectionFontFamilies(families) {
|
|
192
|
+
return Object.freeze({ ...families });
|
|
193
|
+
}
|
|
194
|
+
/** Live theme and typography preferences. */
|
|
195
|
+
const Config = z.object({
|
|
196
|
+
preference: z.union([...THEME_PREFERENCES]).default(DEFAULT_PREFERENCE).volatile(),
|
|
197
|
+
fontSize: fontSizeSchema(FONT_SIZE_SPECS.text).volatile(),
|
|
198
|
+
codeFontSize: fontSizeSchema(FONT_SIZE_SPECS.code).volatile(),
|
|
199
|
+
terminalFontSize: fontSizeSchema(FONT_SIZE_SPECS.terminal).volatile(),
|
|
200
|
+
textFontFamily: z.string().default("").volatile(),
|
|
201
|
+
codeFontFamily: z.string().default("").volatile(),
|
|
202
|
+
terminalFontFamily: z.string().default("").volatile()
|
|
203
|
+
});
|
|
204
|
+
/** Supply the current palette before browser plugins start.
|
|
205
|
+
* @param ctx Host plugin context.
|
|
206
|
+
* @param config Validated live theme preferences.
|
|
101
207
|
*/
|
|
102
|
-
function apply(ctx) {
|
|
103
|
-
ctx.inject(["settings"], (
|
|
104
|
-
|
|
208
|
+
function apply(ctx, config) {
|
|
209
|
+
ctx.inject(["settings"], (child) => {
|
|
210
|
+
child.effect(() => child.settings.configure({ auto: false }, ctx.fiber));
|
|
105
211
|
});
|
|
106
212
|
ctx.on("webserver/index-inject", (table) => {
|
|
107
|
-
|
|
108
|
-
|
|
213
|
+
table.push(...bootThemeInjections(config.preference.get(), {
|
|
214
|
+
text: config.fontSize.get(),
|
|
215
|
+
code: config.codeFontSize.get(),
|
|
216
|
+
terminal: config.terminalFontSize.get()
|
|
217
|
+
}, sectionFontFamilies({
|
|
218
|
+
text: config.textFontFamily.get(),
|
|
219
|
+
code: config.codeFontFamily.get(),
|
|
220
|
+
terminal: config.terminalFontFamily.get()
|
|
221
|
+
})));
|
|
109
222
|
}, { prepend: true });
|
|
110
223
|
}
|
|
111
224
|
//#endregion
|
|
112
|
-
export { DEFAULT_FONT_SIZE, DEFAULT_PREFERENCE, FONT_SIZE_FIELD, FONT_SIZE_MAX, FONT_SIZE_MIN, THEME_PREFERENCES, THEME_PREFERENCE_FIELD, THEME_SETTINGS_NAMESPACE, apply };
|
|
225
|
+
export { Config, DEFAULT_FONT_SIZE, DEFAULT_PREFERENCE, FONT_FAMILY_FIELDS, FONT_ROLES, FONT_SIZE_FIELD, FONT_SIZE_MAX, FONT_SIZE_MIN, FONT_SIZE_SPECS, THEME_PREFERENCES, THEME_PREFERENCE_FIELD, THEME_SETTINGS_NAMESPACE, apply, sectionFontFamilies };
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme bootstrap row for the browser's pre-plugin interval. Each index
|
|
3
|
-
* render embeds the current durable built-in preference,
|
|
4
|
-
*
|
|
5
|
-
* execution; the body script installs the palette selector and
|
|
6
|
-
*
|
|
7
|
-
* activates.
|
|
3
|
+
* render embeds the current durable built-in preference, font sizes, and
|
|
4
|
+
* font-family lists. Head CSS colors the document canvas before script
|
|
5
|
+
* execution; the body script installs the palette selector and font variables
|
|
6
|
+
* that the client presenters adopt.
|
|
8
7
|
*/
|
|
9
8
|
import type { IndexInjection } from '@qilin-agent/host-webserver';
|
|
10
|
-
import { type ThemePreference } from './theme-settings.ts';
|
|
9
|
+
import { type FontFamilies, type FontSizes, type ThemePreference } from './theme-settings.ts';
|
|
11
10
|
/**
|
|
12
11
|
* Theme bootstrap rows: head CSS colors the document canvas before
|
|
13
|
-
* first paint, then the body script installs the palette selector and
|
|
14
|
-
*
|
|
12
|
+
* first paint, then the body script installs the palette selector and font
|
|
13
|
+
* size and font families before the shell mount and module script.
|
|
15
14
|
* @param preference - Current Host-backed built-in preference.
|
|
16
|
-
* @param
|
|
17
|
-
* @
|
|
15
|
+
* @param fontSizes - Current Host-backed font sizes in px by role.
|
|
16
|
+
* @param fontFamilies - Current Host-backed font lists; each is normalized before embedding.
|
|
17
|
+
* @returns head and body script rows in execution order.
|
|
18
18
|
*/
|
|
19
|
-
export declare function bootThemeInjections(preference?: ThemePreference,
|
|
19
|
+
export declare function bootThemeInjections(preference?: ThemePreference, fontSizes?: FontSizes, fontFamilies?: FontFamilies): IndexInjection[];
|
|
20
20
|
//# sourceMappingURL=boot-theme.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime, PropsStore } from '@qilin-agent/client-ui-slots';
|
|
2
|
+
import { type FontRole } from '../theme-settings.ts';
|
|
3
|
+
import type { createFontRowStore } from './settings-store.ts';
|
|
4
|
+
/** Injected business face: the row's font role and its write. */
|
|
5
|
+
export interface FontFamilyRowInjected {
|
|
6
|
+
/** Font role this row edits. */
|
|
7
|
+
role: FontRole;
|
|
8
|
+
/** Change this role's font list (normalized by the theme service). */
|
|
9
|
+
setFontFamily: (value: string) => void;
|
|
10
|
+
}
|
|
11
|
+
/** Full component props: runtime share + store share + locale seat + injected face. */
|
|
12
|
+
export type FontFamilyRowComponentProps = PropsRuntime<'settings.general.item'> & PropsStore<ReturnType<typeof createFontRowStore>> & PropsLocale<'settings.theme'> & FontFamilyRowInjected;
|
|
13
|
+
/**
|
|
14
|
+
* Render one font-family row.
|
|
15
|
+
* @param props - composed slot props.
|
|
16
|
+
* @returns the row element tree.
|
|
17
|
+
*/
|
|
18
|
+
export declare function FontFamilyRow({ t, role, setFontFamily, useStore }: FontFamilyRowComponentProps): import("react").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=FontFamilyRow.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime, PropsStore } from '@qilin-agent/client-ui-slots';
|
|
2
|
+
import type { FontRole } from '../theme-settings.ts';
|
|
3
|
+
import type { createFontRowStore } from './settings-store.ts';
|
|
4
|
+
/** Injected business face: font writes by role. */
|
|
5
|
+
export interface FontSettingsInjected {
|
|
6
|
+
/** Change one role's font list (normalized by the theme service). */
|
|
7
|
+
setFontFamily: (role: FontRole, value: string) => void;
|
|
8
|
+
/** Change one role's font size (integer px within its FONT_SIZE_SPECS range). */
|
|
9
|
+
setFontSize: (role: FontRole, px: number) => void;
|
|
10
|
+
}
|
|
11
|
+
/** Full component props: runtime share + store share + locale seat + injected face. */
|
|
12
|
+
export type FontSettingsGroupProps = PropsRuntime<'settings.general.item'> & PropsStore<ReturnType<typeof createFontRowStore>> & PropsLocale<'settings.theme'> & FontSettingsInjected;
|
|
13
|
+
/**
|
|
14
|
+
* Render the text font-size row and its expandable font settings.
|
|
15
|
+
* @param props - composed slot props.
|
|
16
|
+
* @returns the text size row and, when expanded, the font rows.
|
|
17
|
+
*/
|
|
18
|
+
export declare function FontSettingsGroup({ setFontFamily, setFontSize, ...shared }: FontSettingsGroupProps): import("react").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=FontSettingsGroup.d.ts.map
|
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
import type { PropsLocale, PropsRuntime, PropsStore } from '@qilin-agent/client-ui-slots';
|
|
2
|
-
import type
|
|
3
|
-
|
|
2
|
+
import { type FontRole } from '../theme-settings.ts';
|
|
3
|
+
import type { createFontRowStore } from './settings-store.ts';
|
|
4
|
+
/** Injected business face: the row's font role and its write (t rides the standard locale seat). */
|
|
4
5
|
export interface FontSizeRowInjected {
|
|
5
|
-
/**
|
|
6
|
+
/** Font role this row edits. */
|
|
7
|
+
role: FontRole;
|
|
8
|
+
/** Change this role's font size (integer px within its FONT_SIZE_SPECS range). */
|
|
6
9
|
setFontSize: (px: number) => void;
|
|
7
10
|
}
|
|
8
11
|
/** Full component props: runtime share + store share + locale seat + injected face. */
|
|
9
|
-
export type FontSizeRowComponentProps = PropsRuntime<'settings.general.item'> & PropsStore<ReturnType<typeof
|
|
12
|
+
export type FontSizeRowComponentProps = PropsRuntime<'settings.general.item'> & PropsStore<ReturnType<typeof createFontRowStore>> & PropsLocale<'settings.theme'> & FontSizeRowInjected & {
|
|
13
|
+
/** Disclosure button after the unit label; the font settings group passes it for the text row. */
|
|
14
|
+
expander?: FontSizeRowExpander | undefined;
|
|
15
|
+
};
|
|
16
|
+
/** Controlled disclosure state for the button that expands more font settings. */
|
|
17
|
+
export interface FontSizeRowExpander {
|
|
18
|
+
/** Whether the controlled region is shown. */
|
|
19
|
+
open: boolean;
|
|
20
|
+
/** Id of the controlled region. */
|
|
21
|
+
controls: string;
|
|
22
|
+
/** Toggle the region. */
|
|
23
|
+
onToggle: () => void;
|
|
24
|
+
}
|
|
10
25
|
/**
|
|
11
26
|
* Render the font-size row.
|
|
12
27
|
* @param props - composed slot props.
|
|
13
28
|
* @returns the row element tree.
|
|
14
29
|
*/
|
|
15
|
-
export declare function FontSizeRow({ t, setFontSize, useStore }: FontSizeRowComponentProps): import("react").JSX.Element;
|
|
30
|
+
export declare function FontSizeRow({ t, role, setFontSize, useStore, expander }: FontSizeRowComponentProps): import("react").JSX.Element;
|
|
16
31
|
//# sourceMappingURL=FontSizeRow.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Desktop keyboard shortcuts that step all three font sizes together. */
|
|
2
|
+
import type { Context as ClientContext } from '@qilin-agent/kylin';
|
|
3
|
+
/**
|
|
4
|
+
* Register the desktop font-size keys and consume their gestures.
|
|
5
|
+
* The web client keeps the browser's own zoom for these keys, so the
|
|
6
|
+
* registration exists only where the keyboard service reports the desktop
|
|
7
|
+
* runtime.
|
|
8
|
+
* @param ctx - client cordis context owning the registration effects.
|
|
9
|
+
* @param namespace - locale namespace carrying the shortcut labels (this package's own).
|
|
10
|
+
* @param adjust - applies one +1 or -1 px step to every font-size role.
|
|
11
|
+
*/
|
|
12
|
+
export declare function installFontSizeShortcuts(ctx: ClientContext, namespace: 'settings.theme', adjust: (delta: 1 | -1) => void): void;
|
|
13
|
+
//# sourceMappingURL=font-size-shortcuts.d.ts.map
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser theme registry over the `--
|
|
2
|
+
* Browser theme registry over the `--dsw-*` token stylesheets. The service
|
|
3
3
|
* owns the live theme preference (light/dark/system), resolves `system` through
|
|
4
4
|
* `prefers-color-scheme`, and publishes immutable snapshots; it never touches
|
|
5
5
|
* the DOM — ui-layout's presenter consumes the resolved snapshot. The Host
|
|
6
6
|
* settings scope loads and stores the preference in the user-settings
|
|
7
|
-
* document. The plugin also registers the Appearance
|
|
8
|
-
* settings General section — the theme feature owns its own settings
|
|
7
|
+
* document. The plugin also registers the Appearance and font settings rows
|
|
8
|
+
* into the settings General section — the theme feature owns its own settings
|
|
9
|
+
* surface.
|
|
9
10
|
*/
|
|
10
11
|
import type { Context as ClientContext } from '@qilin-agent/kylin';
|
|
11
12
|
import type { ConfigForm } from '@qilin-agent/client-ui-settings/client';
|
|
12
13
|
import { type ThemeKey } from './locales.ts';
|
|
13
|
-
import { type ThemePreference, type ThemeSettings } from '../theme-settings.ts';
|
|
14
|
-
export type { FontSizeRowComponentProps, FontSizeRowInjected } from './FontSizeRow.tsx';
|
|
14
|
+
import { type FontFamilies, type FontRole, type FontSizes, type ThemePreference, type ThemeSettings } from '../theme-settings.ts';
|
|
15
15
|
export type { AppearanceRowComponentProps, AppearanceRowInjected } from './AppearanceRow.tsx';
|
|
16
|
-
export type {
|
|
16
|
+
export type { FontSettingsGroupProps, FontSettingsInjected } from './FontSettingsGroup.tsx';
|
|
17
|
+
export type { AppearanceRowState, FontRowState } from './settings-store.ts';
|
|
17
18
|
export type { ThemeKey } from './locales.ts';
|
|
18
|
-
export type { ThemePreference, ThemeSettings } from '../theme-settings.ts';
|
|
19
|
+
export type { FontFamilies, FontRole, FontSizes, ThemePreference, ThemeSettings } from '../theme-settings.ts';
|
|
19
20
|
/** Namespace owning this feature's settings-row copy. */
|
|
20
21
|
export declare const SETTINGS_NS = "settings.theme";
|
|
21
22
|
declare module '@qilin-agent/client-ui-slots' {
|
|
@@ -24,7 +25,7 @@ declare module '@qilin-agent/client-ui-slots' {
|
|
|
24
25
|
'settings.theme': ThemeKey;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
|
-
/** Theme token dictionary: --
|
|
28
|
+
/** Theme token dictionary: --dsw-alias-* overrides keyed by variable name. */
|
|
28
29
|
export type ThemeTokens = Record<string, string>;
|
|
29
30
|
/**
|
|
30
31
|
* One override-layer token value: both palette modes are mandatory (repeat
|
|
@@ -55,8 +56,10 @@ export interface ThemeDefinition {
|
|
|
55
56
|
export interface ThemeSnapshot {
|
|
56
57
|
/** The persisted preference (may be `system`). */
|
|
57
58
|
preference: ThemePreference;
|
|
58
|
-
/**
|
|
59
|
-
|
|
59
|
+
/** Integer px font sizes by role, each within its `FONT_SIZE_SPECS` range (`text` is the conversation content size). */
|
|
60
|
+
fontSizes: FontSizes;
|
|
61
|
+
/** Normalized user font lists by role; `''` selects the role's built-in stack. */
|
|
62
|
+
fontFamilies: FontFamilies;
|
|
60
63
|
/**
|
|
61
64
|
* The resolved active theme (`system` resolved via prefers-color-scheme)
|
|
62
65
|
* with override layers folded into its tokens (seq order, later layers win
|
|
@@ -111,8 +114,11 @@ export declare class ThemeRuntime {
|
|
|
111
114
|
private readonly host;
|
|
112
115
|
private themes;
|
|
113
116
|
private preference;
|
|
114
|
-
private
|
|
117
|
+
private fontSizes;
|
|
118
|
+
private fontFamilies;
|
|
115
119
|
private revision;
|
|
120
|
+
/** Own settings writes not yet settled; adoption waits for zero so a Host echo of an earlier write cannot revert a later local change. */
|
|
121
|
+
private pendingWrites;
|
|
116
122
|
private snapshot;
|
|
117
123
|
private readonly media;
|
|
118
124
|
/** Override layers by source; seq (monotonic) is the stacking order. */
|
|
@@ -142,12 +148,28 @@ export declare class ThemeRuntime {
|
|
|
142
148
|
*/
|
|
143
149
|
setTheme(id: string): void;
|
|
144
150
|
/**
|
|
145
|
-
* Change
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* @param px - integer px within
|
|
151
|
+
* Change one role's font size — the only font-size write entry. Accepted
|
|
152
|
+
* values are written through the settings scope and emit `theme/change`.
|
|
153
|
+
* @param role - font role.
|
|
154
|
+
* @param px - integer px within the role's `FONT_SIZE_SPECS` range; out-of-range or fractional values throw.
|
|
149
155
|
*/
|
|
150
|
-
setFontSize(px: number): void;
|
|
156
|
+
setFontSize(role: FontRole, px: number): void;
|
|
157
|
+
/**
|
|
158
|
+
* Step all font sizes within their own ranges and save changed fields in one mutation.
|
|
159
|
+
* Emits one `theme/change`; no write or event occurs when every role is at its limit.
|
|
160
|
+
* @param delta - one pixel to add or remove from each role's current size.
|
|
161
|
+
*/
|
|
162
|
+
private adjustFontSizes;
|
|
163
|
+
/**
|
|
164
|
+
* Change one role's font list — the only font-family write entry. The value
|
|
165
|
+
* is normalized, written through the settings scope, and emits `theme/change`
|
|
166
|
+
* when the normalized list differs.
|
|
167
|
+
* @param role - font role.
|
|
168
|
+
* @param value - comma-separated family names; a value without names restores the built-in stack.
|
|
169
|
+
*/
|
|
170
|
+
setFontFamily(role: FontRole, value: string): void;
|
|
171
|
+
/** Queue one settings write, then adopt the durable section once no own write remains. */
|
|
172
|
+
private write;
|
|
151
173
|
/** Adopt the scope's accepted durable preference without writing it back. */
|
|
152
174
|
private adopt;
|
|
153
175
|
/**
|
|
@@ -194,8 +216,8 @@ export declare class ThemeRuntime {
|
|
|
194
216
|
export declare const inject: string[];
|
|
195
217
|
/**
|
|
196
218
|
* Client plugin body: provide the theme service and register the
|
|
197
|
-
* feature-owned Appearance
|
|
198
|
-
*
|
|
219
|
+
* feature-owned Appearance and font settings rows into the General section's item
|
|
220
|
+
* slot (a feature owns its settings surface).
|
|
199
221
|
* @param ctx - client cordis context.
|
|
200
222
|
*/
|
|
201
223
|
export declare function apply(ctx: ClientContext): void;
|
|
@@ -1,15 +1,31 @@
|
|
|
1
|
-
/** `settings.theme` namespace dictionaries (the Appearance
|
|
1
|
+
/** `settings.theme` namespace dictionaries (the Appearance and font settings rows' copy). */
|
|
2
2
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
3
3
|
export declare const zh: {
|
|
4
4
|
'appearance.title': string;
|
|
5
5
|
'appearance.light': string;
|
|
6
6
|
'appearance.dark': string;
|
|
7
7
|
'appearance.system': string;
|
|
8
|
-
'fontSize.title': string;
|
|
9
|
-
'fontSize.description': string;
|
|
8
|
+
'fontSize.text.title': string;
|
|
9
|
+
'fontSize.text.description': string;
|
|
10
|
+
'fontSize.text.increase': string;
|
|
11
|
+
'fontSize.text.decrease': string;
|
|
12
|
+
'fontSize.code.title': string;
|
|
13
|
+
'fontSize.code.description': string;
|
|
14
|
+
'fontSize.code.increase': string;
|
|
15
|
+
'fontSize.code.decrease': string;
|
|
16
|
+
'fontSize.terminal.title': string;
|
|
17
|
+
'fontSize.terminal.description': string;
|
|
18
|
+
'fontSize.terminal.increase': string;
|
|
19
|
+
'fontSize.terminal.decrease': string;
|
|
10
20
|
'fontSize.unit': string;
|
|
11
|
-
'
|
|
12
|
-
'
|
|
21
|
+
'fontFamily.text.title': string;
|
|
22
|
+
'fontFamily.text.description': string;
|
|
23
|
+
'fontFamily.code.title': string;
|
|
24
|
+
'fontFamily.code.description': string;
|
|
25
|
+
'fontFamily.terminal.title': string;
|
|
26
|
+
'fontFamily.terminal.description': string;
|
|
27
|
+
'fontFamily.placeholder': string;
|
|
28
|
+
'fontSize.more': string;
|
|
13
29
|
};
|
|
14
30
|
/** The settings.theme namespace key union. */
|
|
15
31
|
export type ThemeKey = keyof typeof zh;
|
|
@@ -19,10 +35,26 @@ export declare const en: {
|
|
|
19
35
|
'appearance.light': string;
|
|
20
36
|
'appearance.dark': string;
|
|
21
37
|
'appearance.system': string;
|
|
22
|
-
'fontSize.title': string;
|
|
23
|
-
'fontSize.description': string;
|
|
38
|
+
'fontSize.text.title': string;
|
|
39
|
+
'fontSize.text.description': string;
|
|
40
|
+
'fontSize.text.increase': string;
|
|
41
|
+
'fontSize.text.decrease': string;
|
|
42
|
+
'fontSize.code.title': string;
|
|
43
|
+
'fontSize.code.description': string;
|
|
44
|
+
'fontSize.code.increase': string;
|
|
45
|
+
'fontSize.code.decrease': string;
|
|
46
|
+
'fontSize.terminal.title': string;
|
|
47
|
+
'fontSize.terminal.description': string;
|
|
48
|
+
'fontSize.terminal.increase': string;
|
|
49
|
+
'fontSize.terminal.decrease': string;
|
|
24
50
|
'fontSize.unit': string;
|
|
25
|
-
'
|
|
26
|
-
'
|
|
51
|
+
'fontFamily.text.title': string;
|
|
52
|
+
'fontFamily.text.description': string;
|
|
53
|
+
'fontFamily.code.title': string;
|
|
54
|
+
'fontFamily.code.description': string;
|
|
55
|
+
'fontFamily.terminal.title': string;
|
|
56
|
+
'fontFamily.terminal.description': string;
|
|
57
|
+
'fontFamily.placeholder': string;
|
|
58
|
+
'fontSize.more': string;
|
|
27
59
|
};
|
|
28
60
|
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Appearance and
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Appearance and font row slot stores: mirrors of the theme service
|
|
3
|
+
* snapshot. The plugin's apply-world change listener is the only writer; the
|
|
4
|
+
* row components read via props.useStore.
|
|
5
5
|
*/
|
|
6
6
|
import { type EngineStoreHandle } from '@qilin-agent/client-store';
|
|
7
|
-
import { type ThemePreference } from '../theme-settings.ts';
|
|
8
|
-
/** Store state mirrored from the theme snapshot
|
|
7
|
+
import { type FontFamilies, type FontSizes, type ThemePreference } from '../theme-settings.ts';
|
|
8
|
+
/** Store state mirrored from the theme snapshot. */
|
|
9
9
|
export interface AppearanceRowState {
|
|
10
10
|
/** Persisted preference (selection state reads this, never the resolved active theme). */
|
|
11
11
|
preference: ThemePreference;
|
|
@@ -21,21 +21,23 @@ type AppearanceRowActions = {
|
|
|
21
21
|
* @returns the store handle.
|
|
22
22
|
*/
|
|
23
23
|
export declare function createAppearanceRowStore(): EngineStoreHandle<AppearanceRowState, AppearanceRowActions>;
|
|
24
|
-
/** Store state mirrored from the theme snapshot's
|
|
25
|
-
export interface
|
|
26
|
-
/** Persisted
|
|
27
|
-
|
|
24
|
+
/** Store state mirrored from the theme snapshot's fonts (shared by the font-size row and the font settings group). */
|
|
25
|
+
export interface FontRowState {
|
|
26
|
+
/** Persisted font sizes in px by role. */
|
|
27
|
+
fontSizes: FontSizes;
|
|
28
|
+
/** Persisted normalized font lists by role. */
|
|
29
|
+
fontFamilies: FontFamilies;
|
|
28
30
|
/** Service revision; -1 until first sync so revision 0 lands as a change. */
|
|
29
31
|
revision: number;
|
|
30
32
|
}
|
|
31
33
|
/** Declared action shape giving the exported factory a stable return type. */
|
|
32
|
-
type
|
|
33
|
-
sync: (draft:
|
|
34
|
+
type FontRowActions = {
|
|
35
|
+
sync: (draft: FontRowState, fontSizes: FontSizes, fontFamilies: FontFamilies, revision: number) => void;
|
|
34
36
|
};
|
|
35
37
|
/**
|
|
36
|
-
* Declares the
|
|
38
|
+
* Declares the font rows' state and write surface.
|
|
37
39
|
* @returns the store handle.
|
|
38
40
|
*/
|
|
39
|
-
export declare function
|
|
41
|
+
export declare function createFontRowStore(): EngineStoreHandle<FontRowState, FontRowActions>;
|
|
40
42
|
export {};
|
|
41
43
|
//# sourceMappingURL=settings-store.d.ts.map
|