57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
export const HUB_THEME_STORAGE_KEY = "cline-hub-theme";
|
|
|
|
export type HubTheme = "light" | "dark";
|
|
|
|
export function readStoredHubTheme(): HubTheme | null {
|
|
const stored = window.localStorage.getItem(HUB_THEME_STORAGE_KEY);
|
|
return stored === "light" || stored === "dark" ? stored : null;
|
|
}
|
|
|
|
export function readSystemHubTheme(): HubTheme {
|
|
const kind = document.body.dataset.vscodeThemeKind;
|
|
if (kind) {
|
|
return kind === "vscode-dark" || kind === "vscode-high-contrast"
|
|
? "dark"
|
|
: "light";
|
|
}
|
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches
|
|
? "dark"
|
|
: "light";
|
|
}
|
|
|
|
export function applyHubTheme(theme: HubTheme): HubTheme {
|
|
document.documentElement.classList.toggle("dark", theme === "dark");
|
|
document.documentElement.dataset.clineHubTheme = theme;
|
|
return theme;
|
|
}
|
|
|
|
export function syncHubTheme(): HubTheme {
|
|
return applyHubTheme(readStoredHubTheme() ?? readSystemHubTheme());
|
|
}
|
|
|
|
export function setStoredHubTheme(theme: HubTheme): HubTheme {
|
|
window.localStorage.setItem(HUB_THEME_STORAGE_KEY, theme);
|
|
return applyHubTheme(theme);
|
|
}
|
|
|
|
/**
|
|
* Follow OS light/dark changes while the user has no stored preference.
|
|
* Returns a cleanup function that removes the listener.
|
|
*/
|
|
export function watchSystemHubTheme(
|
|
onChange?: (theme: HubTheme) => void,
|
|
): () => void {
|
|
const media = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
if (!media) {
|
|
return () => {};
|
|
}
|
|
const handle = () => {
|
|
if (readStoredHubTheme() !== null) {
|
|
return;
|
|
}
|
|
onChange?.(applyHubTheme(readSystemHubTheme()));
|
|
};
|
|
media.addEventListener("change", handle);
|
|
return () => media.removeEventListener("change", handle);
|
|
}
|