-
DJ Mountney authored
* Fix some additional incorrect types - This is part of working towards having enough correct types to be able to run tsc on our packed api without error. - Working towards being able to ship types for the api in the package * Add release note
DJ Mountney authored* Fix some additional incorrect types - This is part of working towards having enough correct types to be able to run tsc on our packed api without error. - Working towards being able to ship types for the api in the package * Add release note
theme.tsx 2.48 KiB
// @ts-strict-ignore
import { useEffect, useState } from 'react';
import { isNonProductionEnvironment } from 'loot-core/src/shared/environment';
import type { Theme } from 'loot-core/src/types/prefs';
import { useGlobalPref } from '../hooks/useGlobalPref';
import * as darkTheme from './themes/dark';
import * as developmentTheme from './themes/development';
import * as lightTheme from './themes/light';
import * as midnightTheme from './themes/midnight';
const themes = {
light: { name: 'Light', colors: lightTheme },
dark: { name: 'Dark', colors: darkTheme },
midnight: { name: 'Midnight', colors: midnightTheme },
auto: { name: 'System default', colors: darkTheme },
...(isNonProductionEnvironment() && {
development: { name: 'Development', colors: developmentTheme },
}),
};
export const themeOptions = Object.entries(themes).map(
([key, { name }]) => [key, name] as [Theme, string],
);
export function useTheme() {
const [theme = 'light', setThemePref] = useGlobalPref('theme');
return [theme, setThemePref] as const;
}
export function ThemeStyle() {
const [theme] = useTheme();
const [themeColors, setThemeColors] = useState<
| typeof lightTheme
| typeof darkTheme
| typeof midnightTheme
| typeof developmentTheme
| undefined
>(undefined);
useEffect(() => {
if (theme === 'auto') {
function darkThemeMediaQueryListener(event: MediaQueryListEvent) {
if (event.matches) {
setThemeColors(themes['dark'].colors);
} else {
setThemeColors(themes['light'].colors);
}
}
const darkThemeMediaQuery = window.matchMedia(
'(prefers-color-scheme: dark)',
);
darkThemeMediaQuery.addEventListener(
'change',
darkThemeMediaQueryListener,
);
if (darkThemeMediaQuery.matches) {
setThemeColors(themes['dark'].colors);
} else {
setThemeColors(themes['light'].colors);
}
return () => {
darkThemeMediaQuery.removeEventListener(
'change',
darkThemeMediaQueryListener,
);
};
} else {
setThemeColors(themes[theme].colors);
}
}, [theme]);
if (!themeColors) return null;
const css = Object.keys(themeColors)
.map(key => ` --color-${key}: ${themeColors[key]};`)
.join('\n');
return <style>{`:root {\n${css}}`}</style>;
}
export const theme = Object.fromEntries(
Object.keys(lightTheme).map(key => [key, `var(--color-${key})`]),
) as Record<keyof typeof lightTheme, string>;