@opencode/theme 2.0.7 → 2.0.9
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/dist/tui/categorical.d.ts +1 -0
- package/dist/tui/categorical.js +1 -0
- package/dist/tui/expand.js +8 -10
- package/dist/tui/index.d.ts +3 -3
- package/dist/tui/index.js +2 -2
- package/dist/tui/resolve.d.ts +2 -2
- package/dist/tui/resolve.js +49 -43
- package/dist/tui/schema.d.ts +1150 -4536
- package/dist/tui/schema.js +90 -52
- package/dist/tui/select.d.ts +3 -8
- package/dist/tui/select.js +2 -20
- package/dist/tui/syntax.d.ts +2 -2
- package/dist/tui/syntax.js +19 -19
- package/dist/tui/types.d.ts +20 -22
- package/dist/tui/v1-migrate.js +86 -59
- package/package.json +1 -1
- package/dist/tui/defaults.d.ts +0 -578
- package/dist/tui/defaults.js +0 -453
- package/dist/tui/fallback.d.ts +0 -2
- package/dist/tui/fallback.js +0 -56
package/dist/tui/v1-migrate.js
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
import { RGBA } from "@opentui/core";
|
|
2
2
|
import { oklchToHex, rgbToOklch } from "./color.js";
|
|
3
|
-
import { DEFAULT_CATEGORICAL
|
|
3
|
+
import { DEFAULT_CATEGORICAL } from "./categorical.js";
|
|
4
4
|
import { HueStep } from "./schema.js";
|
|
5
5
|
const chromaticHues = ["red", "orange", "yellow", "green", "cyan", "blue", "purple"];
|
|
6
6
|
const categoricalTokens = ["secondary", "accent", "success", "warning", "primary", "error"];
|
|
7
7
|
const minimumChroma = 0.03;
|
|
8
8
|
const lightThreshold = 0.6;
|
|
9
|
+
// Canonical swatches copied from the original default-theme classifier keep V1 migration self-contained.
|
|
10
|
+
const hueReferences = {
|
|
11
|
+
light: {
|
|
12
|
+
red: "#fca5a5",
|
|
13
|
+
orange: "#fdba74",
|
|
14
|
+
yellow: "#fde047",
|
|
15
|
+
green: "#86efac",
|
|
16
|
+
cyan: "#67e8f9",
|
|
17
|
+
blue: "#93c5fd",
|
|
18
|
+
purple: "#d8b4fe",
|
|
19
|
+
},
|
|
20
|
+
dark: {
|
|
21
|
+
red: "#b91c1c",
|
|
22
|
+
orange: "#c2410c",
|
|
23
|
+
yellow: "#a16207",
|
|
24
|
+
green: "#15803d",
|
|
25
|
+
cyan: "#0e7490",
|
|
26
|
+
blue: "#1d4ed8",
|
|
27
|
+
purple: "#7e22ce",
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const hueAngles = Object.fromEntries(Object.entries(hueReferences).map(([level, colors]) => [
|
|
31
|
+
level,
|
|
32
|
+
Object.fromEntries(Object.entries(colors).map(([name, color]) => [name, toOklch(RGBA.fromHex(color)).h])),
|
|
33
|
+
]));
|
|
9
34
|
export function migrateV1(theme) {
|
|
10
35
|
const light = resolveV1(theme, "light");
|
|
11
36
|
const dark = resolveV1(theme, "dark");
|
|
@@ -13,18 +38,24 @@ export function migrateV1(theme) {
|
|
|
13
38
|
const lightMode = detectMode(light);
|
|
14
39
|
const darkMode = detectMode(dark);
|
|
15
40
|
if (lightMode === darkMode) {
|
|
41
|
+
const definition = migrateMode(lightMode === "light" ? light : dark, lightMode);
|
|
16
42
|
if (lightMode === "light")
|
|
17
|
-
return {
|
|
18
|
-
return {
|
|
43
|
+
return { base: base(definition), light: { hue: definition.hue } };
|
|
44
|
+
return { base: base(definition), dark: { hue: definition.hue } };
|
|
19
45
|
}
|
|
20
46
|
}
|
|
47
|
+
const lightDefinition = migrateMode(light, "light");
|
|
48
|
+
const darkDefinition = migrateMode(dark, "dark");
|
|
21
49
|
return {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
dark: migrateMode(dark, "dark"),
|
|
50
|
+
base: base(lightDefinition),
|
|
51
|
+
light: { hue: lightDefinition.hue },
|
|
52
|
+
dark: darkDefinition,
|
|
26
53
|
};
|
|
27
54
|
}
|
|
55
|
+
function base(definition) {
|
|
56
|
+
const { hue: _, ...base } = definition;
|
|
57
|
+
return base;
|
|
58
|
+
}
|
|
28
59
|
function detectMode(theme) {
|
|
29
60
|
return luminance(theme.text) > luminance(theme.background) ? "dark" : "light";
|
|
30
61
|
}
|
|
@@ -35,21 +66,22 @@ function migrateMode(theme, mode) {
|
|
|
35
66
|
const color = (key) => hex(theme[key]);
|
|
36
67
|
const selected = hex(selectedForeground(theme, theme.primary));
|
|
37
68
|
const destructive = hex(selectedForeground(theme, theme.error));
|
|
38
|
-
const hues = inferHues(theme
|
|
69
|
+
const hues = inferHues(theme);
|
|
39
70
|
const categorical = categoricalTokens.flatMap((token) => {
|
|
40
71
|
const hue = hues.byToken[token];
|
|
41
72
|
return hue ? [hue] : [];
|
|
42
73
|
});
|
|
43
74
|
const uniqueCategorical = categorical.filter((hue, index) => categorical.indexOf(hue) === index);
|
|
44
|
-
const text =
|
|
45
|
-
const textMuted =
|
|
46
|
-
const primary =
|
|
47
|
-
const background =
|
|
48
|
-
const backgroundPanel =
|
|
49
|
-
const backgroundMenu =
|
|
75
|
+
const text = "$hue.neutral.200";
|
|
76
|
+
const textMuted = "$hue.neutral.400";
|
|
77
|
+
const primary = "$hue.interactive.200";
|
|
78
|
+
const background = "$hue.neutral.800";
|
|
79
|
+
const backgroundPanel = "$hue.neutral.700";
|
|
80
|
+
const backgroundMenu = "$hue.neutral.600";
|
|
81
|
+
const backgroundRaisedMax = "$hue.neutral.500";
|
|
50
82
|
return referenceHues({
|
|
51
83
|
hue: {
|
|
52
|
-
gray: neutralScale(theme
|
|
84
|
+
gray: neutralScale(theme),
|
|
53
85
|
...Object.fromEntries(chromaticHues.map((name) => {
|
|
54
86
|
const match = hues.byHue[name];
|
|
55
87
|
return [name, match ? hueScale(match.color, mode) : "$hue.gray"];
|
|
@@ -60,20 +92,20 @@ function migrateMode(theme, mode) {
|
|
|
60
92
|
},
|
|
61
93
|
categorical: uniqueCategorical.length ? uniqueCategorical : DEFAULT_CATEGORICAL,
|
|
62
94
|
text: {
|
|
63
|
-
|
|
64
|
-
|
|
95
|
+
base: text,
|
|
96
|
+
muted: textMuted,
|
|
65
97
|
action: {
|
|
66
98
|
primary: {
|
|
67
|
-
|
|
99
|
+
base: "$text.base",
|
|
68
100
|
$disabled: textMuted,
|
|
69
101
|
$focused: selected,
|
|
70
102
|
$selected: primary,
|
|
71
103
|
},
|
|
72
|
-
secondary: {
|
|
73
|
-
destructive: {
|
|
104
|
+
secondary: { base: "$text.muted", $hovered: "$text.base" },
|
|
105
|
+
destructive: { base: destructive, $disabled: textMuted },
|
|
74
106
|
},
|
|
75
107
|
formfield: {
|
|
76
|
-
|
|
108
|
+
base: text,
|
|
77
109
|
$hovered: primary,
|
|
78
110
|
$focused: primary,
|
|
79
111
|
$pressed: primary,
|
|
@@ -81,35 +113,36 @@ function migrateMode(theme, mode) {
|
|
|
81
113
|
$selected: primary,
|
|
82
114
|
},
|
|
83
115
|
feedback: {
|
|
84
|
-
error: {
|
|
85
|
-
warning: {
|
|
86
|
-
success: {
|
|
87
|
-
info: {
|
|
116
|
+
error: { base: color("error") },
|
|
117
|
+
warning: { base: color("warning") },
|
|
118
|
+
success: { base: color("success") },
|
|
119
|
+
info: { base: color("info") },
|
|
88
120
|
},
|
|
89
121
|
},
|
|
90
122
|
background: {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
123
|
+
base: background,
|
|
124
|
+
raised: {
|
|
125
|
+
base: backgroundPanel,
|
|
126
|
+
high: backgroundMenu,
|
|
127
|
+
max: backgroundRaisedMax,
|
|
95
128
|
},
|
|
96
129
|
action: {
|
|
97
|
-
primary: {
|
|
98
|
-
secondary: {
|
|
99
|
-
destructive: {
|
|
130
|
+
primary: { base: "transparent", $hovered: backgroundPanel, $focused: primary, $selected: "transparent" },
|
|
131
|
+
secondary: { base: "transparent" },
|
|
132
|
+
destructive: { base: color("error") },
|
|
100
133
|
},
|
|
101
134
|
formfield: {
|
|
102
|
-
|
|
135
|
+
base: "$background.base",
|
|
103
136
|
},
|
|
104
137
|
feedback: {
|
|
105
|
-
error: {
|
|
106
|
-
warning: {
|
|
107
|
-
success: {
|
|
108
|
-
info: {
|
|
138
|
+
error: { base: "$background.base" },
|
|
139
|
+
warning: { base: "$background.base" },
|
|
140
|
+
success: { base: "$background.base" },
|
|
141
|
+
info: { base: "$background.base" },
|
|
109
142
|
},
|
|
110
143
|
},
|
|
111
|
-
border: {
|
|
112
|
-
scrollbar: {
|
|
144
|
+
border: { base: color("border") },
|
|
145
|
+
scrollbar: { base: color("borderActive") },
|
|
113
146
|
diff: {
|
|
114
147
|
text: {
|
|
115
148
|
added: color("diffAdded"),
|
|
@@ -158,13 +191,12 @@ function migrateMode(theme, mode) {
|
|
|
158
191
|
imageText: color("markdownImageText"),
|
|
159
192
|
codeBlock: color("markdownCodeBlock"),
|
|
160
193
|
},
|
|
161
|
-
"@
|
|
194
|
+
"@dialog": {
|
|
162
195
|
background: {
|
|
163
|
-
|
|
164
|
-
action: { primary: { $hovered: "$background.
|
|
196
|
+
base: "$background.raised.base",
|
|
197
|
+
action: { primary: { $hovered: "$background.raised.high" } },
|
|
165
198
|
},
|
|
166
199
|
},
|
|
167
|
-
"@context:overlay": { background: { default: "$background.surface.overlay" } },
|
|
168
200
|
});
|
|
169
201
|
}
|
|
170
202
|
function referenceHues(theme) {
|
|
@@ -219,7 +251,7 @@ function referenceHues(theme) {
|
|
|
219
251
|
}
|
|
220
252
|
return Object.fromEntries(Object.entries(theme).map(([key, value]) => [key, key === "hue" || key === "categorical" ? value : replace(value)]));
|
|
221
253
|
}
|
|
222
|
-
function inferHues(theme
|
|
254
|
+
function inferHues(theme) {
|
|
223
255
|
const colors = [
|
|
224
256
|
["accent", theme.accent],
|
|
225
257
|
["success", theme.success],
|
|
@@ -230,7 +262,7 @@ function inferHues(theme, mode) {
|
|
|
230
262
|
["secondary", theme.secondary],
|
|
231
263
|
];
|
|
232
264
|
const inferred = colors.reduce((result, [token, color]) => {
|
|
233
|
-
const nearest = inferHue(color
|
|
265
|
+
const nearest = inferHue(color);
|
|
234
266
|
if (!nearest)
|
|
235
267
|
return result;
|
|
236
268
|
const current = result.byHue[nearest.name];
|
|
@@ -245,7 +277,7 @@ function inferHues(theme, mode) {
|
|
|
245
277
|
["accent", theme.accent],
|
|
246
278
|
["primary", theme.primary],
|
|
247
279
|
].reduce((result, [token, color]) => {
|
|
248
|
-
const nearest = inferHue(color
|
|
280
|
+
const nearest = inferHue(color);
|
|
249
281
|
if (!nearest)
|
|
250
282
|
return result;
|
|
251
283
|
return {
|
|
@@ -254,21 +286,18 @@ function inferHues(theme, mode) {
|
|
|
254
286
|
};
|
|
255
287
|
}, inferred);
|
|
256
288
|
}
|
|
257
|
-
function inferHue(color
|
|
289
|
+
function inferHue(color) {
|
|
258
290
|
const value = toOklch(color);
|
|
259
291
|
if (ambiguous(color, value.c))
|
|
260
292
|
return;
|
|
261
|
-
const
|
|
293
|
+
const reference = value.l >= lightThreshold ? hueAngles.light : hueAngles.dark;
|
|
262
294
|
return chromaticHues
|
|
263
295
|
.map((name) => ({
|
|
264
296
|
name,
|
|
265
|
-
distance: hueDistance(value.h,
|
|
297
|
+
distance: hueDistance(value.h, reference[name]),
|
|
266
298
|
}))
|
|
267
299
|
.sort((first, second) => first.distance - second.distance)[0];
|
|
268
300
|
}
|
|
269
|
-
function inferenceAnchor(lightness) {
|
|
270
|
-
return lightness >= lightThreshold ? 300 : 700;
|
|
271
|
-
}
|
|
272
301
|
function hueDistance(first, second) {
|
|
273
302
|
const difference = Math.abs(first - second);
|
|
274
303
|
return Math.min(difference, 360 - difference);
|
|
@@ -326,13 +355,13 @@ function selectedForeground(theme, background) {
|
|
|
326
355
|
}
|
|
327
356
|
function hueScale(color, mode) {
|
|
328
357
|
const value = toOklch(color);
|
|
329
|
-
const anchor =
|
|
358
|
+
const anchor = 200;
|
|
330
359
|
const endpoint = mode === "light" ? Math.max(0.97, value.l) : Math.min(0.18, value.l);
|
|
331
360
|
const alpha = color.toInts()[3];
|
|
332
361
|
return Object.fromEntries(HueStep.literals.map((step) => {
|
|
333
362
|
if (step === anchor)
|
|
334
363
|
return [step, hex(color)];
|
|
335
|
-
const progress =
|
|
364
|
+
const progress = (step - anchor) / (900 - anchor);
|
|
336
365
|
const generated = oklchToHex({
|
|
337
366
|
l: value.l + (endpoint - value.l) * progress,
|
|
338
367
|
c: value.c * (1 - progress * 0.5),
|
|
@@ -341,8 +370,8 @@ function hueScale(color, mode) {
|
|
|
341
370
|
return [step, alpha === 255 ? generated : `${generated}${byte(alpha)}`];
|
|
342
371
|
}));
|
|
343
372
|
}
|
|
344
|
-
function neutralScale(theme
|
|
345
|
-
const anchors = neutralAnchors(theme
|
|
373
|
+
function neutralScale(theme) {
|
|
374
|
+
const anchors = neutralAnchors(theme);
|
|
346
375
|
return Object.fromEntries(HueStep.literals.map((step) => {
|
|
347
376
|
const exact = anchors.find((anchor) => anchor.step === step);
|
|
348
377
|
if (exact)
|
|
@@ -357,7 +386,7 @@ function neutralScale(theme, mode) {
|
|
|
357
386
|
return [step, interpolate(lower.color, upper.color, (step - lower.step) / (upper.step - lower.step))];
|
|
358
387
|
}));
|
|
359
388
|
}
|
|
360
|
-
function neutralAnchors(theme
|
|
389
|
+
function neutralAnchors(theme) {
|
|
361
390
|
const light = [
|
|
362
391
|
{ step: 200, color: theme.background },
|
|
363
392
|
{ step: 300, color: theme.backgroundPanel },
|
|
@@ -365,8 +394,6 @@ function neutralAnchors(theme, mode) {
|
|
|
365
394
|
{ step: 600, color: theme.textMuted },
|
|
366
395
|
{ step: 800, color: theme.text },
|
|
367
396
|
];
|
|
368
|
-
if (mode === "light")
|
|
369
|
-
return light;
|
|
370
397
|
return light.toReversed().map((source) => ({ ...source, step: (1000 - source.step) }));
|
|
371
398
|
}
|
|
372
399
|
function interpolate(first, second, amount) {
|