dsh-dracula-theme 0.1.0
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/LICENSE +21 -0
- package/README.md +58 -0
- package/README.zh.md +57 -0
- package/cordis.patch.yml +7 -0
- package/lib/client.js +846 -0
- package/lib/index.js +13 -0
- package/package.json +59 -0
- package/themes/dracula-soft.json +189 -0
- package/themes/dracula.json +189 -0
package/lib/client.js
ADDED
|
@@ -0,0 +1,846 @@
|
|
|
1
|
+
// dsh-dracula-theme — browser half (client plugin bundle). GENERATED FILE:
|
|
2
|
+
// run `node scripts/gen-themes.mjs` to regenerate from lib/client.tpl.js.
|
|
3
|
+
//
|
|
4
|
+
// Loaded by dsh-client-modules at /plugins/dsh-dracula-theme/client.js and
|
|
5
|
+
// executed through the vendored cordis Loader's lazy-CJS module table
|
|
6
|
+
// (window.__ModuleLoader__.load). The registered id MUST be the package name
|
|
7
|
+
// ("dsh-dracula-theme"): client-modules keys its boot-graph rows by the
|
|
8
|
+
// loader entry's package name and verifies the bundle registers exactly that
|
|
9
|
+
// id. The factory body is plain CJS with require() resolved against the
|
|
10
|
+
// shell's module table — the same shape the shipped ui-* packages' tsdown
|
|
11
|
+
// bundles emit.
|
|
12
|
+
//
|
|
13
|
+
// Structure modeled on dsh-catppuccin (MIT, zhijun-dai) — thanks.
|
|
14
|
+
window.__ModuleLoader__.load({
|
|
15
|
+
id: "dsh-dracula-theme",
|
|
16
|
+
factory: (require) => {
|
|
17
|
+
var module = { exports: {} };
|
|
18
|
+
var exports = module.exports;
|
|
19
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
20
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
21
|
+
let _runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
22
|
+
|
|
23
|
+
//#region dsh-dracula: definitions
|
|
24
|
+
/** The settings row's locale namespace. */
|
|
25
|
+
const SETTINGS_NS = "settings.dracula";
|
|
26
|
+
/** localStorage key holding the selected theme id. */
|
|
27
|
+
const STORAGE_KEY = "dsh-dracula:skin";
|
|
28
|
+
/** Sentinel meaning "no custom theme — follow the built-in appearance". */
|
|
29
|
+
const DEFAULT_SKIN = "system";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The Dracula theme catalog, generated from palette/dracula.json.
|
|
33
|
+
* Each entry is a third-party theme for the built-in ThemeRuntime:
|
|
34
|
+
* an id, the base palette it builds on (colorScheme drives
|
|
35
|
+
* body[data-ds-dark-theme]), and --dsw-alias-* / --dsw-specific-* /
|
|
36
|
+
* --shiki-* overrides applied as inline custom properties on <body>
|
|
37
|
+
* by ui-layout's ThemePresenter, plus the underlying --dsw-static-*
|
|
38
|
+
* ramps. Values are concrete CSS colors (no var() indirection).
|
|
39
|
+
*/
|
|
40
|
+
const SKINS = [
|
|
41
|
+
{
|
|
42
|
+
"id": "dracula",
|
|
43
|
+
"name": "Dracula",
|
|
44
|
+
"colorScheme": "dark",
|
|
45
|
+
"tokens": {
|
|
46
|
+
"--dsw-static-neutral-50": "#efefe9",
|
|
47
|
+
"--dsw-static-neutral-100": "#e2e2da",
|
|
48
|
+
"--dsw-static-neutral-200": "#cdcdc5",
|
|
49
|
+
"--dsw-static-neutral-300": "#b6b6ae",
|
|
50
|
+
"--dsw-static-neutral-400": "#8f8f96",
|
|
51
|
+
"--dsw-static-neutral-500": "#6d6d7a",
|
|
52
|
+
"--dsw-static-neutral-550": "#5c5c6b",
|
|
53
|
+
"--dsw-static-neutral-600": "#4d4d5e",
|
|
54
|
+
"--dsw-static-neutral-700": "#3e3e50",
|
|
55
|
+
"--dsw-static-neutral-800": "#30303f",
|
|
56
|
+
"--dsw-static-neutral-850": "#282a36",
|
|
57
|
+
"--dsw-static-neutral-900": "#20212b",
|
|
58
|
+
"--dsw-static-neutral-1000": "#191a21",
|
|
59
|
+
"--dsw-static-neutral-description": "Anchor stops of the neutral grayscale ramp (--dsw-static-neutral-*), lightest (00) to darkest (1000). The official port does not override this ramp; values are Dracula-gray interpolations for a self-contained theme.",
|
|
60
|
+
"--dsw-static-neutral-00": "#f8f8f2",
|
|
61
|
+
"--dsw-static-neutral-bluish-50": "#f8f8f2",
|
|
62
|
+
"--dsw-static-neutral-bluish-60": "#282a36",
|
|
63
|
+
"--dsw-static-neutral-bluish-75": "#eef0f8",
|
|
64
|
+
"--dsw-static-neutral-bluish-100": "#e8eaf4",
|
|
65
|
+
"--dsw-static-neutral-bluish-150": "#d8ddef",
|
|
66
|
+
"--dsw-static-neutral-bluish-200": "#ccd2e8",
|
|
67
|
+
"--dsw-static-neutral-bluish-250": "#c4cbe3",
|
|
68
|
+
"--dsw-static-neutral-bluish-300": "#bbc4de",
|
|
69
|
+
"--dsw-static-neutral-bluish-400": "#9ba9d0",
|
|
70
|
+
"--dsw-static-neutral-bluish-500": "#7b8fc4",
|
|
71
|
+
"--dsw-static-neutral-bluish-550": "#6f81b4",
|
|
72
|
+
"--dsw-static-neutral-bluish-600": "#6272a4",
|
|
73
|
+
"--dsw-static-neutral-bluish-700": "#6272a4",
|
|
74
|
+
"--dsw-static-neutral-bluish-750": "#44475a",
|
|
75
|
+
"--dsw-static-neutral-bluish-800": "#44475a",
|
|
76
|
+
"--dsw-static-neutral-bluish-850": "#2e3040",
|
|
77
|
+
"--dsw-static-neutral-bluish-875": "#282a36",
|
|
78
|
+
"--dsw-static-neutral-bluish-900": "#282a36",
|
|
79
|
+
"--dsw-static-neutral-bluish-950": "#20212b",
|
|
80
|
+
"--dsw-static-neutral-bluish-1000": "#1a1b24",
|
|
81
|
+
"--dsw-static-neutral-bluish-00": "#f8f8f2",
|
|
82
|
+
"--dsw-static-deepseek-50": "#f0eaff",
|
|
83
|
+
"--dsw-static-deepseek-100": "#e0d2fe",
|
|
84
|
+
"--dsw-static-deepseek-200": "#c8aafd",
|
|
85
|
+
"--dsw-static-deepseek-300": "#b088fc",
|
|
86
|
+
"--dsw-static-deepseek-400": "#8be9fd",
|
|
87
|
+
"--dsw-static-deepseek-450": "#bd93f9",
|
|
88
|
+
"--dsw-static-deepseek-500": "#a97dfa",
|
|
89
|
+
"--dsw-static-deepseek-600": "#7a5abf",
|
|
90
|
+
"--dsw-static-deepseek-800": "#44475a",
|
|
91
|
+
"--dsw-static-deepseek-900": "#383a4a",
|
|
92
|
+
"--dsw-static-deepseek-description": "--dsw-static-deepseek-* overrides from the official port. 400 link / brand-text → cyan, 450 brand-primary → purple, 500 hover.",
|
|
93
|
+
"--dsw-static-deepseek-700-delete": "#5a3e99",
|
|
94
|
+
"--dsw-static-blue-50": "#eafcff",
|
|
95
|
+
"--dsw-static-blue-75": "#c6f3fd",
|
|
96
|
+
"--dsw-static-blue-100": "#b0edfc",
|
|
97
|
+
"--dsw-static-blue-300": "#8be9fd",
|
|
98
|
+
"--dsw-static-blue-400": "#6fd8f0",
|
|
99
|
+
"--dsw-static-blue-450": "#58c6e2",
|
|
100
|
+
"--dsw-static-blue-500": "#41b0cf",
|
|
101
|
+
"--dsw-static-blue-600": "#2b94b5",
|
|
102
|
+
"--dsw-static-blue-800": "#1c6a86",
|
|
103
|
+
"--dsw-static-blue-900": "#165064",
|
|
104
|
+
"--dsw-static-blue-950": "#103d4d",
|
|
105
|
+
"--dsw-static-blue-50p": "#d9f8fe",
|
|
106
|
+
"--dsw-static-red-50": "#ffecec",
|
|
107
|
+
"--dsw-static-red-100": "#ffd9d9",
|
|
108
|
+
"--dsw-static-red-400": "#ff5555",
|
|
109
|
+
"--dsw-static-red-500": "#ec4d4d",
|
|
110
|
+
"--dsw-static-red-600": "#cd4141",
|
|
111
|
+
"--dsw-static-red-900": "#5e2727",
|
|
112
|
+
"--dsw-static-green-100": "#dcfce6",
|
|
113
|
+
"--dsw-static-green-400": "#50fa7b",
|
|
114
|
+
"--dsw-static-green-500": "#3fdd68",
|
|
115
|
+
"--dsw-static-green-900": "#205c38",
|
|
116
|
+
"--dsw-static-amber-100": "#fff0dc",
|
|
117
|
+
"--dsw-static-amber-400": "#ffb86c",
|
|
118
|
+
"--dsw-static-amber-500": "#f2a352",
|
|
119
|
+
"--dsw-static-amber-600": "#d48b43",
|
|
120
|
+
"--dsw-static-amber-900": "#6b4521",
|
|
121
|
+
"--dsw-alias-bg-base": "#20212b",
|
|
122
|
+
"--dsw-alias-bg-layer-1": "#282a36",
|
|
123
|
+
"--dsw-alias-bg-layer-2": "#2e3040",
|
|
124
|
+
"--dsw-alias-bg-layer-3": "#44475a",
|
|
125
|
+
"--dsw-alias-bg-module-platform": "#44475a",
|
|
126
|
+
"--dsw-alias-bg-overlay": "#44475a",
|
|
127
|
+
"--dsw-alias-bg-multi-select": "#44475a",
|
|
128
|
+
"--dsw-alias-bg-skeleton": "rgba(248, 248, 242, 0.05)",
|
|
129
|
+
"--dsw-alias-bg-mask-1": "rgba(0, 0, 0, 0.45)",
|
|
130
|
+
"--dsw-alias-bg-mask-2": "rgba(0, 0, 0, 0.55)",
|
|
131
|
+
"--dsw-alias-bg-mask-3": "rgba(0, 0, 0, 0.65)",
|
|
132
|
+
"--dsw-alias-bg-mask-photo": "rgba(0, 0, 0, 0.88)",
|
|
133
|
+
"--dsw-alias-bg-mask-drop": "rgba(32, 33, 43, 0.7)",
|
|
134
|
+
"--dsw-alias-border-l1": "color-mix(in srgb, #6272a4 30%, transparent)",
|
|
135
|
+
"--dsw-alias-border-l2": "color-mix(in srgb, #6272a4 45%, transparent)",
|
|
136
|
+
"--dsw-alias-border-l3": "color-mix(in srgb, #6272a4 60%, transparent)",
|
|
137
|
+
"--dsw-alias-border-l4": "color-mix(in srgb, #6272a4 75%, transparent)",
|
|
138
|
+
"--dsw-alias-border-inverted": "rgba(0, 0, 0, 0.08)",
|
|
139
|
+
"--dsw-alias-border-inverted2": "rgba(0, 0, 0, 0.12)",
|
|
140
|
+
"--dsw-alias-border-l2-darkmode-thin": "rgba(98, 114, 164, 0.3)",
|
|
141
|
+
"--dsw-alias-brand-primary": "#bd93f9",
|
|
142
|
+
"--dsw-alias-brand-primary-invert": "#f8f8f2",
|
|
143
|
+
"--dsw-alias-brand-primary-new-colorprimary-new-color": "#bd93f9",
|
|
144
|
+
"--dsw-alias-brand-text": "#8be9fd",
|
|
145
|
+
"--dsw-alias-button-contrast-fill": "#282a36",
|
|
146
|
+
"--dsw-alias-button-elevated-fill": "#2e3040",
|
|
147
|
+
"--dsw-alias-button-floating-fill": "#44475a",
|
|
148
|
+
"--dsw-alias-button-floating-hover": "#6272a4",
|
|
149
|
+
"--dsw-alias-button-ghost-active-border": "#6272a4",
|
|
150
|
+
"--dsw-alias-button-ghost-active-fill": "#2e3040",
|
|
151
|
+
"--dsw-alias-button-ghost-active-hover": "#44475a",
|
|
152
|
+
"--dsw-alias-button-info-fill": "#bd93f9",
|
|
153
|
+
"--dsw-alias-button-info-hover": "#5a3e99",
|
|
154
|
+
"--dsw-alias-button-primary-dimmed": "#7a5abf",
|
|
155
|
+
"--dsw-alias-button-primary-fill": "#bd93f9",
|
|
156
|
+
"--dsw-alias-button-primary-hover": "#a97dfa",
|
|
157
|
+
"--dsw-alias-button-tool-bar-fill": "rgba(98, 114, 164, 0.35)",
|
|
158
|
+
"--dsw-alias-button-tool-bar-fill-invisible": "rgba(98, 114, 164, 0.2)",
|
|
159
|
+
"--dsw-alias-button-tool-bar-hover": "rgba(189, 147, 249, 0.35)",
|
|
160
|
+
"--dsw-alias-interactive-bg-active": "rgba(248, 248, 242, 0.14)",
|
|
161
|
+
"--dsw-alias-interactive-bg-hover": "rgba(248, 248, 242, 0.08)",
|
|
162
|
+
"--dsw-alias-interactive-bg-hover-accent": "rgba(189, 147, 249, 0.16)",
|
|
163
|
+
"--dsw-alias-interactive-bg-hover-danger": "rgba(255, 85, 85, 0.14)",
|
|
164
|
+
"--dsw-alias-interactive-bg-hover-solid": "#44475a",
|
|
165
|
+
"--dsw-alias-label-caption": "#6272a4",
|
|
166
|
+
"--dsw-alias-label-dimmed": "#7b8fc4",
|
|
167
|
+
"--dsw-alias-label-primary": "#f8f8f2",
|
|
168
|
+
"--dsw-alias-label-primary-bluish": "#f8f8f2",
|
|
169
|
+
"--dsw-alias-label-primary-dimmed": "#9ba9d0",
|
|
170
|
+
"--dsw-alias-label-primary-foreground": "#282a36",
|
|
171
|
+
"--dsw-alias-label-primary-inverted": "#44475a",
|
|
172
|
+
"--dsw-alias-label-secondary": "#bbc4de",
|
|
173
|
+
"--dsw-alias-label-tertiary": "#9ba9d0",
|
|
174
|
+
"--dsw-alias-markdown-citation": "#44475a",
|
|
175
|
+
"--dsw-alias-markdown-code-block": "#2e3040",
|
|
176
|
+
"--dsw-alias-markdown-code-block-banner": "#282a36",
|
|
177
|
+
"--dsw-alias-markdown-code-segment-selected": "#44475a",
|
|
178
|
+
"--dsw-alias-markdown-code-segment-unselected": "#2e3040",
|
|
179
|
+
"--dsw-alias-markdown-inline-code": "#44475a",
|
|
180
|
+
"--dsw-alias-markdown-placeholder": "#7b8fc4",
|
|
181
|
+
"--dsw-alias-markdown-tag": "#bd93f9",
|
|
182
|
+
"--dsw-alias-scrollbar-bg-l1": "rgba(98, 114, 164, 0.4)",
|
|
183
|
+
"--dsw-alias-scrollbar-bg-l2": "rgba(98, 114, 164, 0.4)",
|
|
184
|
+
"--dsw-alias-scrollbar-hover-l1": "rgba(189, 147, 249, 0.6)",
|
|
185
|
+
"--dsw-alias-scrollbar-hover-l2": "rgba(189, 147, 249, 0.6)",
|
|
186
|
+
"--dsw-alias-separator-primary": "rgba(189, 147, 249, 0.8)",
|
|
187
|
+
"--dsw-alias-state-business-primary": "#8be9fd",
|
|
188
|
+
"--dsw-alias-state-business-tertiary": "rgba(139, 233, 253, 0.1)",
|
|
189
|
+
"--dsw-alias-state-error-primary": "#ff5555",
|
|
190
|
+
"--dsw-alias-state-error-secondary": "rgba(255, 85, 85, 0.16)",
|
|
191
|
+
"--dsw-alias-state-success-primary": "#50fa7b",
|
|
192
|
+
"--dsw-alias-state-success-secondary": "rgba(80, 250, 123, 0.16)",
|
|
193
|
+
"--dsw-alias-state-success-tertiary": "rgba(80, 250, 123, 0.1)",
|
|
194
|
+
"--dsw-alias-state-warn-label": "#ffca80",
|
|
195
|
+
"--dsw-alias-state-warn-primary": "#ffb86c",
|
|
196
|
+
"--dsw-alias-state-warn-secondary": "rgba(255, 184, 108, 0.16)",
|
|
197
|
+
"--dsw-alias-state-warn-tertiary": "rgba(255, 184, 108, 0.1)",
|
|
198
|
+
"--dsw-alias-toast-bg": "#2e3040",
|
|
199
|
+
"--dsw-alias-tooltip-bg": "#44475a",
|
|
200
|
+
"--dsw-specific-sidebar-fill": "#282a36",
|
|
201
|
+
"--dsw-specific-sidebar-nav-item-active": "#44475a",
|
|
202
|
+
"--dsw-specific-sidebar-nav-item-active-accent": "rgba(189, 147, 249, 0.25)",
|
|
203
|
+
"--dsw-specific-sidebar-nav-item-hover": "#2e3040",
|
|
204
|
+
"--dsw-specific-bubble": "#2e3040",
|
|
205
|
+
"--dsw-specific-bubble-highlight": "#44475a",
|
|
206
|
+
"--dsw-specific-input-major": "#282a36",
|
|
207
|
+
"--dsw-specific-login-input": "#282a36",
|
|
208
|
+
"--dsw-specific-menu": "#2e3040",
|
|
209
|
+
"--dsw-specific-selector": "#44475a",
|
|
210
|
+
"--dsw-specific-tip": "#2e3040",
|
|
211
|
+
"--shiki-description": "The official Prism token mapping, translated to the DSH shiki vocabulary: comments #6272a4, punctuation #f8f8f2, tags/parameters/this → cyan, numbers/constants/strings/inserted → yellow, keywords/operators/builtins/regex → pink, functions → green, deleted/important → red.",
|
|
212
|
+
"--shiki-foreground": "#f8f8f2",
|
|
213
|
+
"--shiki-background": "#282a36",
|
|
214
|
+
"--shiki-token-comment": "#6272a4",
|
|
215
|
+
"--shiki-token-punctuation": "#f8f8f2",
|
|
216
|
+
"--shiki-token-constant": "#f1fa8c",
|
|
217
|
+
"--shiki-token-string": "#f1fa8c",
|
|
218
|
+
"--shiki-token-string-expression": "#f1fa8c",
|
|
219
|
+
"--shiki-token-inserted": "#f1fa8c",
|
|
220
|
+
"--shiki-token-link": "#f1fa8c",
|
|
221
|
+
"--shiki-token-keyword": "#ff79c6",
|
|
222
|
+
"--shiki-token-parameter": "#8be9fd",
|
|
223
|
+
"--shiki-token-function": "#50fa7b",
|
|
224
|
+
"--shiki-token-deleted": "#ff5555",
|
|
225
|
+
"--shiki-token-changed": "#ffb86c",
|
|
226
|
+
"--scroll-color": "rgba(98, 114, 164, 0.4)",
|
|
227
|
+
"--scroll-color-hover": "rgba(189, 147, 249, 0.6)"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"id": "dracula-soft",
|
|
232
|
+
"name": "Dracula Soft",
|
|
233
|
+
"colorScheme": "dark",
|
|
234
|
+
"tokens": {
|
|
235
|
+
"--dsw-static-neutral-50": "#efefe9",
|
|
236
|
+
"--dsw-static-neutral-100": "#e2e2da",
|
|
237
|
+
"--dsw-static-neutral-200": "#cdcdc5",
|
|
238
|
+
"--dsw-static-neutral-300": "#b6b6ae",
|
|
239
|
+
"--dsw-static-neutral-400": "#8f8f96",
|
|
240
|
+
"--dsw-static-neutral-500": "#6d6d7a",
|
|
241
|
+
"--dsw-static-neutral-550": "#5c5c6b",
|
|
242
|
+
"--dsw-static-neutral-600": "#4d4d5e",
|
|
243
|
+
"--dsw-static-neutral-700": "#3e3e50",
|
|
244
|
+
"--dsw-static-neutral-800": "#30303f",
|
|
245
|
+
"--dsw-static-neutral-850": "#282a36",
|
|
246
|
+
"--dsw-static-neutral-900": "#20212b",
|
|
247
|
+
"--dsw-static-neutral-1000": "#191a21",
|
|
248
|
+
"--dsw-static-neutral-description": "Anchor stops of the neutral grayscale ramp (--dsw-static-neutral-*), lightest (00) to darkest (1000). The official port does not override this ramp; values are Dracula-gray interpolations for a self-contained theme.",
|
|
249
|
+
"--dsw-static-neutral-00": "#f8f8f2",
|
|
250
|
+
"--dsw-static-neutral-bluish-50": "#f8f8f2",
|
|
251
|
+
"--dsw-static-neutral-bluish-60": "#282a36",
|
|
252
|
+
"--dsw-static-neutral-bluish-75": "#eef0f8",
|
|
253
|
+
"--dsw-static-neutral-bluish-100": "#e8eaf4",
|
|
254
|
+
"--dsw-static-neutral-bluish-150": "#d8ddef",
|
|
255
|
+
"--dsw-static-neutral-bluish-200": "#ccd2e8",
|
|
256
|
+
"--dsw-static-neutral-bluish-250": "#c4cbe3",
|
|
257
|
+
"--dsw-static-neutral-bluish-300": "#bbc4de",
|
|
258
|
+
"--dsw-static-neutral-bluish-400": "#9ba9d0",
|
|
259
|
+
"--dsw-static-neutral-bluish-500": "#7b8fc4",
|
|
260
|
+
"--dsw-static-neutral-bluish-550": "#6f81b4",
|
|
261
|
+
"--dsw-static-neutral-bluish-600": "#6272a4",
|
|
262
|
+
"--dsw-static-neutral-bluish-700": "#6272a4",
|
|
263
|
+
"--dsw-static-neutral-bluish-750": "#44475a",
|
|
264
|
+
"--dsw-static-neutral-bluish-800": "#44475a",
|
|
265
|
+
"--dsw-static-neutral-bluish-850": "#343746",
|
|
266
|
+
"--dsw-static-neutral-bluish-875": "#2b2d3a",
|
|
267
|
+
"--dsw-static-neutral-bluish-900": "#2b2d3a",
|
|
268
|
+
"--dsw-static-neutral-bluish-950": "#262833",
|
|
269
|
+
"--dsw-static-neutral-bluish-1000": "#1a1b24",
|
|
270
|
+
"--dsw-static-neutral-bluish-00": "#f8f8f2",
|
|
271
|
+
"--dsw-static-deepseek-50": "#f0eaff",
|
|
272
|
+
"--dsw-static-deepseek-100": "#e0d2fe",
|
|
273
|
+
"--dsw-static-deepseek-200": "#c8aafd",
|
|
274
|
+
"--dsw-static-deepseek-300": "#b088fc",
|
|
275
|
+
"--dsw-static-deepseek-400": "#8be9fd",
|
|
276
|
+
"--dsw-static-deepseek-450": "#bd93f9",
|
|
277
|
+
"--dsw-static-deepseek-500": "#a97dfa",
|
|
278
|
+
"--dsw-static-deepseek-600": "#7a5abf",
|
|
279
|
+
"--dsw-static-deepseek-800": "#44475a",
|
|
280
|
+
"--dsw-static-deepseek-900": "#383a4a",
|
|
281
|
+
"--dsw-static-deepseek-description": "--dsw-static-deepseek-* overrides from the official port. 400 link / brand-text → cyan, 450 brand-primary → purple, 500 hover.",
|
|
282
|
+
"--dsw-static-deepseek-700-delete": "#5a3e99",
|
|
283
|
+
"--dsw-static-blue-50": "#eafcff",
|
|
284
|
+
"--dsw-static-blue-75": "#c6f3fd",
|
|
285
|
+
"--dsw-static-blue-100": "#b0edfc",
|
|
286
|
+
"--dsw-static-blue-300": "#8be9fd",
|
|
287
|
+
"--dsw-static-blue-400": "#6fd8f0",
|
|
288
|
+
"--dsw-static-blue-450": "#58c6e2",
|
|
289
|
+
"--dsw-static-blue-500": "#41b0cf",
|
|
290
|
+
"--dsw-static-blue-600": "#2b94b5",
|
|
291
|
+
"--dsw-static-blue-800": "#1c6a86",
|
|
292
|
+
"--dsw-static-blue-900": "#165064",
|
|
293
|
+
"--dsw-static-blue-950": "#103d4d",
|
|
294
|
+
"--dsw-static-blue-50p": "#d9f8fe",
|
|
295
|
+
"--dsw-static-red-50": "#ffecec",
|
|
296
|
+
"--dsw-static-red-100": "#ffd9d9",
|
|
297
|
+
"--dsw-static-red-400": "#ff5555",
|
|
298
|
+
"--dsw-static-red-500": "#ec4d4d",
|
|
299
|
+
"--dsw-static-red-600": "#cd4141",
|
|
300
|
+
"--dsw-static-red-900": "#5e2727",
|
|
301
|
+
"--dsw-static-green-100": "#dcfce6",
|
|
302
|
+
"--dsw-static-green-400": "#50fa7b",
|
|
303
|
+
"--dsw-static-green-500": "#3fdd68",
|
|
304
|
+
"--dsw-static-green-900": "#205c38",
|
|
305
|
+
"--dsw-static-amber-100": "#fff0dc",
|
|
306
|
+
"--dsw-static-amber-400": "#ffb86c",
|
|
307
|
+
"--dsw-static-amber-500": "#f2a352",
|
|
308
|
+
"--dsw-static-amber-600": "#d48b43",
|
|
309
|
+
"--dsw-static-amber-900": "#6b4521",
|
|
310
|
+
"--dsw-alias-bg-base": "#262833",
|
|
311
|
+
"--dsw-alias-bg-layer-1": "#2b2d3a",
|
|
312
|
+
"--dsw-alias-bg-layer-2": "#343746",
|
|
313
|
+
"--dsw-alias-bg-layer-3": "#44475a",
|
|
314
|
+
"--dsw-alias-bg-module-platform": "#44475a",
|
|
315
|
+
"--dsw-alias-bg-overlay": "#44475a",
|
|
316
|
+
"--dsw-alias-bg-multi-select": "#44475a",
|
|
317
|
+
"--dsw-alias-bg-skeleton": "rgba(248, 248, 242, 0.05)",
|
|
318
|
+
"--dsw-alias-bg-mask-1": "rgba(0, 0, 0, 0.45)",
|
|
319
|
+
"--dsw-alias-bg-mask-2": "rgba(0, 0, 0, 0.55)",
|
|
320
|
+
"--dsw-alias-bg-mask-3": "rgba(0, 0, 0, 0.65)",
|
|
321
|
+
"--dsw-alias-bg-mask-photo": "rgba(0, 0, 0, 0.88)",
|
|
322
|
+
"--dsw-alias-bg-mask-drop": "rgba(32, 33, 43, 0.7)",
|
|
323
|
+
"--dsw-alias-border-l1": "color-mix(in srgb, #6272a4 30%, transparent)",
|
|
324
|
+
"--dsw-alias-border-l2": "color-mix(in srgb, #6272a4 45%, transparent)",
|
|
325
|
+
"--dsw-alias-border-l3": "color-mix(in srgb, #6272a4 60%, transparent)",
|
|
326
|
+
"--dsw-alias-border-l4": "color-mix(in srgb, #6272a4 75%, transparent)",
|
|
327
|
+
"--dsw-alias-border-inverted": "rgba(0, 0, 0, 0.08)",
|
|
328
|
+
"--dsw-alias-border-inverted2": "rgba(0, 0, 0, 0.12)",
|
|
329
|
+
"--dsw-alias-border-l2-darkmode-thin": "rgba(98, 114, 164, 0.3)",
|
|
330
|
+
"--dsw-alias-brand-primary": "#bd93f9",
|
|
331
|
+
"--dsw-alias-brand-primary-invert": "#f8f8f2",
|
|
332
|
+
"--dsw-alias-brand-primary-new-colorprimary-new-color": "#bd93f9",
|
|
333
|
+
"--dsw-alias-brand-text": "#8be9fd",
|
|
334
|
+
"--dsw-alias-button-contrast-fill": "#282a36",
|
|
335
|
+
"--dsw-alias-button-elevated-fill": "#343746",
|
|
336
|
+
"--dsw-alias-button-floating-fill": "#44475a",
|
|
337
|
+
"--dsw-alias-button-floating-hover": "#59658e",
|
|
338
|
+
"--dsw-alias-button-ghost-active-border": "#6272a4",
|
|
339
|
+
"--dsw-alias-button-ghost-active-fill": "#343746",
|
|
340
|
+
"--dsw-alias-button-ghost-active-hover": "#44475a",
|
|
341
|
+
"--dsw-alias-button-info-fill": "#bd93f9",
|
|
342
|
+
"--dsw-alias-button-info-hover": "#5a3e99",
|
|
343
|
+
"--dsw-alias-button-primary-dimmed": "#7a5abf",
|
|
344
|
+
"--dsw-alias-button-primary-fill": "#bd93f9",
|
|
345
|
+
"--dsw-alias-button-primary-hover": "#a97dfa",
|
|
346
|
+
"--dsw-alias-button-tool-bar-fill": "rgba(98, 114, 164, 0.35)",
|
|
347
|
+
"--dsw-alias-button-tool-bar-fill-invisible": "rgba(98, 114, 164, 0.2)",
|
|
348
|
+
"--dsw-alias-button-tool-bar-hover": "rgba(189, 147, 249, 0.35)",
|
|
349
|
+
"--dsw-alias-interactive-bg-active": "rgba(248, 248, 242, 0.14)",
|
|
350
|
+
"--dsw-alias-interactive-bg-hover": "rgba(248, 248, 242, 0.08)",
|
|
351
|
+
"--dsw-alias-interactive-bg-hover-accent": "rgba(189, 147, 249, 0.16)",
|
|
352
|
+
"--dsw-alias-interactive-bg-hover-danger": "rgba(255, 85, 85, 0.14)",
|
|
353
|
+
"--dsw-alias-interactive-bg-hover-solid": "#59658e",
|
|
354
|
+
"--dsw-alias-label-caption": "#6272a4",
|
|
355
|
+
"--dsw-alias-label-dimmed": "#7b8fc4",
|
|
356
|
+
"--dsw-alias-label-primary": "#f8f8f2",
|
|
357
|
+
"--dsw-alias-label-primary-bluish": "#f8f8f2",
|
|
358
|
+
"--dsw-alias-label-primary-dimmed": "#9ba9d0",
|
|
359
|
+
"--dsw-alias-label-primary-foreground": "#282a36",
|
|
360
|
+
"--dsw-alias-label-primary-inverted": "#44475a",
|
|
361
|
+
"--dsw-alias-label-secondary": "#bbc4de",
|
|
362
|
+
"--dsw-alias-label-tertiary": "#9ba9d0",
|
|
363
|
+
"--dsw-alias-markdown-citation": "#44475a",
|
|
364
|
+
"--dsw-alias-markdown-code-block": "#343746",
|
|
365
|
+
"--dsw-alias-markdown-code-block-banner": "#2b2d3a",
|
|
366
|
+
"--dsw-alias-markdown-code-segment-selected": "#44475a",
|
|
367
|
+
"--dsw-alias-markdown-code-segment-unselected": "#343746",
|
|
368
|
+
"--dsw-alias-markdown-inline-code": "#44475a",
|
|
369
|
+
"--dsw-alias-markdown-placeholder": "#7b8fc4",
|
|
370
|
+
"--dsw-alias-markdown-tag": "#bd93f9",
|
|
371
|
+
"--dsw-alias-scrollbar-bg-l1": "#44475a",
|
|
372
|
+
"--dsw-alias-scrollbar-bg-l2": "#44475a",
|
|
373
|
+
"--dsw-alias-scrollbar-hover-l1": "#59658e",
|
|
374
|
+
"--dsw-alias-scrollbar-hover-l2": "#59658e",
|
|
375
|
+
"--dsw-alias-separator-primary": "rgba(189, 147, 249, 0.8)",
|
|
376
|
+
"--dsw-alias-state-business-primary": "#8be9fd",
|
|
377
|
+
"--dsw-alias-state-business-tertiary": "rgba(139, 233, 253, 0.1)",
|
|
378
|
+
"--dsw-alias-state-error-primary": "#ff5555",
|
|
379
|
+
"--dsw-alias-state-error-secondary": "rgba(255, 85, 85, 0.16)",
|
|
380
|
+
"--dsw-alias-state-success-primary": "#50fa7b",
|
|
381
|
+
"--dsw-alias-state-success-secondary": "rgba(80, 250, 123, 0.16)",
|
|
382
|
+
"--dsw-alias-state-success-tertiary": "rgba(80, 250, 123, 0.1)",
|
|
383
|
+
"--dsw-alias-state-warn-label": "#ffca80",
|
|
384
|
+
"--dsw-alias-state-warn-primary": "#ffb86c",
|
|
385
|
+
"--dsw-alias-state-warn-secondary": "rgba(255, 184, 108, 0.16)",
|
|
386
|
+
"--dsw-alias-state-warn-tertiary": "rgba(255, 184, 108, 0.1)",
|
|
387
|
+
"--dsw-alias-toast-bg": "#343746",
|
|
388
|
+
"--dsw-alias-tooltip-bg": "#44475a",
|
|
389
|
+
"--dsw-specific-sidebar-fill": "#2b2d3a",
|
|
390
|
+
"--dsw-specific-sidebar-nav-item-active": "#44475a",
|
|
391
|
+
"--dsw-specific-sidebar-nav-item-active-accent": "rgba(189, 147, 249, 0.25)",
|
|
392
|
+
"--dsw-specific-sidebar-nav-item-hover": "#343746",
|
|
393
|
+
"--dsw-specific-bubble": "#343746",
|
|
394
|
+
"--dsw-specific-bubble-highlight": "#44475a",
|
|
395
|
+
"--dsw-specific-input-major": "#2b2d3a",
|
|
396
|
+
"--dsw-specific-login-input": "#2b2d3a",
|
|
397
|
+
"--dsw-specific-menu": "#343746",
|
|
398
|
+
"--dsw-specific-selector": "#44475a",
|
|
399
|
+
"--dsw-specific-tip": "#343746",
|
|
400
|
+
"--shiki-description": "The official Prism token mapping, translated to the DSH shiki vocabulary: comments #6272a4, punctuation #f8f8f2, tags/parameters/this → cyan, numbers/constants/strings/inserted → yellow, keywords/operators/builtins/regex → pink, functions → green, deleted/important → red.",
|
|
401
|
+
"--shiki-foreground": "#f8f8f2",
|
|
402
|
+
"--shiki-background": "#282a36",
|
|
403
|
+
"--shiki-token-comment": "#6272a4",
|
|
404
|
+
"--shiki-token-punctuation": "#f8f8f2",
|
|
405
|
+
"--shiki-token-constant": "#f1fa8c",
|
|
406
|
+
"--shiki-token-string": "#f1fa8c",
|
|
407
|
+
"--shiki-token-string-expression": "#f1fa8c",
|
|
408
|
+
"--shiki-token-inserted": "#f1fa8c",
|
|
409
|
+
"--shiki-token-link": "#f1fa8c",
|
|
410
|
+
"--shiki-token-keyword": "#ff79c6",
|
|
411
|
+
"--shiki-token-parameter": "#8be9fd",
|
|
412
|
+
"--shiki-token-function": "#50fa7b",
|
|
413
|
+
"--shiki-token-deleted": "#ff5555",
|
|
414
|
+
"--shiki-token-changed": "#ffb86c",
|
|
415
|
+
"--scroll-color": "rgba(98, 114, 164, 0.4)",
|
|
416
|
+
"--scroll-color-hover": "rgba(189, 147, 249, 0.6)"
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
];
|
|
420
|
+
|
|
421
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
422
|
+
const zh = {
|
|
423
|
+
"skin.title": "德古拉主题",
|
|
424
|
+
"skin.default": "默认",
|
|
425
|
+
"skin.dracula": "Dracula",
|
|
426
|
+
"skin.dracula-soft": "Dracula Soft"
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
430
|
+
const en = {
|
|
431
|
+
"skin.title": "Dracula theme",
|
|
432
|
+
"skin.default": "Default",
|
|
433
|
+
"skin.dracula": "Dracula",
|
|
434
|
+
"skin.dracula-soft": "Dracula Soft"
|
|
435
|
+
};
|
|
436
|
+
//#endregion
|
|
437
|
+
|
|
438
|
+
//#region dsh-dracula: persistence
|
|
439
|
+
/** Read a localStorage string value (null on absence or error). */
|
|
440
|
+
function readStorage(key) {
|
|
441
|
+
try {
|
|
442
|
+
const value = window.localStorage.getItem(key);
|
|
443
|
+
return typeof value === "string" ? value : null;
|
|
444
|
+
} catch {
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/** Write (or remove with null) a localStorage value. */
|
|
450
|
+
function writeStorage(key, value) {
|
|
451
|
+
try {
|
|
452
|
+
if (value === null) window.localStorage.removeItem(key);
|
|
453
|
+
else window.localStorage.setItem(key, value);
|
|
454
|
+
} catch {
|
|
455
|
+
// storage unavailable / quota — the preference stays process-local
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/** Saved skin id (may be unknown/absent). */
|
|
460
|
+
function readSavedSkin() {
|
|
461
|
+
return readStorage(STORAGE_KEY);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/** Persist a skin choice; DEFAULT_SKIN clears the stored value. */
|
|
465
|
+
function writeSavedSkin(id) {
|
|
466
|
+
writeStorage(STORAGE_KEY, id === DEFAULT_SKIN ? null : id);
|
|
467
|
+
}
|
|
468
|
+
//#endregion
|
|
469
|
+
|
|
470
|
+
//#region dsh-dracula: settings row store
|
|
471
|
+
/**
|
|
472
|
+
* Skin row slot store: a mirror of the theme service snapshot. The
|
|
473
|
+
* plugin's apply-world change listener is the only writer; the row
|
|
474
|
+
* component reads via props.useStore.
|
|
475
|
+
*/
|
|
476
|
+
function createSkinStore() {
|
|
477
|
+
return (0, _runtime_client.defineStore)({
|
|
478
|
+
init: () => ({
|
|
479
|
+
skin: DEFAULT_SKIN,
|
|
480
|
+
revision: -1
|
|
481
|
+
}),
|
|
482
|
+
actions: {
|
|
483
|
+
sync: (d, skin, revision) => {
|
|
484
|
+
if (revision <= d.revision) return;
|
|
485
|
+
d.skin = skin;
|
|
486
|
+
d.revision = revision;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
//#endregion
|
|
492
|
+
|
|
493
|
+
//#region dsh-dracula: settings row
|
|
494
|
+
/** Inline style sheet for the row (kept dependency-free). */
|
|
495
|
+
const styles = {
|
|
496
|
+
group: {
|
|
497
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
498
|
+
display: "flex",
|
|
499
|
+
flexDirection: "column",
|
|
500
|
+
gap: "10px",
|
|
501
|
+
padding: "16px 0"
|
|
502
|
+
},
|
|
503
|
+
title: {
|
|
504
|
+
color: "var(--dsw-alias-label-primary)",
|
|
505
|
+
fontSize: "14px",
|
|
506
|
+
fontWeight: 400,
|
|
507
|
+
lineHeight: "22px"
|
|
508
|
+
},
|
|
509
|
+
grid: {
|
|
510
|
+
display: "flex",
|
|
511
|
+
flexWrap: "wrap",
|
|
512
|
+
gap: "10px"
|
|
513
|
+
},
|
|
514
|
+
card: {
|
|
515
|
+
display: "flex",
|
|
516
|
+
flexDirection: "column",
|
|
517
|
+
alignItems: "center",
|
|
518
|
+
gap: "6px",
|
|
519
|
+
width: "96px",
|
|
520
|
+
padding: "3px",
|
|
521
|
+
borderRadius: "10px",
|
|
522
|
+
// longhand on purpose: the shorthand leaves borderColor to
|
|
523
|
+
// fall back to currentColor once React clears the selected
|
|
524
|
+
// override, painting stale black/white boxes on deselect
|
|
525
|
+
borderWidth: "2px",
|
|
526
|
+
borderStyle: "solid",
|
|
527
|
+
borderColor: "transparent",
|
|
528
|
+
background: "transparent",
|
|
529
|
+
cursor: "pointer",
|
|
530
|
+
font: "inherit",
|
|
531
|
+
boxSizing: "border-box"
|
|
532
|
+
},
|
|
533
|
+
cardSelected: {
|
|
534
|
+
borderColor: "var(--dsw-alias-brand-primary)",
|
|
535
|
+
background: "var(--dsw-alias-interactive-bg-hover)"
|
|
536
|
+
},
|
|
537
|
+
cardLabel: {
|
|
538
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
539
|
+
fontSize: "12px",
|
|
540
|
+
lineHeight: "16px",
|
|
541
|
+
whiteSpace: "nowrap"
|
|
542
|
+
},
|
|
543
|
+
cardLabelSelected: {
|
|
544
|
+
color: "var(--dsw-alias-label-primary)"
|
|
545
|
+
},
|
|
546
|
+
swatch: {
|
|
547
|
+
width: "100%",
|
|
548
|
+
height: "52px",
|
|
549
|
+
borderRadius: "8px",
|
|
550
|
+
boxSizing: "border-box",
|
|
551
|
+
padding: "8px",
|
|
552
|
+
display: "flex",
|
|
553
|
+
flexDirection: "column",
|
|
554
|
+
justifyContent: "center",
|
|
555
|
+
gap: "6px"
|
|
556
|
+
},
|
|
557
|
+
swatchLine: {
|
|
558
|
+
height: "7px",
|
|
559
|
+
borderRadius: "4px"
|
|
560
|
+
},
|
|
561
|
+
defaultSwatch: {
|
|
562
|
+
width: "100%",
|
|
563
|
+
height: "52px",
|
|
564
|
+
borderRadius: "8px",
|
|
565
|
+
boxSizing: "border-box",
|
|
566
|
+
display: "flex",
|
|
567
|
+
overflow: "hidden",
|
|
568
|
+
border: "1px solid var(--dsw-alias-border-l2)"
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
/** Mini palette preview driven by one skin's token table. */
|
|
573
|
+
function Swatch({ tokens }) {
|
|
574
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
575
|
+
style: {
|
|
576
|
+
...styles.swatch,
|
|
577
|
+
background: tokens["--dsw-alias-bg-layer-2"],
|
|
578
|
+
border: `1px solid ${tokens["--dsw-alias-border-l2"]}`
|
|
579
|
+
},
|
|
580
|
+
children: [
|
|
581
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
582
|
+
style: {
|
|
583
|
+
...styles.swatchLine,
|
|
584
|
+
width: "70%",
|
|
585
|
+
background: tokens["--dsw-alias-label-primary"]
|
|
586
|
+
}
|
|
587
|
+
}),
|
|
588
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
589
|
+
style: {
|
|
590
|
+
...styles.swatchLine,
|
|
591
|
+
width: "45%",
|
|
592
|
+
background: tokens["--dsw-alias-brand-primary"]
|
|
593
|
+
}
|
|
594
|
+
}),
|
|
595
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
596
|
+
style: {
|
|
597
|
+
...styles.swatchLine,
|
|
598
|
+
width: "55%",
|
|
599
|
+
background: tokens["--dsw-alias-label-secondary"],
|
|
600
|
+
opacity: 0.55
|
|
601
|
+
}
|
|
602
|
+
})
|
|
603
|
+
]
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/** "Default" chip: follow the built-in appearance (light + dark halves). */
|
|
608
|
+
function DefaultSwatch() {
|
|
609
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
610
|
+
style: styles.defaultSwatch,
|
|
611
|
+
children: [
|
|
612
|
+
(0, react_jsx_runtime.jsx)("div", { style: { flex: 1, background: "#f4f4f5" } }),
|
|
613
|
+
(0, react_jsx_runtime.jsx)("div", { style: { flex: 1, background: "#1c1c20" } })
|
|
614
|
+
]
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/** One selectable skin card. */
|
|
619
|
+
function SkinCard({ skin, selected, onSelect, t }) {
|
|
620
|
+
return (0, react_jsx_runtime.jsxs)("button", {
|
|
621
|
+
type: "button",
|
|
622
|
+
onClick: (event) => {
|
|
623
|
+
onSelect();
|
|
624
|
+
// drop focus so a stale focus ring never outlives the selection
|
|
625
|
+
event.currentTarget.blur();
|
|
626
|
+
},
|
|
627
|
+
"aria-pressed": selected,
|
|
628
|
+
style: {
|
|
629
|
+
...styles.card,
|
|
630
|
+
...(selected ? styles.cardSelected : {})
|
|
631
|
+
},
|
|
632
|
+
children: [
|
|
633
|
+
(0, react_jsx_runtime.jsx)(Swatch, { tokens: skin.tokens }),
|
|
634
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
635
|
+
style: {
|
|
636
|
+
...styles.cardLabel,
|
|
637
|
+
...(selected ? styles.cardLabelSelected : {})
|
|
638
|
+
},
|
|
639
|
+
children: t(`skin.${skin.id}`)
|
|
640
|
+
})
|
|
641
|
+
]
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Skin picker row registered into the Settings → General item slot,
|
|
647
|
+
* right after the built-in Appearance row: title + a "Default" chip
|
|
648
|
+
* and one swatch card per Dracula variant.
|
|
649
|
+
*/
|
|
650
|
+
function SkinRow({ t, setSkin, useStore }) {
|
|
651
|
+
const skin = useStore((s) => s.skin);
|
|
652
|
+
const selected = SKINS.some((candidate) => candidate.id === skin) ? skin : null;
|
|
653
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
654
|
+
style: styles.group,
|
|
655
|
+
children: [
|
|
656
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
657
|
+
style: styles.title,
|
|
658
|
+
children: t("skin.title")
|
|
659
|
+
}),
|
|
660
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
661
|
+
style: styles.grid,
|
|
662
|
+
children: [
|
|
663
|
+
(0, react_jsx_runtime.jsxs)("button", {
|
|
664
|
+
type: "button",
|
|
665
|
+
onClick: (event) => {
|
|
666
|
+
setSkin(DEFAULT_SKIN);
|
|
667
|
+
// drop focus so a stale focus ring never outlives the selection
|
|
668
|
+
event.currentTarget.blur();
|
|
669
|
+
},
|
|
670
|
+
"aria-pressed": selected === null,
|
|
671
|
+
style: {
|
|
672
|
+
...styles.card,
|
|
673
|
+
...(selected === null ? styles.cardSelected : {})
|
|
674
|
+
},
|
|
675
|
+
children: [
|
|
676
|
+
(0, react_jsx_runtime.jsx)(DefaultSwatch, {}),
|
|
677
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
678
|
+
style: {
|
|
679
|
+
...styles.cardLabel,
|
|
680
|
+
...(selected === null ? styles.cardLabelSelected : {})
|
|
681
|
+
},
|
|
682
|
+
children: t("skin.default")
|
|
683
|
+
})
|
|
684
|
+
]
|
|
685
|
+
}),
|
|
686
|
+
SKINS.map((skinDefinition) => (0, react_jsx_runtime.jsx)(SkinCard, {
|
|
687
|
+
skin: skinDefinition,
|
|
688
|
+
selected: selected === skinDefinition.id,
|
|
689
|
+
onSelect: () => setSkin(skinDefinition.id),
|
|
690
|
+
t
|
|
691
|
+
}, skinDefinition.id))
|
|
692
|
+
]
|
|
693
|
+
})
|
|
694
|
+
]
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
//#endregion
|
|
698
|
+
|
|
699
|
+
//#region dsh-dracula: client plugin body
|
|
700
|
+
/**
|
|
701
|
+
* Required services: theme runtime (skins, switching), slots/locale
|
|
702
|
+
* (the settings row). Persistence is localStorage, so no settings
|
|
703
|
+
* transport is needed.
|
|
704
|
+
*/
|
|
705
|
+
const inject = [
|
|
706
|
+
"slots",
|
|
707
|
+
"locale",
|
|
708
|
+
"theme"
|
|
709
|
+
];
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Client plugin body: register the Dracula skins into the theme
|
|
713
|
+
* runtime, restore the saved choice, keep the row's store in sync
|
|
714
|
+
* with theme/change, and register the picker into Settings → General.
|
|
715
|
+
* @param ctx - client cordis context.
|
|
716
|
+
*/
|
|
717
|
+
function apply(ctx) {
|
|
718
|
+
const disposers = SKINS.map((skinDefinition) => ctx.theme.register(skinDefinition));
|
|
719
|
+
ctx.effect(() => () => {
|
|
720
|
+
for (const dispose of disposers) dispose();
|
|
721
|
+
}, "dsh-dracula-theme: theme registration");
|
|
722
|
+
|
|
723
|
+
// Surface polish derived from the official Dracula DeepSeek port:
|
|
724
|
+
// user-message bubbles carry the brand tint, message reference
|
|
725
|
+
// chips lose the hardcoded deepseek blue, and reasoning text
|
|
726
|
+
// reads in the official brand cyan. Keyed on the stable
|
|
727
|
+
// CSS-module suffixes and colored from our own injected theme
|
|
728
|
+
// variables so it adapts per variant automatically.
|
|
729
|
+
//
|
|
730
|
+
// Every selector is boosted with :not(#dsh-dracula-theme): the
|
|
731
|
+
// shipped ui-* stylesheets are injected by React after ours, so a
|
|
732
|
+
// plain attribute selector loses to the equally specific module
|
|
733
|
+
// class and the tint silently dies. The :not(id) pseudo is a
|
|
734
|
+
// no-op predicate that only raises specificity (1,1,0).
|
|
735
|
+
//
|
|
736
|
+
// The sheet is mounted only while one of our skins is active and
|
|
737
|
+
// removed on the "Default" preference, so the built-in appearance
|
|
738
|
+
// stays pixel-identical unless the user picked a Dracula skin.
|
|
739
|
+
const boost = (selector) =>
|
|
740
|
+
selector.split(",").map((part) => `${part.trim()}:not(#dsh-dracula-theme)`).join(",");
|
|
741
|
+
const SURFACE_RULES = [
|
|
742
|
+
[
|
|
743
|
+
"[class$=\"_userStack\"] [class$=\"_bubble\"]",
|
|
744
|
+
" background: color-mix(in srgb, var(--dsw-alias-brand-primary) 30%, var(--dsw-alias-bg-layer-2));"
|
|
745
|
+
],
|
|
746
|
+
[
|
|
747
|
+
"[class$=\"_refChip\"]",
|
|
748
|
+
" background: color-mix(in srgb, var(--dsw-alias-brand-primary) 22%, transparent);"
|
|
749
|
+
],
|
|
750
|
+
[
|
|
751
|
+
"[class$=\"_thinkBody\"]",
|
|
752
|
+
" color: var(--dsw-alias-brand-text);"
|
|
753
|
+
]
|
|
754
|
+
].map(([selector, body]) => `${boost(selector)} {\n${body}\n}`).join("\n");
|
|
755
|
+
const style = document.createElement("style");
|
|
756
|
+
style.textContent = SURFACE_RULES;
|
|
757
|
+
const syncSurfaceTint = () => {
|
|
758
|
+
const active = SKINS.some((skinDefinition) => skinDefinition.id === ctx.theme.getTheme().preference);
|
|
759
|
+
if (active && !style.isConnected) document.head.appendChild(style);
|
|
760
|
+
if (!active && style.isConnected) style.remove();
|
|
761
|
+
};
|
|
762
|
+
syncSurfaceTint();
|
|
763
|
+
ctx.on("theme/change", syncSurfaceTint);
|
|
764
|
+
ctx.effect(() => () => {
|
|
765
|
+
style.remove();
|
|
766
|
+
}, "dsh-dracula-theme: surface tint lifecycle");
|
|
767
|
+
|
|
768
|
+
// Restore the saved skin. The ThemeService adopts its durable
|
|
769
|
+
// built-in preference ("light"/"dark"/"system") from the Host
|
|
770
|
+
// settings scope asynchronously after boot, which overwrites a
|
|
771
|
+
// third-party preference restored too early. Re-assert the saved
|
|
772
|
+
// skin for a short boot window (a handful of change events or a
|
|
773
|
+
// few seconds), then yield to subsequent user actions.
|
|
774
|
+
const saved = readSavedSkin();
|
|
775
|
+
const savedValid = typeof saved === "string" && saved !== DEFAULT_SKIN && SKINS.some((skinDefinition) => skinDefinition.id === saved);
|
|
776
|
+
let bootGuard = savedValid ? 3 : 0;
|
|
777
|
+
const reassertSaved = () => {
|
|
778
|
+
if (bootGuard <= 0) return;
|
|
779
|
+
const current = ctx.theme.getTheme().preference;
|
|
780
|
+
if (current === saved) return;
|
|
781
|
+
bootGuard -= 1;
|
|
782
|
+
ctx.theme.setTheme(saved);
|
|
783
|
+
};
|
|
784
|
+
reassertSaved();
|
|
785
|
+
const bootWindow = setTimeout(() => {
|
|
786
|
+
bootGuard = 0;
|
|
787
|
+
}, 5000);
|
|
788
|
+
ctx.effect(() => () => {
|
|
789
|
+
clearTimeout(bootWindow);
|
|
790
|
+
}, "dsh-dracula: boot restore window");
|
|
791
|
+
|
|
792
|
+
const skinStore = createSkinStore();
|
|
793
|
+
let skinBound;
|
|
794
|
+
const syncSkin = (snapshot) => {
|
|
795
|
+
skinBound?.sync(snapshot.preference, snapshot.revision);
|
|
796
|
+
};
|
|
797
|
+
ctx.on("theme/change", (snapshot) => {
|
|
798
|
+
syncSkin(snapshot);
|
|
799
|
+
// If the preference moved to another plugin's third-party theme,
|
|
800
|
+
// drop our stored choice so only the last-picked plugin restores
|
|
801
|
+
// at boot (both plugins must implement this convention).
|
|
802
|
+
const pref = snapshot.preference;
|
|
803
|
+
if (pref !== DEFAULT_SKIN && pref !== "light" && pref !== "dark" && !SKINS.some((skinDefinition) => skinDefinition.id === pref)) {
|
|
804
|
+
writeSavedSkin(DEFAULT_SKIN);
|
|
805
|
+
}
|
|
806
|
+
// Re-assert from a fresh task: a re-entrant setTheme inside the
|
|
807
|
+
// dispatch is missed by other subscribers (ui-layout's
|
|
808
|
+
// ThemePresenter), so the restored skin would never reach the DOM.
|
|
809
|
+
setTimeout(() => {
|
|
810
|
+
reassertSaved();
|
|
811
|
+
}, 0);
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
ctx.effect(() => ctx.locale.register(SETTINGS_NS, {
|
|
815
|
+
zh,
|
|
816
|
+
en
|
|
817
|
+
}), "dsh-dracula: settings row dictionaries");
|
|
818
|
+
|
|
819
|
+
const skinInjected = (actions) => {
|
|
820
|
+
skinBound = actions;
|
|
821
|
+
syncSkin(ctx.theme.getTheme());
|
|
822
|
+
return {
|
|
823
|
+
setSkin: (id) => {
|
|
824
|
+
ctx.theme.setTheme(id);
|
|
825
|
+
writeSavedSkin(id);
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
};
|
|
829
|
+
ctx.slots.inject("settings.general.item", () => ctx.slots.register({
|
|
830
|
+
name: "settings.general.item",
|
|
831
|
+
id: "dracula",
|
|
832
|
+
order: 19,
|
|
833
|
+
store: skinStore,
|
|
834
|
+
locale: SETTINGS_NS,
|
|
835
|
+
inject: skinInjected
|
|
836
|
+
}, SkinRow));
|
|
837
|
+
}
|
|
838
|
+
//#endregion
|
|
839
|
+
|
|
840
|
+
exports.SKINS = SKINS;
|
|
841
|
+
exports.DEFAULT_SKIN = DEFAULT_SKIN;
|
|
842
|
+
exports.apply = apply;
|
|
843
|
+
exports.inject = inject;
|
|
844
|
+
return module.exports;
|
|
845
|
+
}
|
|
846
|
+
});
|