dsh-theme-studio 0.2.0 → 0.3.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/CHANGELOG.md +35 -0
- package/README.md +26 -17
- package/lib/apply.d.ts +60 -0
- package/lib/apply.js +172 -0
- package/lib/io.js +0 -4
- package/lib/theme-studio.web.js +351 -348
- package/lib/themes.d.ts +4 -13
- package/lib/themes.js +27 -199
- package/lib/tokens.d.ts +67 -0
- package/lib/tokens.js +151 -0
- package/lib/types.d.ts +4 -5
- package/lib/types.js +2 -1
- package/package.json +2 -2
package/lib/theme-studio.web.js
CHANGED
|
@@ -8,29 +8,28 @@ var zh = {
|
|
|
8
8
|
presetHint: "\u9009\u62E9\u4E00\u4E2A\u9884\u8BBE\u914D\u8272\u65B9\u6848",
|
|
9
9
|
noPreset: "\u65E0\uFF08\u4F7F\u7528\u9ED8\u8BA4\uFF09",
|
|
10
10
|
accentSection: "\u5F3A\u8C03\u8272",
|
|
11
|
-
accentHint: "\
|
|
12
|
-
accentPlaceholder: "#
|
|
11
|
+
accentHint: "\u540C\u65F6\u4F5C\u7528\u4E8E\u4E3B\u6309\u94AE\u3001\u94FE\u63A5\u3001\u5BFC\u822A\u9009\u4E2D\u6001\u4E0E\u60AC\u505C\u9AD8\u4EAE",
|
|
12
|
+
accentPlaceholder: "#4d6bfe",
|
|
13
|
+
accentApplying: "\u5F53\u524D\u751F\u6548\uFF1A",
|
|
13
14
|
darkAccentSection: "\u6697\u8272\u6A21\u5F0F\u5F3A\u8C03\u8272",
|
|
14
15
|
darkAccentHint: "\u6697\u8272\u6A21\u5F0F\u4E0B\u4F7F\u7528\u7684\u5F3A\u8C03\u8272\uFF0C\u7559\u7A7A\u5219\u6CBF\u7528\u4E0A\u9762\u7684\u989C\u8272",
|
|
15
16
|
preserveContrast: "\u5DF2\u81EA\u52A8\u63D0\u4EAE\u4EE5\u4FDD\u8BC1\u6697\u8272\u4E0B\u53EF\u8BFB",
|
|
17
|
+
tokenNote: "\u672C\u9762\u677F\u53EA\u5199 dsh \u771F\u5B9E\u5B58\u5728\u7684\u8BBE\u8BA1\u4EE4\u724C\uFF08{count} \u4E2A\uFF0C\u5747\u4ECE dsh \u6837\u5F0F\u8868\u6838\u5B9E\uFF09\u3002dsh \u6309\u7EC4\u4EF6\u786C\u7F16\u7801\u4E86\u5706\u89D2\u4E14\u672A\u63D0\u4F9B\u52A8\u753B\u4EE4\u724C\uFF0C\u56E0\u6B64\u4E0D\u63D0\u4F9B\u5706\u89D2\u8C03\u8282\uFF0C\u52A8\u753B\u5F00\u5173\u6539\u7528\u6837\u5F0F\u8868\u5B9E\u73B0\u3002",
|
|
16
18
|
densitySection: "\u5BC6\u5EA6",
|
|
17
19
|
densityCompact: "\u7D27\u51D1",
|
|
18
20
|
densityComfortable: "\u8212\u9002",
|
|
19
21
|
densitySpacious: "\u5BBD\u677E",
|
|
20
22
|
radiusSection: "\u5706\u89D2",
|
|
21
|
-
radiusSharp: "\u9510\u5229",
|
|
22
|
-
radiusRounded: "\u5706\u89D2",
|
|
23
|
-
radiusSoft: "\u67D4\u548C",
|
|
24
23
|
fontSection: "\u5B57\u4F53",
|
|
25
24
|
fontSystem: "\u7CFB\u7EDF",
|
|
26
25
|
fontMono: "\u7B49\u5BBD",
|
|
27
26
|
fontSerif: "\u886C\u7EBF",
|
|
28
27
|
customCssSection: "\u81EA\u5B9A\u4E49 CSS",
|
|
29
|
-
customCssHint: "\
|
|
30
|
-
customCssPlaceholder: "--
|
|
28
|
+
customCssHint: "\u8986\u76D6 dsh \u4EE4\u724C\uFF0C\u6BCF\u884C\u4E00\u4E2A `--dsw-* \u6216 --dsh-*: value;`",
|
|
29
|
+
customCssPlaceholder: "--dsw-alias-brand-primary: #ff0000;\n--dsw-alias-label-primary: #111111;",
|
|
31
30
|
behaviorSection: "\u884C\u4E3A",
|
|
32
31
|
animations: "\u754C\u9762\u52A8\u753B",
|
|
33
|
-
animationsHint: "\u5173\u95ED\u53EF\u51CF\u5C11\u52A8\u753B\u5E72\u6270\uFF0C\
|
|
32
|
+
animationsHint: "\u5173\u95ED\u53EF\u51CF\u5C11\u52A8\u753B\u5E72\u6270\uFF08\u7528\u6837\u5F0F\u8868\u628A\u8FC7\u6E21\u65F6\u957F\u538B\u5230\u8FD1\u96F6\uFF0C\u4E8B\u4EF6\u4ECD\u4F1A\u89E6\u53D1\uFF09",
|
|
34
33
|
ioSection: "\u5BFC\u5165 / \u5BFC\u51FA",
|
|
35
34
|
export: "\u5BFC\u51FA\u4E3B\u9898",
|
|
36
35
|
import: "\u5BFC\u5165\u4E3B\u9898",
|
|
@@ -40,18 +39,13 @@ var zh = {
|
|
|
40
39
|
importSuccess: "\u4E3B\u9898\u5DF2\u5BFC\u5165",
|
|
41
40
|
importFailed: "\u5BFC\u5165\u5931\u8D25\uFF1A\u4E0D\u662F\u6709\u6548\u7684\u4E3B\u9898 JSON",
|
|
42
41
|
exportSuccess: "\u4E3B\u9898\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F",
|
|
43
|
-
exportFailed: "\u590D\u5236\u5931\u8D25\uFF0C\
|
|
44
|
-
copy: "\u590D\u5236",
|
|
42
|
+
exportFailed: "\u590D\u5236\u5931\u8D25\uFF0C\u5DF2\u586B\u5165\u4E0B\u65B9\u6587\u672C\u6846",
|
|
45
43
|
preview: "\u9884\u89C8",
|
|
46
|
-
apply: "\u5E94\u7528",
|
|
47
44
|
reset: "\u91CD\u7F6E\u4E3A\u9ED8\u8BA4",
|
|
48
45
|
resetConfirm: "\u786E\u5B9A\u8981\u91CD\u7F6E\u6240\u6709\u4E3B\u9898\u8BBE\u7F6E\u5417\uFF1F",
|
|
49
|
-
applied: "\u4E3B\u9898\u5DF2\u5E94\u7528",
|
|
50
46
|
resetted: "\u5DF2\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u4E3B\u9898",
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
badge: "\u6807\u7B7E",
|
|
54
|
-
text: "\u8FD9\u662F\u4E00\u6BB5\u793A\u4F8B\u6587\u672C\uFF0C\u7528\u4E8E\u9884\u89C8\u4E3B\u9898\u6548\u679C\u3002"
|
|
47
|
+
link: "\u94FE\u63A5",
|
|
48
|
+
text: "\u8FD9\u662F\u4E00\u6BB5\u793A\u4F8B\u6587\u672C\uFF0C\u7528\u4E8E\u9884\u89C8\u5B57\u53F7\u4E0E\u5B57\u4F53\u3002"
|
|
55
49
|
};
|
|
56
50
|
var en = {
|
|
57
51
|
nav: "Theme Studio",
|
|
@@ -61,29 +55,29 @@ var en = {
|
|
|
61
55
|
presetHint: "Choose a pre-built color scheme",
|
|
62
56
|
noPreset: "None (use default)",
|
|
63
57
|
accentSection: "Accent Color",
|
|
64
|
-
accentHint: "Custom accent color,
|
|
65
|
-
accentPlaceholder: "#
|
|
58
|
+
accentHint: "Custom accent color \u2014 drives buttons, links, the active nav item and hover tints",
|
|
59
|
+
accentPlaceholder: "#4d6bfe",
|
|
60
|
+
accentApplying: "Currently applied:",
|
|
66
61
|
darkAccentSection: "Dark Mode Accent",
|
|
67
62
|
darkAccentHint: "Accent used in dark mode; leave empty to reuse the color above",
|
|
68
63
|
preserveContrast: "Lightened automatically for dark-mode readability",
|
|
64
|
+
tokenNote: "This panel only writes design tokens that actually exist in dsh ({count} verified against its stylesheets). dsh hardcodes per-component corner radii and ships no motion tokens, so there is no radius control and the animation toggle is implemented as a stylesheet.",
|
|
69
65
|
densitySection: "Density",
|
|
70
66
|
densityCompact: "Compact",
|
|
71
67
|
densityComfortable: "Comfortable",
|
|
72
68
|
densitySpacious: "Spacious",
|
|
73
69
|
radiusSection: "Border Radius",
|
|
74
|
-
|
|
75
|
-
radiusRounded: "Rounded",
|
|
76
|
-
radiusSoft: "Soft",
|
|
70
|
+
radiusUnavailable: "dsh ships no radius token, so this cannot be adjusted",
|
|
77
71
|
fontSection: "Font Family",
|
|
78
72
|
fontSystem: "System",
|
|
79
73
|
fontMono: "Monospace",
|
|
80
74
|
fontSerif: "Serif",
|
|
81
75
|
customCssSection: "Custom CSS",
|
|
82
|
-
customCssHint: "Override
|
|
83
|
-
customCssPlaceholder: "--
|
|
76
|
+
customCssHint: "Override dsh tokens, one `--dsw-* or --dsh-*: value;` per line",
|
|
77
|
+
customCssPlaceholder: "--dsw-alias-brand-primary: #ff0000;\n--dsw-alias-label-primary: #111111;",
|
|
84
78
|
behaviorSection: "Behavior",
|
|
85
79
|
animations: "UI Animations",
|
|
86
|
-
animationsHint: "Turn off to reduce motion
|
|
80
|
+
animationsHint: "Turn off to reduce motion (a stylesheet compresses transition durations to near-zero so events still fire)",
|
|
87
81
|
ioSection: "Import / Export",
|
|
88
82
|
export: "Export Theme",
|
|
89
83
|
import: "Import Theme",
|
|
@@ -93,18 +87,13 @@ var en = {
|
|
|
93
87
|
importSuccess: "Theme imported",
|
|
94
88
|
importFailed: "Import failed: not a valid theme JSON",
|
|
95
89
|
exportSuccess: "Theme copied to clipboard",
|
|
96
|
-
exportFailed: "Copy failed
|
|
97
|
-
copy: "Copy",
|
|
90
|
+
exportFailed: "Copy failed \u2014 filled into the box below",
|
|
98
91
|
preview: "Preview",
|
|
99
|
-
apply: "Apply",
|
|
100
92
|
reset: "Reset to Default",
|
|
101
93
|
resetConfirm: "Reset all theme settings to default?",
|
|
102
|
-
applied: "Theme applied",
|
|
103
94
|
resetted: "Reset to default theme",
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
badge: "Badge",
|
|
107
|
-
text: "This is sample text to preview the theme."
|
|
95
|
+
link: "Link",
|
|
96
|
+
text: "Sample text for previewing size and font family."
|
|
108
97
|
};
|
|
109
98
|
|
|
110
99
|
// src/client/view.tsx
|
|
@@ -116,207 +105,121 @@ var DEFAULT_PREFERENCES = {
|
|
|
116
105
|
accentColor: null,
|
|
117
106
|
darkAccentColor: null,
|
|
118
107
|
density: "comfortable",
|
|
119
|
-
radius: "rounded",
|
|
120
108
|
fontFamily: "system",
|
|
121
109
|
animations: true,
|
|
122
110
|
customCss: ""
|
|
123
111
|
};
|
|
124
112
|
var STORAGE_KEY = "dsh-theme-studio";
|
|
113
|
+
var STYLE_ELEMENT_ID = "dsh-theme-studio-overrides";
|
|
125
114
|
|
|
126
|
-
// src/
|
|
127
|
-
var
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
"--dsw-alias-interactive-bg-hover": "rgba(22,163,74,0.08)"
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
id: "sunset",
|
|
154
|
-
name: "Sunset",
|
|
155
|
-
description: "Warm orange accent with amber highlights",
|
|
156
|
-
tokens: {
|
|
157
|
-
"--accent": "#ea580c",
|
|
158
|
-
"--accent-hover": "#c2410c",
|
|
159
|
-
"--dsw-alias-state-business-primary": "#ea580c",
|
|
160
|
-
"--dsw-alias-state-business-secondary": "#fed7aa",
|
|
161
|
-
"--dsw-alias-interactive-bg-hover": "rgba(234,88,12,0.08)"
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
id: "monochrome",
|
|
166
|
-
name: "Monochrome",
|
|
167
|
-
description: "Grayscale only \u2014 no color accent",
|
|
168
|
-
tokens: {
|
|
169
|
-
"--accent": "#404040",
|
|
170
|
-
"--accent-hover": "#262626",
|
|
171
|
-
"--dsw-alias-state-business-primary": "#404040",
|
|
172
|
-
"--dsw-alias-state-business-secondary": "#e5e5e5",
|
|
173
|
-
"--dsw-alias-interactive-bg-hover": "rgba(64,64,64,0.08)"
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
id: "nord",
|
|
178
|
-
name: "Nord",
|
|
179
|
-
description: "Frost blue inspired by the Nord palette",
|
|
180
|
-
tokens: {
|
|
181
|
-
"--accent": "#5e81ac",
|
|
182
|
-
"--accent-hover": "#4c6f96",
|
|
183
|
-
"--dsw-alias-state-business-primary": "#5e81ac",
|
|
184
|
-
"--dsw-alias-state-business-secondary": "#e5ebf1",
|
|
185
|
-
"--dsw-alias-interactive-bg-hover": "rgba(94,129,172,0.08)"
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
id: "dracula",
|
|
190
|
-
name: "Dracula",
|
|
191
|
-
description: "Purple accent with dark mode flair",
|
|
192
|
-
tokens: {
|
|
193
|
-
"--accent": "#bd93f9",
|
|
194
|
-
"--accent-hover": "#a678e8",
|
|
195
|
-
"--dsw-alias-state-business-primary": "#bd93f9",
|
|
196
|
-
"--dsw-alias-state-business-secondary": "#3a3a5c",
|
|
197
|
-
"--dsw-alias-interactive-bg-hover": "rgba(189,147,249,0.12)"
|
|
198
|
-
},
|
|
199
|
-
darkTokens: {
|
|
200
|
-
"--dsw-alias-state-business-secondary": "#44475a",
|
|
201
|
-
"--dsw-alias-interactive-bg-hover": "rgba(189,147,249,0.18)"
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
id: "gruvbox",
|
|
206
|
-
name: "Gruvbox",
|
|
207
|
-
description: "Retro groove with warm earthy tones",
|
|
208
|
-
tokens: {
|
|
209
|
-
"--accent": "#d65d0e",
|
|
210
|
-
"--accent-hover": "#cc241d",
|
|
211
|
-
"--dsw-alias-state-business-primary": "#d65d0e",
|
|
212
|
-
"--dsw-alias-state-business-secondary": "#fabd2f",
|
|
213
|
-
"--dsw-alias-interactive-bg-hover": "rgba(214,93,14,0.08)"
|
|
214
|
-
},
|
|
215
|
-
darkTokens: {
|
|
216
|
-
"--accent": "#fe8019",
|
|
217
|
-
"--accent-hover": "#fabd2f",
|
|
218
|
-
"--dsw-alias-state-business-primary": "#fe8019",
|
|
219
|
-
"--dsw-alias-state-business-secondary": "#3c3836"
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
id: "solarized",
|
|
224
|
-
name: "Solarized",
|
|
225
|
-
description: "Ethan Schoonover's precision palette",
|
|
226
|
-
tokens: {
|
|
227
|
-
"--accent": "#268bd2",
|
|
228
|
-
"--accent-hover": "#1e6fa8",
|
|
229
|
-
"--dsw-alias-state-business-primary": "#268bd2",
|
|
230
|
-
"--dsw-alias-state-business-secondary": "#eee8d5",
|
|
231
|
-
"--dsw-alias-interactive-bg-hover": "rgba(38,139,210,0.08)"
|
|
232
|
-
},
|
|
233
|
-
darkTokens: {
|
|
234
|
-
"--accent": "#839496",
|
|
235
|
-
"--accent-hover": "#93a1a1",
|
|
236
|
-
"--dsw-alias-state-business-primary": "#268bd2",
|
|
237
|
-
"--dsw-alias-state-business-secondary": "#073642"
|
|
238
|
-
}
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
id: "tokyo-night",
|
|
242
|
-
name: "Tokyo Night",
|
|
243
|
-
description: "Inspired by the lights of downtown Tokyo at night",
|
|
244
|
-
tokens: {
|
|
245
|
-
"--accent": "#7aa2f7",
|
|
246
|
-
"--accent-hover": "#6183f0",
|
|
247
|
-
"--dsw-alias-state-business-primary": "#7aa2f7",
|
|
248
|
-
"--dsw-alias-state-business-secondary": "#bb9af7",
|
|
249
|
-
"--dsw-alias-interactive-bg-hover": "rgba(122,162,247,0.08)"
|
|
250
|
-
},
|
|
251
|
-
darkTokens: {
|
|
252
|
-
"--dsw-alias-state-business-secondary": "#1a1b26",
|
|
253
|
-
"--dsw-alias-interactive-bg-hover": "rgba(122,162,247,0.15)"
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
id: "catppuccin",
|
|
258
|
-
name: "Catppuccin",
|
|
259
|
-
description: "Soothing pastel theme for high contrast",
|
|
260
|
-
tokens: {
|
|
261
|
-
"--accent": "#89b4fa",
|
|
262
|
-
"--accent-hover": "#74a8fc",
|
|
263
|
-
"--dsw-alias-state-business-primary": "#89b4fa",
|
|
264
|
-
"--dsw-alias-state-business-secondary": "#f5e0dc",
|
|
265
|
-
"--dsw-alias-interactive-bg-hover": "rgba(137,180,250,0.08)"
|
|
266
|
-
},
|
|
267
|
-
darkTokens: {
|
|
268
|
-
"--accent": "#cba6f7",
|
|
269
|
-
"--accent-hover": "#b48bef",
|
|
270
|
-
"--dsw-alias-state-business-primary": "#cba6f7",
|
|
271
|
-
"--dsw-alias-state-business-secondary": "#313244",
|
|
272
|
-
"--dsw-alias-interactive-bg-hover": "rgba(203,166,247,0.12)"
|
|
273
|
-
}
|
|
274
|
-
}
|
|
115
|
+
// src/tokens.ts
|
|
116
|
+
var VERIFIED_TOKENS = [
|
|
117
|
+
// Accent / business
|
|
118
|
+
"--dsw-alias-state-business-primary",
|
|
119
|
+
"--dsw-alias-state-business-tertiary",
|
|
120
|
+
"--dsw-alias-brand-primary",
|
|
121
|
+
"--dsw-alias-brand-text",
|
|
122
|
+
"--dsw-alias-link",
|
|
123
|
+
"--dsw-alias-interactive-bg-hover",
|
|
124
|
+
"--dsw-alias-interactive-bg-hover-accent",
|
|
125
|
+
"--dsw-alias-button-primary-fill",
|
|
126
|
+
"--dsw-alias-button-primary-hover",
|
|
127
|
+
// Typography
|
|
128
|
+
"--dsw-font-family",
|
|
129
|
+
"--dsw-font-mono",
|
|
130
|
+
"--dsw-font-xs-13",
|
|
131
|
+
"--dsw-font-xs-strong-13",
|
|
132
|
+
"--dsw-font-xxs-12",
|
|
133
|
+
"--dsw-font-xxxs-11",
|
|
134
|
+
"--dsw-font-s-14",
|
|
135
|
+
"--dsw-font-l-20",
|
|
136
|
+
"--dsh-content-font-size",
|
|
137
|
+
"--dsh-content-font-delta"
|
|
275
138
|
];
|
|
276
|
-
var
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
139
|
+
var VERIFIED = new Set(VERIFIED_TOKENS);
|
|
140
|
+
function tint(hex, alpha) {
|
|
141
|
+
const value = hex.trim().replace(/^#/, "");
|
|
142
|
+
let r;
|
|
143
|
+
let g;
|
|
144
|
+
let b;
|
|
145
|
+
if (value.length === 3) {
|
|
146
|
+
r = parseInt(value[0] + value[0], 16);
|
|
147
|
+
g = parseInt(value[1] + value[1], 16);
|
|
148
|
+
b = parseInt(value[2] + value[2], 16);
|
|
149
|
+
} else if (value.length === 6) {
|
|
150
|
+
r = parseInt(value.slice(0, 2), 16);
|
|
151
|
+
g = parseInt(value.slice(2, 4), 16);
|
|
152
|
+
b = parseInt(value.slice(4, 6), 16);
|
|
153
|
+
} else {
|
|
154
|
+
return hex;
|
|
288
155
|
}
|
|
156
|
+
if ([r, g, b].some((n) => Number.isNaN(n))) return hex;
|
|
157
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
158
|
+
}
|
|
159
|
+
function accentTokens(hex) {
|
|
160
|
+
return {
|
|
161
|
+
"--dsw-alias-state-business-primary": hex,
|
|
162
|
+
"--dsw-alias-state-business-tertiary": tint(hex, 0.12),
|
|
163
|
+
"--dsw-alias-brand-primary": hex,
|
|
164
|
+
"--dsw-alias-brand-text": hex,
|
|
165
|
+
"--dsw-alias-link": hex,
|
|
166
|
+
"--dsw-alias-interactive-bg-hover-accent": tint(hex, 0.1),
|
|
167
|
+
"--dsw-alias-button-primary-fill": hex,
|
|
168
|
+
"--dsw-alias-button-primary-hover": hex
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
var DENSITY_TOKENS = {
|
|
172
|
+
compact: { "--dsh-content-font-size": "13px" },
|
|
173
|
+
comfortable: { "--dsh-content-font-size": "14px" },
|
|
174
|
+
spacious: { "--dsh-content-font-size": "15px" }
|
|
289
175
|
};
|
|
290
|
-
var
|
|
291
|
-
|
|
292
|
-
"--
|
|
293
|
-
"--
|
|
294
|
-
"--dsh-radius-large": "6px"
|
|
176
|
+
var FONT_TOKENS = {
|
|
177
|
+
system: {
|
|
178
|
+
"--dsw-font-family": "system-ui, -apple-system, 'Segoe UI', sans-serif",
|
|
179
|
+
"--dsw-font-mono": "'Cascadia Code', 'JetBrains Mono', Consolas, monospace"
|
|
295
180
|
},
|
|
296
|
-
|
|
297
|
-
"--
|
|
298
|
-
"--
|
|
299
|
-
"--dsh-radius-large": "14px"
|
|
181
|
+
mono: {
|
|
182
|
+
"--dsw-font-family": "'Cascadia Code', 'JetBrains Mono', Consolas, monospace",
|
|
183
|
+
"--dsw-font-mono": "'Cascadia Code', 'JetBrains Mono', Consolas, monospace"
|
|
300
184
|
},
|
|
301
|
-
|
|
302
|
-
"--
|
|
303
|
-
"--
|
|
304
|
-
"--dsh-radius-large": "22px"
|
|
185
|
+
serif: {
|
|
186
|
+
"--dsw-font-family": "Georgia, 'Times New Roman', serif",
|
|
187
|
+
"--dsw-font-mono": "'Cascadia Code', Consolas, monospace"
|
|
305
188
|
}
|
|
306
189
|
};
|
|
307
|
-
var
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
190
|
+
var MOTION_OFF_CSS = `
|
|
191
|
+
*, *::before, *::after {
|
|
192
|
+
transition-duration: 0.001ms !important;
|
|
193
|
+
transition-delay: 0ms !important;
|
|
194
|
+
animation-duration: 0.001ms !important;
|
|
195
|
+
animation-delay: 0ms !important;
|
|
196
|
+
animation-iteration-count: 1 !important;
|
|
197
|
+
scroll-behavior: auto !important;
|
|
198
|
+
}
|
|
199
|
+
`.trim();
|
|
200
|
+
|
|
201
|
+
// src/themes.ts
|
|
202
|
+
function preset(id, name, description, lightAccent, darkAccent) {
|
|
203
|
+
const base = { id, name, description, tokens: accentTokens(lightAccent) };
|
|
204
|
+
if (darkAccent !== void 0 && darkAccent.toLowerCase() !== lightAccent.toLowerCase()) {
|
|
205
|
+
base.darkTokens = accentTokens(darkAccent);
|
|
206
|
+
}
|
|
207
|
+
return base;
|
|
208
|
+
}
|
|
209
|
+
var PRESETS = [
|
|
210
|
+
preset("ocean", "Ocean", "Deep blue, close to dsh default", "#4d6bfe"),
|
|
211
|
+
preset("forest", "Forest", "Calm green", "#16a34a", "#22c55e"),
|
|
212
|
+
preset("sunset", "Sunset", "Warm orange", "#ea580c", "#fb923c"),
|
|
213
|
+
preset("monochrome", "Monochrome", "No color accent at all", "#5c5c5c", "#9e9e9e"),
|
|
214
|
+
preset("nord", "Nord", "Frost blue", "#5e81ac", "#88c0d0"),
|
|
215
|
+
preset("dracula", "Dracula", "Purple, brighter on dark", "#7c5cd6", "#bd93f9"),
|
|
216
|
+
preset("gruvbox", "Gruvbox", "Retro warm earth tones", "#b57614", "#fe8019"),
|
|
217
|
+
preset("solarized", "Solarized", "Schoonover precision palette", "#268bd2", "#5fa8d3"),
|
|
218
|
+
preset("tokyo-night", "Tokyo Night", "City lights blue", "#3d59a1", "#7aa2f7"),
|
|
219
|
+
preset("catppuccin", "Catppuccin", "Soft pastel", "#7287fd", "#cba6f7"),
|
|
220
|
+
preset("rose", "Ros\xE9", "Muted pink", "#b3276b", "#f472b6"),
|
|
221
|
+
preset("ember", "Ember", "Deep red", "#b91c1c", "#ef4444")
|
|
222
|
+
];
|
|
320
223
|
function getPreset(id) {
|
|
321
224
|
return PRESETS.find((p) => p.id === id);
|
|
322
225
|
}
|
|
@@ -332,7 +235,6 @@ function exportTheme(prefs, name) {
|
|
|
332
235
|
return JSON.stringify(payload, null, 2);
|
|
333
236
|
}
|
|
334
237
|
var DENSITIES = /* @__PURE__ */ new Set(["compact", "comfortable", "spacious"]);
|
|
335
|
-
var RADII = /* @__PURE__ */ new Set(["sharp", "rounded", "soft"]);
|
|
336
238
|
var FONTS = /* @__PURE__ */ new Set(["system", "mono", "serif"]);
|
|
337
239
|
function asColor(value) {
|
|
338
240
|
if (typeof value !== "string") return null;
|
|
@@ -359,9 +261,6 @@ function parseTheme(raw) {
|
|
|
359
261
|
if (typeof source["density"] === "string" && DENSITIES.has(source["density"])) {
|
|
360
262
|
result.density = source["density"];
|
|
361
263
|
}
|
|
362
|
-
if (typeof source["radius"] === "string" && RADII.has(source["radius"])) {
|
|
363
|
-
result.radius = source["radius"];
|
|
364
|
-
}
|
|
365
264
|
if (typeof source["fontFamily"] === "string" && FONTS.has(source["fontFamily"])) {
|
|
366
265
|
result.fontFamily = source["fontFamily"];
|
|
367
266
|
}
|
|
@@ -419,6 +318,104 @@ function ensureDarkContrast(hex) {
|
|
|
419
318
|
return { color: current, adjusted: true };
|
|
420
319
|
}
|
|
421
320
|
|
|
321
|
+
// src/apply.ts
|
|
322
|
+
function themeTarget() {
|
|
323
|
+
if (typeof document === "undefined") return null;
|
|
324
|
+
return document.body ?? null;
|
|
325
|
+
}
|
|
326
|
+
function isDshToken(name) {
|
|
327
|
+
return /^--dsh-\S+$/.test(name) || /^--dsw-\S+$/.test(name);
|
|
328
|
+
}
|
|
329
|
+
function isDarkMode() {
|
|
330
|
+
if (typeof document === "undefined") return false;
|
|
331
|
+
return document.body.hasAttribute("data-ds-dark-theme");
|
|
332
|
+
}
|
|
333
|
+
function observeDarkMode(onChange) {
|
|
334
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
|
|
335
|
+
return () => {
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const observer = new MutationObserver(() => onChange(isDarkMode()));
|
|
339
|
+
observer.observe(document.body, {
|
|
340
|
+
attributes: true,
|
|
341
|
+
attributeFilter: ["data-ds-dark-theme"]
|
|
342
|
+
});
|
|
343
|
+
return () => observer.disconnect();
|
|
344
|
+
}
|
|
345
|
+
function resolveAccent(prefs, dark) {
|
|
346
|
+
const chosen = dark ? prefs.darkAccentColor ?? prefs.accentColor : prefs.accentColor;
|
|
347
|
+
if (chosen === null || chosen.trim() === "") return { accent: null, adjusted: false };
|
|
348
|
+
if (!dark) return { accent: chosen, adjusted: false };
|
|
349
|
+
const guarded = ensureDarkContrast(chosen);
|
|
350
|
+
return { accent: guarded.color, adjusted: guarded.adjusted };
|
|
351
|
+
}
|
|
352
|
+
function parseCustomCss(css, allow) {
|
|
353
|
+
const out = {};
|
|
354
|
+
for (const line of css.split("\n")) {
|
|
355
|
+
const match = line.match(/^\s*(--[\w-]+)\s*:\s*([^;{}/*]+?)\s*;?\s*$/);
|
|
356
|
+
if (match === null) continue;
|
|
357
|
+
if (!allow(match[1])) continue;
|
|
358
|
+
out[match[1]] = match[2];
|
|
359
|
+
}
|
|
360
|
+
return out;
|
|
361
|
+
}
|
|
362
|
+
function clearManagedProperties(fullCustomCss = "") {
|
|
363
|
+
const target = themeTarget();
|
|
364
|
+
if (target === null) return;
|
|
365
|
+
const names = /* @__PURE__ */ new Set([
|
|
366
|
+
...Object.keys(accentTokens("#000000")),
|
|
367
|
+
...Object.values(DENSITY_TOKENS).flatMap((t) => Object.keys(t)),
|
|
368
|
+
...Object.values(FONT_TOKENS).flatMap((t) => Object.keys(t))
|
|
369
|
+
]);
|
|
370
|
+
for (const line of fullCustomCss.split("\n")) {
|
|
371
|
+
const match = line.match(/^\s*(--[\w-]+)\s*:/);
|
|
372
|
+
if (match !== null) names.add(match[1]);
|
|
373
|
+
}
|
|
374
|
+
for (const name of names) target.style.removeProperty(name);
|
|
375
|
+
}
|
|
376
|
+
function motionStylesheet() {
|
|
377
|
+
if (typeof document === "undefined") return null;
|
|
378
|
+
let el = document.getElementById(STYLE_ELEMENT_ID);
|
|
379
|
+
if (el === null) {
|
|
380
|
+
el = document.createElement("style");
|
|
381
|
+
el.id = STYLE_ELEMENT_ID;
|
|
382
|
+
document.head.appendChild(el);
|
|
383
|
+
}
|
|
384
|
+
return el;
|
|
385
|
+
}
|
|
386
|
+
function applyTheme(prefs, dark = isDarkMode()) {
|
|
387
|
+
const target = themeTarget();
|
|
388
|
+
if (target === null) return false;
|
|
389
|
+
clearManagedProperties(prefs.customCss);
|
|
390
|
+
const tokens = {};
|
|
391
|
+
if (prefs.preset !== null) {
|
|
392
|
+
const found = getPreset(prefs.preset);
|
|
393
|
+
if (found !== void 0) {
|
|
394
|
+
Object.assign(tokens, found.tokens);
|
|
395
|
+
if (dark && found.darkTokens !== void 0) Object.assign(tokens, found.darkTokens);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
const { accent, adjusted } = resolveAccent(prefs, dark);
|
|
399
|
+
if (accent !== null) Object.assign(tokens, accentTokens(accent));
|
|
400
|
+
Object.assign(tokens, DENSITY_TOKENS[prefs.density] ?? {});
|
|
401
|
+
Object.assign(tokens, FONT_TOKENS[prefs.fontFamily] ?? {});
|
|
402
|
+
for (const [name, value] of Object.entries(tokens)) {
|
|
403
|
+
target.style.setProperty(name, value);
|
|
404
|
+
}
|
|
405
|
+
const custom = parseCustomCss(prefs.customCss, isDshToken);
|
|
406
|
+
for (const [name, value] of Object.entries(custom)) {
|
|
407
|
+
target.style.setProperty(name, value);
|
|
408
|
+
}
|
|
409
|
+
const sheet = motionStylesheet();
|
|
410
|
+
if (sheet !== null) sheet.textContent = prefs.animations ? "" : MOTION_OFF_CSS;
|
|
411
|
+
return adjusted;
|
|
412
|
+
}
|
|
413
|
+
function resetTheme() {
|
|
414
|
+
clearManagedProperties();
|
|
415
|
+
const sheet = typeof document !== "undefined" ? document.getElementById(STYLE_ELEMENT_ID) : null;
|
|
416
|
+
if (sheet !== null) sheet.textContent = "";
|
|
417
|
+
}
|
|
418
|
+
|
|
422
419
|
// src/client/ui.tsx
|
|
423
420
|
import {
|
|
424
421
|
createContext,
|
|
@@ -787,7 +784,7 @@ function ToastProvider({ children }) {
|
|
|
787
784
|
fontWeight: 500,
|
|
788
785
|
boxShadow: "0 6px 20px rgba(0,0,0,0.2)",
|
|
789
786
|
color: "#fff",
|
|
790
|
-
background: t.type === "success" ? T.success : t.type === "error" ? T.error : T.accent,
|
|
787
|
+
background: t.type === "success" ? T.success : t.type === "error" ? T.error : t.type === "warning" ? T.warning : T.accent,
|
|
791
788
|
maxWidth: 360
|
|
792
789
|
},
|
|
793
790
|
children: t.message
|
|
@@ -872,21 +869,6 @@ function Field({
|
|
|
872
869
|
|
|
873
870
|
// src/client/view.tsx
|
|
874
871
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
875
|
-
var MANAGED_PROPERTIES = [
|
|
876
|
-
"--accent",
|
|
877
|
-
"--accent-hover",
|
|
878
|
-
"--dsh-content-font-size",
|
|
879
|
-
"--dsh-spacing-unit",
|
|
880
|
-
"--dsh-radius-small",
|
|
881
|
-
"--dsh-radius-medium",
|
|
882
|
-
"--dsh-radius-large",
|
|
883
|
-
"--dsh-font-family",
|
|
884
|
-
"--dsh-transition-fast",
|
|
885
|
-
"--dsh-transition-normal",
|
|
886
|
-
"--dsw-alias-state-business-primary",
|
|
887
|
-
"--dsw-alias-state-business-secondary",
|
|
888
|
-
"--dsw-alias-interactive-bg-hover"
|
|
889
|
-
];
|
|
890
872
|
function loadPreferences() {
|
|
891
873
|
if (typeof localStorage === "undefined") return { ...DEFAULT_PREFERENCES };
|
|
892
874
|
try {
|
|
@@ -901,71 +883,9 @@ function savePreferences(prefs) {
|
|
|
901
883
|
if (typeof localStorage === "undefined") return;
|
|
902
884
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));
|
|
903
885
|
}
|
|
904
|
-
function
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
}
|
|
908
|
-
function observeDarkMode(onChange) {
|
|
909
|
-
if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
|
|
910
|
-
return () => {
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
const observer = new MutationObserver(() => onChange(isDarkMode()));
|
|
914
|
-
observer.observe(document.body, { attributes: true, attributeFilter: ["data-ds-dark-theme"] });
|
|
915
|
-
return () => observer.disconnect();
|
|
916
|
-
}
|
|
917
|
-
function resolveTokens(prefs, dark) {
|
|
918
|
-
const tokens = {};
|
|
919
|
-
let contrastAdjusted = false;
|
|
920
|
-
const preset = prefs.preset !== null ? getPreset(prefs.preset) : void 0;
|
|
921
|
-
if (preset !== void 0) {
|
|
922
|
-
Object.assign(tokens, preset.tokens);
|
|
923
|
-
if (dark && preset.darkTokens !== void 0) Object.assign(tokens, preset.darkTokens);
|
|
924
|
-
}
|
|
925
|
-
const chosenAccent = dark ? prefs.darkAccentColor ?? prefs.accentColor : prefs.accentColor;
|
|
926
|
-
if (chosenAccent !== null && chosenAccent.trim() !== "") {
|
|
927
|
-
let accent = chosenAccent;
|
|
928
|
-
if (dark) {
|
|
929
|
-
const guarded = ensureDarkContrast(accent);
|
|
930
|
-
accent = guarded.color;
|
|
931
|
-
contrastAdjusted = guarded.adjusted;
|
|
932
|
-
}
|
|
933
|
-
tokens["--accent"] = accent;
|
|
934
|
-
}
|
|
935
|
-
Object.assign(tokens, DENSITY_TOKENS[prefs.density] ?? {});
|
|
936
|
-
Object.assign(tokens, RADIUS_TOKENS[prefs.radius] ?? {});
|
|
937
|
-
Object.assign(tokens, FONT_TOKENS[prefs.fontFamily] ?? {});
|
|
938
|
-
Object.assign(tokens, prefs.animations ? ANIMATION_ON_TOKENS : ANIMATION_OFF_TOKENS);
|
|
939
|
-
return { tokens, contrastAdjusted };
|
|
940
|
-
}
|
|
941
|
-
function parseCustomCss(css) {
|
|
942
|
-
const out = {};
|
|
943
|
-
for (const line of css.split("\n")) {
|
|
944
|
-
const match = line.match(/^\s*(--[\w-]+)\s*:\s*(.+?)\s*;?\s*$/);
|
|
945
|
-
if (match !== null) out[match[1]] = match[2];
|
|
946
|
-
}
|
|
947
|
-
return out;
|
|
948
|
-
}
|
|
949
|
-
function applyTheme(prefs, dark = isDarkMode()) {
|
|
950
|
-
if (typeof document === "undefined") return false;
|
|
951
|
-
const root = document.documentElement;
|
|
952
|
-
const { tokens, contrastAdjusted } = resolveTokens(prefs, dark);
|
|
953
|
-
const custom = parseCustomCss(prefs.customCss);
|
|
954
|
-
const merged = { ...tokens, ...custom };
|
|
955
|
-
for (const prop of MANAGED_PROPERTIES) {
|
|
956
|
-
if (!(prop in merged)) root.style.removeProperty(prop);
|
|
957
|
-
}
|
|
958
|
-
for (const [prop, value] of Object.entries(merged)) root.style.setProperty(prop, value);
|
|
959
|
-
return contrastAdjusted;
|
|
960
|
-
}
|
|
961
|
-
function clearTheme() {
|
|
962
|
-
if (typeof document === "undefined") return;
|
|
963
|
-
const root = document.documentElement;
|
|
964
|
-
for (const prop of MANAGED_PROPERTIES) root.style.removeProperty(prop);
|
|
965
|
-
}
|
|
966
|
-
function PresetCard({ preset, selected, onClick }) {
|
|
967
|
-
const accent = preset.tokens["--accent"] ?? "#4B8BBE";
|
|
968
|
-
const secondary = preset.tokens["--dsw-alias-state-business-secondary"] ?? "#e5e5e5";
|
|
886
|
+
function PresetCard({ preset: preset2, selected, onClick }) {
|
|
887
|
+
const accent = preset2.tokens["--dsw-alias-state-business-primary"] ?? "#4d6bfe";
|
|
888
|
+
const darkAccent = preset2.darkTokens?.["--dsw-alias-state-business-primary"];
|
|
969
889
|
return /* @__PURE__ */ jsxs2(
|
|
970
890
|
"div",
|
|
971
891
|
{
|
|
@@ -974,27 +894,31 @@ function PresetCard({ preset, selected, onClick }) {
|
|
|
974
894
|
cursor: "pointer",
|
|
975
895
|
borderRadius: 10,
|
|
976
896
|
padding: 12,
|
|
977
|
-
border: selected ?
|
|
978
|
-
background: selected ? "
|
|
897
|
+
border: selected ? `2px solid ${accent}` : "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
898
|
+
background: selected ? "var(--dsw-alias-interactive-bg-hover-accent, rgba(77,107,254,0.08))" : "transparent",
|
|
979
899
|
transition: "all 0.15s ease"
|
|
980
900
|
},
|
|
981
901
|
children: [
|
|
982
902
|
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }, children: [
|
|
983
|
-
/* @__PURE__ */ jsxs2("
|
|
984
|
-
/* @__PURE__ */ jsx2("
|
|
985
|
-
/* @__PURE__ */ jsx2("
|
|
903
|
+
/* @__PURE__ */ jsxs2("span", { style: { display: "flex", gap: 3 }, children: [
|
|
904
|
+
/* @__PURE__ */ jsx2("i", { style: { width: 14, height: 14, borderRadius: "50%", background: accent, display: "block" } }),
|
|
905
|
+
darkAccent !== void 0 && /* @__PURE__ */ jsx2("i", { style: { width: 14, height: 14, borderRadius: "50%", background: darkAccent, display: "block" } })
|
|
986
906
|
] }),
|
|
987
|
-
/* @__PURE__ */ jsx2("strong", { style: { fontSize: 13 }, children:
|
|
988
|
-
preset.darkTokens !== void 0 && /* @__PURE__ */ jsx2(Badge, { color: "info", children: "\u25D0" }),
|
|
907
|
+
/* @__PURE__ */ jsx2("strong", { style: { fontSize: 13 }, children: preset2.name }),
|
|
989
908
|
selected && /* @__PURE__ */ jsx2(Badge, { color: "success", children: "\u2713" })
|
|
990
909
|
] }),
|
|
991
|
-
/* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.
|
|
910
|
+
/* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.65, lineHeight: 1.4 }, children: preset2.description })
|
|
992
911
|
]
|
|
993
912
|
}
|
|
994
913
|
);
|
|
995
914
|
}
|
|
996
915
|
function Segmented({ value, options, onChange }) {
|
|
997
|
-
return /* @__PURE__ */ jsx2("div", { style: {
|
|
916
|
+
return /* @__PURE__ */ jsx2("div", { style: {
|
|
917
|
+
display: "inline-flex",
|
|
918
|
+
borderRadius: 8,
|
|
919
|
+
overflow: "hidden",
|
|
920
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))"
|
|
921
|
+
}, children: options.map((opt) => /* @__PURE__ */ jsx2(
|
|
998
922
|
"button",
|
|
999
923
|
{
|
|
1000
924
|
type: "button",
|
|
@@ -1006,8 +930,8 @@ function Segmented({ value, options, onChange }) {
|
|
|
1006
930
|
fontSize: 13,
|
|
1007
931
|
fontWeight: 500,
|
|
1008
932
|
fontFamily: "inherit",
|
|
1009
|
-
background: value === opt.value ? "var(--
|
|
1010
|
-
color: value === opt.value ? "#fff" : "
|
|
933
|
+
background: value === opt.value ? "var(--dsw-alias-button-primary-fill, #4d6bfe)" : "transparent",
|
|
934
|
+
color: value === opt.value ? "#fff" : "inherit",
|
|
1011
935
|
transition: "all 0.15s ease"
|
|
1012
936
|
},
|
|
1013
937
|
children: opt.label
|
|
@@ -1021,9 +945,15 @@ function ColorRow({ value, onChange, placeholder }) {
|
|
|
1021
945
|
"input",
|
|
1022
946
|
{
|
|
1023
947
|
type: "color",
|
|
1024
|
-
value: value ?? "#
|
|
948
|
+
value: value ?? "#4d6bfe",
|
|
1025
949
|
onChange: (e) => onChange(e.target.value),
|
|
1026
|
-
style: {
|
|
950
|
+
style: {
|
|
951
|
+
width: 40,
|
|
952
|
+
height: 40,
|
|
953
|
+
cursor: "pointer",
|
|
954
|
+
borderRadius: 8,
|
|
955
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))"
|
|
956
|
+
}
|
|
1027
957
|
}
|
|
1028
958
|
),
|
|
1029
959
|
/* @__PURE__ */ jsx2(
|
|
@@ -1038,32 +968,113 @@ function ColorRow({ value, onChange, placeholder }) {
|
|
|
1038
968
|
value !== null && /* @__PURE__ */ jsx2(Button, { variant: "ghost", size: "sm", onClick: () => onChange(null), children: "\u2715" })
|
|
1039
969
|
] });
|
|
1040
970
|
}
|
|
1041
|
-
function PreviewArea({ t, dark }) {
|
|
971
|
+
function PreviewArea({ t, dark, accentApplied }) {
|
|
1042
972
|
return /* @__PURE__ */ jsx2(
|
|
1043
973
|
Card,
|
|
1044
974
|
{
|
|
1045
975
|
title: t("preview"),
|
|
1046
976
|
icon: "\u{1F441}",
|
|
1047
977
|
actions: /* @__PURE__ */ jsx2(Badge, { color: dark ? "info" : "warning", children: dark ? "\u{1F319} dark" : "\u2600 light" }),
|
|
1048
|
-
children: /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap:
|
|
1049
|
-
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap:
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
978
|
+
children: /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
|
|
979
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap" }, children: [
|
|
980
|
+
/* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
|
|
981
|
+
/* @__PURE__ */ jsx2("i", { style: {
|
|
982
|
+
width: 18,
|
|
983
|
+
height: 18,
|
|
984
|
+
borderRadius: 4,
|
|
985
|
+
display: "block",
|
|
986
|
+
background: "var(--dsw-alias-state-business-primary, #4d6bfe)"
|
|
987
|
+
} }),
|
|
988
|
+
"accent"
|
|
989
|
+
] }),
|
|
990
|
+
/* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
|
|
991
|
+
/* @__PURE__ */ jsx2("i", { style: {
|
|
992
|
+
width: 18,
|
|
993
|
+
height: 18,
|
|
994
|
+
borderRadius: 4,
|
|
995
|
+
display: "block",
|
|
996
|
+
background: "var(--dsw-alias-button-primary-fill, #4d6bfe)"
|
|
997
|
+
} }),
|
|
998
|
+
"button"
|
|
999
|
+
] }),
|
|
1000
|
+
/* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
|
|
1001
|
+
/* @__PURE__ */ jsx2("i", { style: {
|
|
1002
|
+
width: 18,
|
|
1003
|
+
height: 18,
|
|
1004
|
+
borderRadius: 4,
|
|
1005
|
+
display: "block",
|
|
1006
|
+
background: "var(--dsw-alias-label-primary, currentColor)"
|
|
1007
|
+
} }),
|
|
1008
|
+
"label"
|
|
1009
|
+
] }),
|
|
1010
|
+
/* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
|
|
1011
|
+
/* @__PURE__ */ jsx2("i", { style: {
|
|
1012
|
+
width: 18,
|
|
1013
|
+
height: 18,
|
|
1014
|
+
borderRadius: 4,
|
|
1015
|
+
display: "block",
|
|
1016
|
+
background: "var(--dsw-alias-bg-layer-1, rgba(128,128,128,0.1))",
|
|
1017
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))"
|
|
1018
|
+
} }),
|
|
1019
|
+
"surface"
|
|
1020
|
+
] })
|
|
1054
1021
|
] }),
|
|
1055
|
-
/* @__PURE__ */ jsxs2(
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1022
|
+
/* @__PURE__ */ jsxs2("div", { style: {
|
|
1023
|
+
padding: 12,
|
|
1024
|
+
borderRadius: 10,
|
|
1025
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
1026
|
+
background: "var(--dsw-alias-bg-layer-1, transparent)"
|
|
1027
|
+
}, children: [
|
|
1028
|
+
/* @__PURE__ */ jsx2(
|
|
1029
|
+
"div",
|
|
1030
|
+
{
|
|
1031
|
+
style: {
|
|
1032
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
1033
|
+
fontFamily: "var(--dsw-font-family, inherit)",
|
|
1034
|
+
marginBottom: 10
|
|
1035
|
+
},
|
|
1036
|
+
children: t("text")
|
|
1037
|
+
}
|
|
1038
|
+
),
|
|
1039
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }, children: [
|
|
1040
|
+
/* @__PURE__ */ jsx2("span", { style: {
|
|
1041
|
+
display: "inline-block",
|
|
1042
|
+
padding: "7px 16px",
|
|
1043
|
+
borderRadius: 7,
|
|
1044
|
+
background: "var(--dsw-alias-button-primary-fill, #4d6bfe)",
|
|
1045
|
+
color: "var(--dsw-alias-label-primary-inverted, #fff)",
|
|
1046
|
+
fontSize: 13
|
|
1047
|
+
}, children: t("button") }),
|
|
1048
|
+
/* @__PURE__ */ jsx2("span", { style: {
|
|
1049
|
+
display: "inline-block",
|
|
1050
|
+
padding: "7px 16px",
|
|
1051
|
+
borderRadius: 7,
|
|
1052
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
1053
|
+
fontSize: 13
|
|
1054
|
+
}, children: t("link") }),
|
|
1055
|
+
/* @__PURE__ */ jsx2(
|
|
1056
|
+
"a",
|
|
1057
|
+
{
|
|
1058
|
+
href: "#preview",
|
|
1059
|
+
onClick: (e) => e.preventDefault(),
|
|
1060
|
+
style: { color: "var(--dsw-alias-link, #4d6bfe)", fontSize: 13 },
|
|
1061
|
+
children: t("link")
|
|
1062
|
+
}
|
|
1063
|
+
)
|
|
1061
1064
|
] })
|
|
1065
|
+
] }),
|
|
1066
|
+
accentApplied !== null && /* @__PURE__ */ jsxs2("div", { style: { fontSize: 11, opacity: 0.6, fontFamily: "var(--dsw-font-mono, monospace)" }, children: [
|
|
1067
|
+
t("accentApplying"),
|
|
1068
|
+
" ",
|
|
1069
|
+
accentApplied
|
|
1062
1070
|
] })
|
|
1063
1071
|
] })
|
|
1064
1072
|
}
|
|
1065
1073
|
);
|
|
1066
1074
|
}
|
|
1075
|
+
function TokenCoverage({ t }) {
|
|
1076
|
+
return /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.55, lineHeight: 1.5 }, children: t("tokenNote", { count: VERIFIED_TOKENS.length }) });
|
|
1077
|
+
}
|
|
1067
1078
|
function ThemePanelInner({ t }) {
|
|
1068
1079
|
const toast = useToast();
|
|
1069
1080
|
const [prefs, setPrefs] = useState2(loadPreferences);
|
|
@@ -1078,11 +1089,14 @@ function ThemePanelInner({ t }) {
|
|
|
1078
1089
|
savePreferences(prefs);
|
|
1079
1090
|
}, [prefs, dark]);
|
|
1080
1091
|
useEffect2(() => observeDarkMode(setDark), []);
|
|
1092
|
+
useEffect2(() => () => {
|
|
1093
|
+
applyTheme(loadPreferences(), isDarkMode());
|
|
1094
|
+
}, []);
|
|
1081
1095
|
const update = useCallback2((key, value) => {
|
|
1082
1096
|
setPrefs((p) => ({ ...p, [key]: value }));
|
|
1083
1097
|
}, []);
|
|
1084
1098
|
const handleReset = useCallback2(() => {
|
|
1085
|
-
|
|
1099
|
+
resetTheme();
|
|
1086
1100
|
setPrefs({ ...DEFAULT_PREFERENCES });
|
|
1087
1101
|
setConfirmReset(false);
|
|
1088
1102
|
toast("success", t("resetted"));
|
|
@@ -1120,6 +1134,7 @@ function ThemePanelInner({ t }) {
|
|
|
1120
1134
|
if (file === void 0) return;
|
|
1121
1135
|
file.text().then(runImport, () => toast("error", t("importFailed")));
|
|
1122
1136
|
}, [runImport, t, toast]);
|
|
1137
|
+
const { accent: accentApplied } = resolveAccent(prefs, dark);
|
|
1123
1138
|
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 16, maxWidth: 860 }, children: [
|
|
1124
1139
|
/* @__PURE__ */ jsxs2("header", { style: { display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }, children: [
|
|
1125
1140
|
/* @__PURE__ */ jsxs2("strong", { style: { fontSize: 15 }, children: [
|
|
@@ -1211,7 +1226,7 @@ function ThemePanelInner({ t }) {
|
|
|
1211
1226
|
placeholder: t("accentPlaceholder")
|
|
1212
1227
|
}
|
|
1213
1228
|
),
|
|
1214
|
-
/* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.
|
|
1229
|
+
/* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.55, marginTop: 6 }, children: t("accentHint") }),
|
|
1215
1230
|
/* @__PURE__ */ jsx2("div", { style: { height: 14 } }),
|
|
1216
1231
|
/* @__PURE__ */ jsx2(Field, { label: t("darkAccentSection"), hint: t("darkAccentHint"), children: /* @__PURE__ */ jsx2(
|
|
1217
1232
|
ColorRow,
|
|
@@ -1239,19 +1254,6 @@ function ThemePanelInner({ t }) {
|
|
|
1239
1254
|
]
|
|
1240
1255
|
}
|
|
1241
1256
|
),
|
|
1242
|
-
/* @__PURE__ */ jsx2(SectionTitle, { icon: "\u2B1C", children: t("radiusSection") }),
|
|
1243
|
-
/* @__PURE__ */ jsx2(
|
|
1244
|
-
Segmented,
|
|
1245
|
-
{
|
|
1246
|
-
value: prefs.radius,
|
|
1247
|
-
onChange: (v) => update("radius", v),
|
|
1248
|
-
options: [
|
|
1249
|
-
{ value: "sharp", label: t("radiusSharp") },
|
|
1250
|
-
{ value: "rounded", label: t("radiusRounded") },
|
|
1251
|
-
{ value: "soft", label: t("radiusSoft") }
|
|
1252
|
-
]
|
|
1253
|
-
}
|
|
1254
|
-
),
|
|
1255
1257
|
/* @__PURE__ */ jsx2(SectionTitle, { icon: "\u{1F524}", children: t("fontSection") }),
|
|
1256
1258
|
/* @__PURE__ */ jsx2(
|
|
1257
1259
|
Segmented,
|
|
@@ -1280,7 +1282,7 @@ function ThemePanelInner({ t }) {
|
|
|
1280
1282
|
),
|
|
1281
1283
|
/* @__PURE__ */ jsx2("label", { htmlFor: "theme-animations", style: { fontSize: 13, cursor: "pointer" }, children: t("animations") })
|
|
1282
1284
|
] }),
|
|
1283
|
-
/* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.
|
|
1285
|
+
/* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.55, marginTop: 6, marginLeft: 26 }, children: t("animationsHint") })
|
|
1284
1286
|
] }),
|
|
1285
1287
|
/* @__PURE__ */ jsx2(SectionTitle, { icon: "\u270F\uFE0F", children: t("customCssSection") }),
|
|
1286
1288
|
/* @__PURE__ */ jsx2(Card, { children: /* @__PURE__ */ jsx2(Field, { label: t("customCssSection"), hint: t("customCssHint"), children: /* @__PURE__ */ jsx2(
|
|
@@ -1292,7 +1294,8 @@ function ThemePanelInner({ t }) {
|
|
|
1292
1294
|
rows: 4
|
|
1293
1295
|
}
|
|
1294
1296
|
) }) }),
|
|
1295
|
-
/* @__PURE__ */ jsx2(PreviewArea, { t, dark }),
|
|
1297
|
+
/* @__PURE__ */ jsx2(PreviewArea, { t, dark, accentApplied }),
|
|
1298
|
+
/* @__PURE__ */ jsx2(TokenCoverage, { t }),
|
|
1296
1299
|
confirmReset && /* @__PURE__ */ jsx2(
|
|
1297
1300
|
ConfirmDialog,
|
|
1298
1301
|
{
|