@tooee/themes 0.12.0 → 0.13.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/dist/color-mix.d.ts +10 -0
- package/dist/color-mix.d.ts.map +1 -0
- package/dist/color-mix.js +45 -0
- package/dist/color-mix.js.map +1 -0
- package/dist/context.d.ts +4 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +8 -2
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +6 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +23 -11
- package/dist/loader.js.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/color-mix.ts +66 -0
- package/src/context.tsx +19 -2
- package/src/index.ts +3 -0
- package/src/loader.ts +40 -11
- package/src/types.ts +54 -0
- package/themes/aura.json +5 -1
- package/themes/ayu.json +5 -1
- package/themes/catppuccin-frappe.json +5 -1
- package/themes/catppuccin-macchiato.json +5 -1
- package/themes/catppuccin.json +5 -1
- package/themes/cobalt2.json +11 -1
- package/themes/cursor.json +11 -1
- package/themes/dracula.json +11 -1
- package/themes/everforest.json +11 -1
- package/themes/flexoki.json +11 -1
- package/themes/github-light.json +5 -1
- package/themes/github.json +11 -1
- package/themes/gruvbox.json +5 -1
- package/themes/kanagawa.json +5 -1
- package/themes/lucent-orng.json +5 -1
- package/themes/material.json +11 -1
- package/themes/matrix.json +5 -1
- package/themes/mercury.json +11 -1
- package/themes/monokai.json +11 -1
- package/themes/nightowl.json +5 -1
- package/themes/nord.json +11 -1
- package/themes/one-dark.json +5 -1
- package/themes/opencode-light.json +5 -1
- package/themes/opencode.json +11 -1
- package/themes/orng.json +11 -1
- package/themes/osaka-jade.json +5 -1
- package/themes/palenight.json +11 -1
- package/themes/rosepine.json +11 -1
- package/themes/solarized.json +11 -1
- package/themes/synthwave84.json +11 -1
- package/themes/tokyonight.json +11 -1
- package/themes/vercel.json +11 -1
- package/themes/vesper.json +11 -1
- package/themes/zenburn.json +11 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blend `amount` (0 to 1) of `tint` over `base`.
|
|
3
|
+
*
|
|
4
|
+
* An opaque base gives an opaque colour. A fully transparent base, such as a
|
|
5
|
+
* theme that leaves the terminal background visible, gives `tint` at `amount`
|
|
6
|
+
* opacity, so the renderer blends it over whatever is behind. When either
|
|
7
|
+
* colour cannot be parsed, the result is `tint`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const mixColors: (base: string, tint: string, amount: number) => string;
|
|
10
|
+
//# sourceMappingURL=color-mix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-mix.d.ts","sourceRoot":"","sources":["../src/color-mix.ts"],"names":[],"mappings":"AAuCA;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,SAA4B,MAAM,QAAQ,MAAM,UAAU,MAAM,KAAG,MAkBxF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Hex colour blending for derived theme tokens.
|
|
2
|
+
const SHORT_HEX = /^#(?<digits>[0-9a-f]{3,4})$/iu;
|
|
3
|
+
const LONG_HEX = /^#(?<digits>[0-9a-f]{6}|[0-9a-f]{8})$/iu;
|
|
4
|
+
const parseHex = function parseHex(hex) {
|
|
5
|
+
const short = SHORT_HEX.exec(hex)?.groups?.digits;
|
|
6
|
+
const digits = short === undefined
|
|
7
|
+
? LONG_HEX.exec(hex)?.groups?.digits
|
|
8
|
+
: short.replaceAll(/(?<d>.)/gu, "$1$1");
|
|
9
|
+
if (digits === undefined) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const channel = (index) => Number.parseInt(digits.slice(index * 2, index * 2 + 2), 16);
|
|
13
|
+
return { a: digits.length === 8 ? channel(3) : 255, b: channel(2), g: channel(1), r: channel(0) };
|
|
14
|
+
};
|
|
15
|
+
const toHex = function toHex(value) {
|
|
16
|
+
return Math.round(value).toString(16).padStart(2, "0");
|
|
17
|
+
};
|
|
18
|
+
const toRgbHex = function toRgbHex(source) {
|
|
19
|
+
return `#${toHex(source.r)}${toHex(source.g)}${toHex(source.b)}`;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Blend `amount` (0 to 1) of `tint` over `base`.
|
|
23
|
+
*
|
|
24
|
+
* An opaque base gives an opaque colour. A fully transparent base, such as a
|
|
25
|
+
* theme that leaves the terminal background visible, gives `tint` at `amount`
|
|
26
|
+
* opacity, so the renderer blends it over whatever is behind. When either
|
|
27
|
+
* colour cannot be parsed, the result is `tint`.
|
|
28
|
+
*/
|
|
29
|
+
export const mixColors = function mixColors(base, tint, amount) {
|
|
30
|
+
const from = parseHex(base);
|
|
31
|
+
const to = parseHex(tint);
|
|
32
|
+
if (from === null || to === null) {
|
|
33
|
+
return tint;
|
|
34
|
+
}
|
|
35
|
+
if (from.a === 0) {
|
|
36
|
+
return `${toRgbHex(to)}${toHex(to.a * amount)}`;
|
|
37
|
+
}
|
|
38
|
+
return toRgbHex({
|
|
39
|
+
a: 255,
|
|
40
|
+
b: from.b + (to.b - from.b) * amount,
|
|
41
|
+
g: from.g + (to.g - from.g) * amount,
|
|
42
|
+
r: from.r + (to.r - from.r) * amount,
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=color-mix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-mix.js","sourceRoot":"","sources":["../src/color-mix.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAShD,MAAM,SAAS,GAAG,+BAA+B,CAAC;AAElD,MAAM,QAAQ,GAAG,yCAAyC,CAAC;AAE3D,MAAM,QAAQ,GAAG,SAAS,QAAQ,CAAC,GAAW;IAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC;IAElD,MAAM,MAAM,GACV,KAAK,KAAK,SAAS;QACjB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM;QACpC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,KAAa,EAAU,EAAE,CACxC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE9D,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AACpG,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,SAAS,KAAK,CAAC,KAAa;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,SAAS,QAAQ,CAAC,MAAY;IAC7C,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,SAAS,CAAC,IAAY,EAAE,IAAY,EAAE,MAAc;IACpF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE1B,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;IAClD,CAAC;IAED,OAAO,QAAQ,CAAC;QACd,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM;QACpC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM;QACpC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM;KACrC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
package/dist/context.d.ts
CHANGED
|
@@ -26,6 +26,10 @@ interface ThemeSwitcherContextValue extends ThemeContextValue {
|
|
|
26
26
|
setTheme: (name: string, opts?: {
|
|
27
27
|
persist?: boolean;
|
|
28
28
|
}) => void;
|
|
29
|
+
/** Switch between the light and dark variants of the current theme. */
|
|
30
|
+
setMode: (mode: ColorMode, opts?: {
|
|
31
|
+
persist?: boolean;
|
|
32
|
+
}) => void;
|
|
29
33
|
allThemes: string[];
|
|
30
34
|
}
|
|
31
35
|
export interface ThemeSwitcherProviderProps {
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AASvC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,UAAU,iBAAiB;IACzB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AASD,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,gDAKvB,kBAAkB,KAAG,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AASvC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,UAAU,iBAAiB;IACzB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AASD,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,gDAKvB,kBAAkB,KAAG,SAiBvB,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAwB,iBAE5C,CAAC;AAMF,UAAU,yBAA0B,SAAQ,iBAAiB;IAC3D,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/D,uEAAuE;IACvE,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACjE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAID,MAAM,WAAW,0BAA0B;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,qBAAqB,6CAI/B,0BAA0B,KAAG,SAoE/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAgC,yBAQ5D,CAAC"}
|
package/dist/context.js
CHANGED
|
@@ -31,7 +31,6 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({ initialThe
|
|
|
31
31
|
const allThemes = useMemo(() => getThemeNames(), []);
|
|
32
32
|
const [themeName, setThemeName] = useState(initialTheme ?? DEFAULT_THEME_NAME);
|
|
33
33
|
const [mode, setMode] = useState(initialMode ?? DEFAULT_MODE);
|
|
34
|
-
void setMode;
|
|
35
34
|
const theme = useMemo(() => buildTheme(themeName, mode), [themeName, mode]);
|
|
36
35
|
const nextTheme = useCallback(() => {
|
|
37
36
|
const idx = allThemes.indexOf(themeName);
|
|
@@ -51,16 +50,23 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({ initialThe
|
|
|
51
50
|
writeGlobalConfig({ theme: { mode, name } });
|
|
52
51
|
}
|
|
53
52
|
}, [mode]);
|
|
53
|
+
const setModeByName = useCallback((nextMode, opts) => {
|
|
54
|
+
setMode(nextMode);
|
|
55
|
+
if (opts?.persist === true) {
|
|
56
|
+
writeGlobalConfig({ theme: { mode: nextMode, name: themeName } });
|
|
57
|
+
}
|
|
58
|
+
}, [themeName]);
|
|
54
59
|
const value = useMemo(() => ({
|
|
55
60
|
allThemes,
|
|
56
61
|
mode,
|
|
57
62
|
name: theme.name,
|
|
58
63
|
nextTheme,
|
|
59
64
|
prevTheme,
|
|
65
|
+
setMode: setModeByName,
|
|
60
66
|
setTheme: setThemeByName,
|
|
61
67
|
syntax: theme.syntax,
|
|
62
68
|
theme: theme.colors,
|
|
63
|
-
}), [theme, mode, nextTheme, prevTheme, setThemeByName, allThemes]);
|
|
69
|
+
}), [theme, mode, nextTheme, prevTheme, setModeByName, setThemeByName, allThemes]);
|
|
64
70
|
const themeValue = useMemo(() => ({ mode, name: theme.name, syntax: theme.syntax, theme: theme.colors }), [theme, mode]);
|
|
65
71
|
return (_jsx(ThemeSwitcherContext.Provider, { value: value, children: _jsx(ThemeContext.Provider, { value: themeValue, children: children }) }));
|
|
66
72
|
};
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGlF,OAAO,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,YAAY,GACb,MAAM,aAAa,CAAC;AAerB,MAAM,YAAY,GAAG,aAAa,CAAoB;IACpD,IAAI,EAAE,YAAY,CAAC,IAAI;IACvB,IAAI,EAAE,YAAY,CAAC,IAAI;IACvB,MAAM,EAAE,YAAY,CAAC,MAAM;IAC3B,KAAK,EAAE,YAAY,CAAC,MAAM;CAC3B,CAAC,CAAC;AAYH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,aAAa,CAAC,EAClD,IAAI,EACJ,IAAI,EACJ,KAAK,EAAE,SAAS,EAChB,QAAQ,GACW;IACnB,MAAM,QAAQ,GAAG,OAAO,CAAoB,GAAG,EAAE;QAC/C,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;gBACL,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,KAAK,EAAE,SAAS,CAAC,MAAM;aACxB,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,kBAAkB,EAAE,IAAI,IAAI,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEpE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEtE,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhG,YAAY,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAItE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/loader.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ export interface Theme {
|
|
|
7
7
|
colors: ResolvedTheme;
|
|
8
8
|
syntax: SyntaxStyle;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* The project `.tooee/themes` folders for `cwd`, in load order: the
|
|
12
|
+
* filesystem root first and `cwd` last. A later folder replaces a theme of
|
|
13
|
+
* the same name, so the folder nearest to `cwd` wins, as config files do.
|
|
14
|
+
*/
|
|
15
|
+
export declare const projectThemeDirs: (cwd: string) => string[];
|
|
10
16
|
export declare const loadThemes: () => Map<string, ThemeJSON>;
|
|
11
17
|
export declare const getThemeNames: () => string[];
|
|
12
18
|
export declare const DEFAULT_THEME_NAME = "tokyonight";
|
package/dist/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAM3D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAM3D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;CACrB;AAwCD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAkC,MAAM,KAAG,MAAM,EAkB7E,CAAC;AAwBF,eAAO,MAAM,UAAU,QAA0B,GAAG,CAAC,MAAM,EAAE,SAAS,CAErE,CAAC;AAEF,eAAO,MAAM,aAAa,QAA6B,MAAM,EAE5D,CAAC;AAMF,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,eAAO,MAAM,YAAY,EAAE,SAAkB,CAAC;AAkB9C,eAAO,MAAM,YAAY,EAAE,KAA8C,CAAC;AAE1E,eAAO,MAAM,UAAU,SAA6B,MAAM,QAAQ,SAAS,KAAG,KAwB7E,CAAC"}
|
package/dist/loader.js
CHANGED
|
@@ -34,6 +34,26 @@ const loadJsonThemesFromDir = function loadJsonThemesFromDir(dir, target) {
|
|
|
34
34
|
// dir not readable
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* The project `.tooee/themes` folders for `cwd`, in load order: the
|
|
39
|
+
* filesystem root first and `cwd` last. A later folder replaces a theme of
|
|
40
|
+
* the same name, so the folder nearest to `cwd` wins, as config files do.
|
|
41
|
+
*/
|
|
42
|
+
export const projectThemeDirs = function projectThemeDirs(cwd) {
|
|
43
|
+
const dirs = [];
|
|
44
|
+
let dir = cwd;
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
while (dir && !seen.has(dir)) {
|
|
47
|
+
seen.add(dir);
|
|
48
|
+
dirs.push(path.join(dir, ".tooee", "themes"));
|
|
49
|
+
const parent = path.dirname(dir);
|
|
50
|
+
if (parent === dir) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
dir = parent;
|
|
54
|
+
}
|
|
55
|
+
return dirs.toReversed();
|
|
56
|
+
};
|
|
37
57
|
/** Load all bundled themes from packages/themes/themes/ */
|
|
38
58
|
const loadBundledThemes = function loadBundledThemes() {
|
|
39
59
|
if (themeJsonCache.size > 0) {
|
|
@@ -45,17 +65,9 @@ const loadBundledThemes = function loadBundledThemes() {
|
|
|
45
65
|
// XDG config: ~/.config/tooee/themes/
|
|
46
66
|
const xdgConfig = process.env.XDG_CONFIG_HOME ?? path.join(process.env.HOME ?? "", ".config");
|
|
47
67
|
loadJsonThemesFromDir(path.join(xdgConfig, "tooee", "themes"), themeJsonCache);
|
|
48
|
-
// Project-local:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
while (dir && !seen.has(dir)) {
|
|
52
|
-
seen.add(dir);
|
|
53
|
-
loadJsonThemesFromDir(path.join(dir, ".tooee", "themes"), themeJsonCache);
|
|
54
|
-
const parent = path.dirname(dir);
|
|
55
|
-
if (parent === dir) {
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
dir = parent;
|
|
68
|
+
// Project-local: every .tooee/themes/ from the filesystem root down to cwd
|
|
69
|
+
for (const themesDir of projectThemeDirs(process.cwd())) {
|
|
70
|
+
loadJsonThemesFromDir(themesDir, themeJsonCache);
|
|
59
71
|
}
|
|
60
72
|
return themeJsonCache;
|
|
61
73
|
};
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc1C,0CAA0C;AAC1C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAqB,CAAC;AAEpD,MAAM,qBAAqB,GAAG,SAAS,qBAAqB,CAC1D,GAAW,EACX,MAA8B;IAE9B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -53,6 +53,14 @@ export interface ResolvedTheme {
|
|
|
53
53
|
markdownCodeBlock: string;
|
|
54
54
|
cursorLine: string;
|
|
55
55
|
selection: string;
|
|
56
|
+
/** Row background for every search match. */
|
|
57
|
+
searchMatchBg: string;
|
|
58
|
+
/** Row background for the current search match. */
|
|
59
|
+
searchCurrentMatchBg: string;
|
|
60
|
+
/** Gutter sign colour for every search match. */
|
|
61
|
+
searchMatchFg: string;
|
|
62
|
+
/** Gutter sign colour for the current search match. */
|
|
63
|
+
searchCurrentMatchFg: string;
|
|
56
64
|
syntaxComment: string;
|
|
57
65
|
syntaxKeyword: string;
|
|
58
66
|
syntaxFunction: string;
|
|
@@ -101,6 +109,10 @@ export declare const FALLBACKS: {
|
|
|
101
109
|
markdownStrong: string;
|
|
102
110
|
markdownText: string;
|
|
103
111
|
primary: string;
|
|
112
|
+
searchCurrentMatchBg: string;
|
|
113
|
+
searchCurrentMatchFg: string;
|
|
114
|
+
searchMatchBg: string;
|
|
115
|
+
searchMatchFg: string;
|
|
104
116
|
secondary: string;
|
|
105
117
|
selection: string;
|
|
106
118
|
success: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mixColors } from "./color-mix.js";
|
|
1
2
|
// Fallbacks used when a theme key is missing: a complete theme in its own right.
|
|
2
3
|
export const FALLBACKS = {
|
|
3
4
|
accent: "#808080",
|
|
@@ -37,6 +38,10 @@ export const FALLBACKS = {
|
|
|
37
38
|
markdownStrong: "#808080",
|
|
38
39
|
markdownText: "#d4d4d4",
|
|
39
40
|
primary: "#808080",
|
|
41
|
+
searchCurrentMatchBg: "#4a4a4a",
|
|
42
|
+
searchCurrentMatchFg: "#808080",
|
|
43
|
+
searchMatchBg: "#3a3a3a",
|
|
44
|
+
searchMatchFg: "#808080",
|
|
40
45
|
secondary: "#808080",
|
|
41
46
|
selection: "#1e1e1e",
|
|
42
47
|
success: "#808080",
|
|
@@ -60,6 +65,10 @@ Object.keys(FALLBACKS);
|
|
|
60
65
|
// ---------------------------------------------------------------------------
|
|
61
66
|
// Resolution
|
|
62
67
|
// ---------------------------------------------------------------------------
|
|
68
|
+
/** Share of `warning` blended over `background` for a derived `searchMatchBg`. */
|
|
69
|
+
const SEARCH_MATCH_TINT = 0.22;
|
|
70
|
+
/** Share of `primary` blended over `background` for a derived `searchCurrentMatchBg`. */
|
|
71
|
+
const SEARCH_CURRENT_MATCH_TINT = 0.35;
|
|
63
72
|
/** A mode-specific colour pair is an object; a single colour is a string. */
|
|
64
73
|
const isVariant = function isVariant(value) {
|
|
65
74
|
return value instanceof Object;
|
|
@@ -102,6 +111,19 @@ export const resolveTheme = function resolveTheme(json, mode) {
|
|
|
102
111
|
if (json.theme.selection === undefined) {
|
|
103
112
|
result.selection = result.backgroundPanel;
|
|
104
113
|
}
|
|
114
|
+
// Search highlights tint the background, so matched text stays readable.
|
|
115
|
+
if (json.theme.searchMatchBg === undefined) {
|
|
116
|
+
result.searchMatchBg = mixColors(result.background, result.warning, SEARCH_MATCH_TINT);
|
|
117
|
+
}
|
|
118
|
+
if (json.theme.searchCurrentMatchBg === undefined) {
|
|
119
|
+
result.searchCurrentMatchBg = mixColors(result.background, result.primary, SEARCH_CURRENT_MATCH_TINT);
|
|
120
|
+
}
|
|
121
|
+
if (json.theme.searchMatchFg === undefined) {
|
|
122
|
+
result.searchMatchFg = result.warning;
|
|
123
|
+
}
|
|
124
|
+
if (json.theme.searchCurrentMatchFg === undefined) {
|
|
125
|
+
result.searchCurrentMatchFg = result.primary;
|
|
126
|
+
}
|
|
105
127
|
return result;
|
|
106
128
|
};
|
|
107
129
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tooee/themes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Theme management with 34 bundled themes for Tooee",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"typecheck": "tsc --noEmit"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@tooee/config": "0.
|
|
43
|
+
"@tooee/config": "0.13.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@opentui/core": "^0.5.12",
|
package/src/color-mix.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Hex colour blending for derived theme tokens.
|
|
2
|
+
|
|
3
|
+
interface Rgba {
|
|
4
|
+
r: number;
|
|
5
|
+
g: number;
|
|
6
|
+
b: number;
|
|
7
|
+
a: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const SHORT_HEX = /^#(?<digits>[0-9a-f]{3,4})$/iu;
|
|
11
|
+
|
|
12
|
+
const LONG_HEX = /^#(?<digits>[0-9a-f]{6}|[0-9a-f]{8})$/iu;
|
|
13
|
+
|
|
14
|
+
const parseHex = function parseHex(hex: string): Rgba | null {
|
|
15
|
+
const short = SHORT_HEX.exec(hex)?.groups?.digits;
|
|
16
|
+
|
|
17
|
+
const digits =
|
|
18
|
+
short === undefined
|
|
19
|
+
? LONG_HEX.exec(hex)?.groups?.digits
|
|
20
|
+
: short.replaceAll(/(?<d>.)/gu, "$1$1");
|
|
21
|
+
|
|
22
|
+
if (digits === undefined) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const channel = (index: number): number =>
|
|
27
|
+
Number.parseInt(digits.slice(index * 2, index * 2 + 2), 16);
|
|
28
|
+
|
|
29
|
+
return { a: digits.length === 8 ? channel(3) : 255, b: channel(2), g: channel(1), r: channel(0) };
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const toHex = function toHex(value: number): string {
|
|
33
|
+
return Math.round(value).toString(16).padStart(2, "0");
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const toRgbHex = function toRgbHex(source: Rgba): string {
|
|
37
|
+
return `#${toHex(source.r)}${toHex(source.g)}${toHex(source.b)}`;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Blend `amount` (0 to 1) of `tint` over `base`.
|
|
42
|
+
*
|
|
43
|
+
* An opaque base gives an opaque colour. A fully transparent base, such as a
|
|
44
|
+
* theme that leaves the terminal background visible, gives `tint` at `amount`
|
|
45
|
+
* opacity, so the renderer blends it over whatever is behind. When either
|
|
46
|
+
* colour cannot be parsed, the result is `tint`.
|
|
47
|
+
*/
|
|
48
|
+
export const mixColors = function mixColors(base: string, tint: string, amount: number): string {
|
|
49
|
+
const from = parseHex(base);
|
|
50
|
+
const to = parseHex(tint);
|
|
51
|
+
|
|
52
|
+
if (from === null || to === null) {
|
|
53
|
+
return tint;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (from.a === 0) {
|
|
57
|
+
return `${toRgbHex(to)}${toHex(to.a * amount)}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return toRgbHex({
|
|
61
|
+
a: 255,
|
|
62
|
+
b: from.b + (to.b - from.b) * amount,
|
|
63
|
+
g: from.g + (to.g - from.g) * amount,
|
|
64
|
+
r: from.r + (to.r - from.r) * amount,
|
|
65
|
+
});
|
|
66
|
+
};
|
package/src/context.tsx
CHANGED
|
@@ -59,6 +59,7 @@ export const ThemeProvider = function ThemeProvider({
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const t = buildTheme(name ?? DEFAULT_THEME_NAME, mode ?? DEFAULT_MODE);
|
|
62
|
+
|
|
62
63
|
return { mode: t.mode, name: t.name, syntax: t.syntax, theme: t.colors };
|
|
63
64
|
}, [themeProp, name, mode]);
|
|
64
65
|
|
|
@@ -77,6 +78,8 @@ interface ThemeSwitcherContextValue extends ThemeContextValue {
|
|
|
77
78
|
nextTheme: () => void;
|
|
78
79
|
prevTheme: () => void;
|
|
79
80
|
setTheme: (name: string, opts?: { persist?: boolean }) => void;
|
|
81
|
+
/** Switch between the light and dark variants of the current theme. */
|
|
82
|
+
setMode: (mode: ColorMode, opts?: { persist?: boolean }) => void;
|
|
80
83
|
allThemes: string[];
|
|
81
84
|
}
|
|
82
85
|
|
|
@@ -96,7 +99,6 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({
|
|
|
96
99
|
const allThemes = useMemo(() => getThemeNames(), []);
|
|
97
100
|
const [themeName, setThemeName] = useState(initialTheme ?? DEFAULT_THEME_NAME);
|
|
98
101
|
const [mode, setMode] = useState<ColorMode>(initialMode ?? DEFAULT_MODE);
|
|
99
|
-
void setMode;
|
|
100
102
|
|
|
101
103
|
const theme = useMemo(() => buildTheme(themeName, mode), [themeName, mode]);
|
|
102
104
|
|
|
@@ -117,6 +119,7 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({
|
|
|
117
119
|
const setThemeByName = useCallback(
|
|
118
120
|
(name: string, opts?: { persist?: boolean }) => {
|
|
119
121
|
setThemeName(name);
|
|
122
|
+
|
|
120
123
|
if (opts?.persist === true) {
|
|
121
124
|
writeGlobalConfig({ theme: { mode, name } });
|
|
122
125
|
}
|
|
@@ -124,6 +127,17 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({
|
|
|
124
127
|
[mode]
|
|
125
128
|
);
|
|
126
129
|
|
|
130
|
+
const setModeByName = useCallback(
|
|
131
|
+
(nextMode: ColorMode, opts?: { persist?: boolean }) => {
|
|
132
|
+
setMode(nextMode);
|
|
133
|
+
|
|
134
|
+
if (opts?.persist === true) {
|
|
135
|
+
writeGlobalConfig({ theme: { mode: nextMode, name: themeName } });
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
[themeName]
|
|
139
|
+
);
|
|
140
|
+
|
|
127
141
|
const value = useMemo<ThemeSwitcherContextValue>(
|
|
128
142
|
() => ({
|
|
129
143
|
allThemes,
|
|
@@ -131,11 +145,12 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({
|
|
|
131
145
|
name: theme.name,
|
|
132
146
|
nextTheme,
|
|
133
147
|
prevTheme,
|
|
148
|
+
setMode: setModeByName,
|
|
134
149
|
setTheme: setThemeByName,
|
|
135
150
|
syntax: theme.syntax,
|
|
136
151
|
theme: theme.colors,
|
|
137
152
|
}),
|
|
138
|
-
[theme, mode, nextTheme, prevTheme, setThemeByName, allThemes]
|
|
153
|
+
[theme, mode, nextTheme, prevTheme, setModeByName, setThemeByName, allThemes]
|
|
139
154
|
);
|
|
140
155
|
|
|
141
156
|
const themeValue = useMemo<ThemeContextValue>(
|
|
@@ -152,8 +167,10 @@ export const ThemeSwitcherProvider = function ThemeSwitcherProvider({
|
|
|
152
167
|
|
|
153
168
|
export const useThemeSwitcher = function useThemeSwitcher(): ThemeSwitcherContextValue {
|
|
154
169
|
const ctx = useContext(ThemeSwitcherContext);
|
|
170
|
+
|
|
155
171
|
if (!ctx) {
|
|
156
172
|
throw new Error("useThemeSwitcher must be used within ThemeSwitcherProvider");
|
|
157
173
|
}
|
|
174
|
+
|
|
158
175
|
return ctx;
|
|
159
176
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export { FALLBACKS, RESOLVED_KEYS, resolveTheme } from "./types.js";
|
|
2
|
+
|
|
2
3
|
export type { ThemeJSON, ResolvedTheme } from "./types.js";
|
|
3
4
|
|
|
4
5
|
export { buildSyntaxStyle } from "./syntax-rules.js";
|
|
5
6
|
|
|
6
7
|
export { loadThemes, getThemeNames, defaultTheme } from "./loader.js";
|
|
8
|
+
|
|
7
9
|
export type { Theme } from "./loader.js";
|
|
8
10
|
|
|
9
11
|
export { ThemeProvider, ThemeSwitcherProvider, useTheme, useThemeSwitcher } from "./context.js";
|
|
12
|
+
|
|
10
13
|
export type { ThemeProviderProps, ThemeSwitcherProviderProps } from "./context.js";
|
package/src/loader.ts
CHANGED
|
@@ -30,11 +30,14 @@ const loadJsonThemesFromDir = function loadJsonThemesFromDir(
|
|
|
30
30
|
if (!existsSync(dir)) {
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
+
|
|
33
34
|
for (const file of readdirSync(dir)) {
|
|
34
35
|
if (!file.endsWith(".json")) {
|
|
35
36
|
continue;
|
|
36
37
|
}
|
|
38
|
+
|
|
37
39
|
const name = path.basename(file, ".json");
|
|
40
|
+
|
|
38
41
|
try {
|
|
39
42
|
const content = readFileSync(path.join(dir, file), "utf-8");
|
|
40
43
|
// SAFETY: the file is not validated here on purpose. Its only consumer is
|
|
@@ -54,6 +57,31 @@ const loadJsonThemesFromDir = function loadJsonThemesFromDir(
|
|
|
54
57
|
}
|
|
55
58
|
};
|
|
56
59
|
|
|
60
|
+
/**
|
|
61
|
+
* The project `.tooee/themes` folders for `cwd`, in load order: the
|
|
62
|
+
* filesystem root first and `cwd` last. A later folder replaces a theme of
|
|
63
|
+
* the same name, so the folder nearest to `cwd` wins, as config files do.
|
|
64
|
+
*/
|
|
65
|
+
export const projectThemeDirs = function projectThemeDirs(cwd: string): string[] {
|
|
66
|
+
const dirs: string[] = [];
|
|
67
|
+
let dir = cwd;
|
|
68
|
+
const seen = new Set<string>();
|
|
69
|
+
|
|
70
|
+
while (dir && !seen.has(dir)) {
|
|
71
|
+
seen.add(dir);
|
|
72
|
+
dirs.push(path.join(dir, ".tooee", "themes"));
|
|
73
|
+
const parent = path.dirname(dir);
|
|
74
|
+
|
|
75
|
+
if (parent === dir) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
dir = parent;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return dirs.toReversed();
|
|
83
|
+
};
|
|
84
|
+
|
|
57
85
|
/** Load all bundled themes from packages/themes/themes/ */
|
|
58
86
|
const loadBundledThemes = function loadBundledThemes(): Map<string, ThemeJSON> {
|
|
59
87
|
if (themeJsonCache.size > 0) {
|
|
@@ -68,17 +96,9 @@ const loadBundledThemes = function loadBundledThemes(): Map<string, ThemeJSON> {
|
|
|
68
96
|
const xdgConfig = process.env.XDG_CONFIG_HOME ?? path.join(process.env.HOME ?? "", ".config");
|
|
69
97
|
loadJsonThemesFromDir(path.join(xdgConfig, "tooee", "themes"), themeJsonCache);
|
|
70
98
|
|
|
71
|
-
// Project-local:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
while (dir && !seen.has(dir)) {
|
|
75
|
-
seen.add(dir);
|
|
76
|
-
loadJsonThemesFromDir(path.join(dir, ".tooee", "themes"), themeJsonCache);
|
|
77
|
-
const parent = path.dirname(dir);
|
|
78
|
-
if (parent === dir) {
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
dir = parent;
|
|
99
|
+
// Project-local: every .tooee/themes/ from the filesystem root down to cwd
|
|
100
|
+
for (const themesDir of projectThemeDirs(process.cwd())) {
|
|
101
|
+
loadJsonThemesFromDir(themesDir, themeJsonCache);
|
|
82
102
|
}
|
|
83
103
|
|
|
84
104
|
return themeJsonCache;
|
|
@@ -97,12 +117,14 @@ export const getThemeNames = function getThemeNames(): string[] {
|
|
|
97
117
|
// ---------------------------------------------------------------------------
|
|
98
118
|
|
|
99
119
|
export const DEFAULT_THEME_NAME = "tokyonight";
|
|
120
|
+
|
|
100
121
|
export const DEFAULT_MODE: ColorMode = "dark";
|
|
101
122
|
|
|
102
123
|
const bundledDefaultThemeText = readFileSync(
|
|
103
124
|
new URL("../themes/tokyonight.json", import.meta.url),
|
|
104
125
|
"utf-8"
|
|
105
126
|
);
|
|
127
|
+
|
|
106
128
|
// SAFETY: this package owns the bundled theme document. resolveTheme validates
|
|
107
129
|
// every consumed color and fills every omitted key from FALLBACKS.
|
|
108
130
|
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- trusted package-owned JSON boundary
|
|
@@ -110,6 +132,7 @@ const bundledDefaultThemeJson = JSON.parse(bundledDefaultThemeText) as ThemeJSON
|
|
|
110
132
|
|
|
111
133
|
const buildBundledDefaultTheme = function buildBundledDefaultTheme(mode: ColorMode): Theme {
|
|
112
134
|
const colors = resolveTheme(bundledDefaultThemeJson, mode);
|
|
135
|
+
|
|
113
136
|
return { colors, mode, name: DEFAULT_THEME_NAME, syntax: buildSyntaxStyle(colors) };
|
|
114
137
|
};
|
|
115
138
|
|
|
@@ -118,17 +141,23 @@ export const defaultTheme: Theme = buildBundledDefaultTheme(DEFAULT_MODE);
|
|
|
118
141
|
export const buildTheme = function buildTheme(name: string, mode: ColorMode): Theme {
|
|
119
142
|
const themes = loadThemes();
|
|
120
143
|
const json = themes.get(name);
|
|
144
|
+
|
|
121
145
|
if (!json) {
|
|
122
146
|
// Fall back to tokyonight, then first available, then the bundled default.
|
|
123
147
|
const fallbackJson = themes.get(DEFAULT_THEME_NAME) ?? themes.values().next().value;
|
|
148
|
+
|
|
124
149
|
if (fallbackJson) {
|
|
125
150
|
const resolved = resolveTheme(fallbackJson, mode);
|
|
151
|
+
|
|
126
152
|
return { colors: resolved, mode, name, syntax: buildSyntaxStyle(resolved) };
|
|
127
153
|
}
|
|
154
|
+
|
|
128
155
|
return buildBundledDefaultTheme(mode);
|
|
129
156
|
}
|
|
157
|
+
|
|
130
158
|
try {
|
|
131
159
|
const resolved = resolveTheme(json, mode);
|
|
160
|
+
|
|
132
161
|
return { colors: resolved, mode, name, syntax: buildSyntaxStyle(resolved) };
|
|
133
162
|
} catch {
|
|
134
163
|
return buildBundledDefaultTheme(mode);
|