redux-devtools/packages/redux-devtools-ui/src/utils/theme.ts
renovate[bot] 922985f9ea
chore(deps): update dependency prettier to v3 (#1434)
* chore(deps): update dependency prettier to v3

* Format

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nathan Bierema <nbierema@gmail.com>
2023-07-12 18:03:20 +00:00

82 lines
2.2 KiB
TypeScript

import { useEffect, useMemo, useState } from 'react';
import * as themes from '../themes';
import { nicinabox as defaultDarkScheme } from 'redux-devtools-themes';
import * as baseSchemes from 'base16';
import * as additionalSchemes from '../colorSchemes';
import invertColors from '../utils/invertColors';
import { Theme as ThemeBase } from '../themes/default';
export const schemes = { ...baseSchemes, ...additionalSchemes };
export const listSchemes = () => Object.keys(schemes).slice(1).sort(); // remove `__esModule`
export const listThemes = () => Object.keys(themes);
export type ThemeName = keyof typeof themes;
export type SchemeName = keyof typeof schemes;
export interface ThemeData {
theme: keyof typeof themes;
scheme: keyof typeof schemes;
colorPreference: 'auto' | 'light' | 'dark';
}
export interface ThemeFromProvider extends ThemeBase {
type: keyof typeof themes;
light: boolean;
}
const getTheme = (
type: keyof typeof themes,
scheme: keyof typeof schemes,
light: boolean,
): ThemeFromProvider => {
let colors;
if (scheme === 'default') {
colors = light ? schemes.default : defaultDarkScheme;
} else {
colors = schemes[scheme];
if (light) colors = invertColors(colors);
}
let theme = {
type,
light,
...themes.default(colors),
};
if (type !== 'default') {
theme = { ...theme, ...themes[type](colors) };
}
return theme;
};
export const useTheme = ({
theme: type,
scheme,
colorPreference,
}: ThemeData): ThemeFromProvider => {
const [prefersDarkColorScheme, setPrefersDarkColorScheme] = useState(
window.matchMedia('(prefers-color-scheme: dark)').matches,
);
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = ({ matches }: MediaQueryListEvent) => {
setPrefersDarkColorScheme(matches);
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);
const light = useMemo(
() =>
colorPreference === 'auto'
? !prefersDarkColorScheme
: colorPreference === 'light',
[colorPreference, prefersDarkColorScheme],
);
return getTheme(type, scheme, light);
};