first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View 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;
}

View 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);
}

View 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;
}

View File

@@ -0,0 +1,6 @@
import {useThemeSelector} from './theme-selector-context';
export function useIsDarkMode(): boolean {
const {selectedTheme} = useThemeSelector();
return selectedTheme.is_dark ?? false;
}

View 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;
}

View 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');
}
}

View 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, ' ');
}

View 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;
}

View 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);
}

View 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;
}
}