17
common/resources/client/ui/themes/css-theme.ts
Executable file
17
common/resources/client/ui/themes/css-theme.ts
Executable file
@@ -0,0 +1,17 @@
|
||||
import {FontConfig} from '@common/http/value-lists';
|
||||
|
||||
export interface CssTheme {
|
||||
id: number | string;
|
||||
name: string;
|
||||
is_dark?: boolean;
|
||||
default_dark?: boolean;
|
||||
default_light?: boolean;
|
||||
values: CssThemeColors;
|
||||
font?: FontConfig;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
export interface CssThemeColors {
|
||||
[key: string]: string;
|
||||
}
|
||||
18
common/resources/client/ui/themes/theme-selector-context.ts
Executable file
18
common/resources/client/ui/themes/theme-selector-context.ts
Executable file
@@ -0,0 +1,18 @@
|
||||
import {createContext, useContext} from 'react';
|
||||
import {CssTheme} from './css-theme';
|
||||
|
||||
export type ThemeId = 'light' | 'dark' | number;
|
||||
|
||||
export interface ThemeSelectorContextValue {
|
||||
allThemes: CssTheme[];
|
||||
selectedTheme: CssTheme;
|
||||
selectTheme: (themeId: ThemeId) => void;
|
||||
}
|
||||
|
||||
export const ThemeSelectorContext = createContext<ThemeSelectorContextValue>(
|
||||
null!
|
||||
);
|
||||
|
||||
export function useThemeSelector() {
|
||||
return useContext(ThemeSelectorContext);
|
||||
}
|
||||
13
common/resources/client/ui/themes/use-dark-theme-variables.ts
Executable file
13
common/resources/client/ui/themes/use-dark-theme-variables.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
import {useBootstrapData} from '@common/core/bootstrap-data/bootstrap-data-context';
|
||||
import {useIsDarkMode} from '@common/ui/themes/use-is-dark-mode';
|
||||
|
||||
export function useDarkThemeVariables() {
|
||||
const {data} = useBootstrapData();
|
||||
const isDarkMode = useIsDarkMode();
|
||||
// already in dark mode, no need to set variables again
|
||||
if (isDarkMode) {
|
||||
return undefined;
|
||||
}
|
||||
return data.themes.all.find(theme => theme.is_dark && theme.default_dark)
|
||||
?.values;
|
||||
}
|
||||
6
common/resources/client/ui/themes/use-is-dark-mode.ts
Executable file
6
common/resources/client/ui/themes/use-is-dark-mode.ts
Executable file
@@ -0,0 +1,6 @@
|
||||
import {useThemeSelector} from './theme-selector-context';
|
||||
|
||||
export function useIsDarkMode(): boolean {
|
||||
const {selectedTheme} = useThemeSelector();
|
||||
return selectedTheme.is_dark ?? false;
|
||||
}
|
||||
7
common/resources/client/ui/themes/use-light-theme-variables.ts
Executable file
7
common/resources/client/ui/themes/use-light-theme-variables.ts
Executable file
@@ -0,0 +1,7 @@
|
||||
import {useBootstrapData} from '@common/core/bootstrap-data/bootstrap-data-context';
|
||||
|
||||
export function useLightThemeVariables() {
|
||||
const {data} = useBootstrapData();
|
||||
return data.themes.all.find(theme => !theme.is_dark && theme.default_light)
|
||||
?.values;
|
||||
}
|
||||
14
common/resources/client/ui/themes/utils/apply-theme-to-dom.ts
Executable file
14
common/resources/client/ui/themes/utils/apply-theme-to-dom.ts
Executable file
@@ -0,0 +1,14 @@
|
||||
import {CssTheme} from '../css-theme';
|
||||
import {setThemeValue} from './set-theme-value';
|
||||
import {themeEl} from '@common/core/root-el';
|
||||
|
||||
export function applyThemeToDom(theme: CssTheme) {
|
||||
Object.entries(theme.values).forEach(([key, value]) => {
|
||||
setThemeValue(key, value);
|
||||
});
|
||||
if (theme.is_dark) {
|
||||
themeEl.classList.add('dark');
|
||||
} else {
|
||||
themeEl.classList.remove('dark');
|
||||
}
|
||||
}
|
||||
9
common/resources/client/ui/themes/utils/color-to-theme-value.ts
Executable file
9
common/resources/client/ui/themes/utils/color-to-theme-value.ts
Executable file
@@ -0,0 +1,9 @@
|
||||
import {parseColor} from '@react-stately/color';
|
||||
|
||||
export function colorToThemeValue(color: string): string {
|
||||
return parseColor(color)
|
||||
.toString('rgb')
|
||||
.replace('rgb(', '')
|
||||
.replace(')', '')
|
||||
.replace(/, ?/g, ' ');
|
||||
}
|
||||
10
common/resources/client/ui/themes/utils/get-color-brightness.ts
Executable file
10
common/resources/client/ui/themes/utils/get-color-brightness.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import {parseColor} from '@react-stately/color';
|
||||
|
||||
export function getColorBrightness(value: string) {
|
||||
const parsed = parseColor(value).toFormat('rgb');
|
||||
//http://www.w3.org/TR/AERT#color-contrast
|
||||
const red = parsed.getChannelValue('red');
|
||||
const green = parsed.getChannelValue('green');
|
||||
const blue = parsed.getChannelValue('blue');
|
||||
return (red * 299 + green * 587 + blue * 114) / 1000;
|
||||
}
|
||||
9
common/resources/client/ui/themes/utils/set-theme-value.ts
Executable file
9
common/resources/client/ui/themes/utils/set-theme-value.ts
Executable file
@@ -0,0 +1,9 @@
|
||||
import {themeEl} from '@common/core/root-el';
|
||||
|
||||
export function setThemeValue(key: string, value: string) {
|
||||
themeEl?.style.setProperty(key, value);
|
||||
}
|
||||
|
||||
export function removeThemeValue(key: string) {
|
||||
themeEl?.style.removeProperty(key);
|
||||
}
|
||||
9
common/resources/client/ui/themes/utils/theme-value-to-hex.ts
Executable file
9
common/resources/client/ui/themes/utils/theme-value-to-hex.ts
Executable file
@@ -0,0 +1,9 @@
|
||||
import {parseColor} from '@react-stately/color';
|
||||
|
||||
export function themeValueToHex(value: string): string {
|
||||
try {
|
||||
return parseColor(`rgb(${value.split(' ').join(',')})`).toString('hex');
|
||||
} catch (e) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user