Files
Trilium/apps/client/src/services/css_class_manager.ts

82 lines
2.8 KiB
TypeScript
Raw Normal View History

import {readCssVar} from "../utils/css-var";
import Color, { ColorInstance } from "color";
const registeredClasses = new Set<string>();
2022-09-25 14:19:30 +02:00
// Read the color lightness limits defined in the theme as CSS variables
const lightThemeColorMaxLightness = readCssVar(
document.documentElement,
"tree-item-light-theme-max-color-lightness"
).asNumber(70);
const darkThemeColorMinLightness = readCssVar(
document.documentElement,
"tree-item-dark-theme-min-color-lightness"
).asNumber(50);
2025-10-18 23:52:43 +03:00
function createClassForColor(colorString: string | null) {
2025-10-19 11:38:34 +03:00
if (!colorString?.trim()) return "";
2022-09-25 14:19:30 +02:00
2025-10-18 23:52:43 +03:00
const color = parseColor(colorString);
2025-10-19 11:38:34 +03:00
if (!color) return "";
2022-09-25 14:19:30 +02:00
2025-10-18 23:52:43 +03:00
const className = `color-${color.hex().substring(1)}`;
2022-09-25 14:19:30 +02:00
if (!registeredClasses.has(className)) {
2025-10-19 00:11:37 +03:00
const adjustedColor = adjustColorLightness(color, lightThemeColorMaxLightness!,
darkThemeColorMinLightness!);
$("head").append(`<style>
.${className}, span.fancytree-active.${className} {
--light-theme-custom-color: ${adjustedColor.lightThemeColor};
2025-10-19 00:15:06 +03:00
--dark-theme-custom-color: ${adjustedColor.darkThemeColor};
--custom-color-hue: ${getHue(color) ?? 'unset'};
}
</style>`);
2022-09-25 14:19:30 +02:00
registeredClasses.add(className);
}
return className;
}
2025-10-18 23:52:43 +03:00
function parseColor(color: string) {
try {
return Color(color);
} catch (ex) {
2025-10-19 00:02:22 +03:00
console.error(ex);
2025-10-18 23:52:43 +03:00
}
}
2025-10-19 11:38:34 +03:00
/**
* Returns a pair of colors one optimized for light themes and the other for dark themes, derived
* from the specified color to maintain sufficient contrast with each theme.
* The adjustment is performed by limiting the colors lightness in the CIELAB color space,
* according to the lightThemeMaxLightness and darkThemeMinLightness parameters.
*/
2025-10-18 23:52:43 +03:00
function adjustColorLightness(color: ColorInstance, lightThemeMaxLightness: number, darkThemeMinLightness: number) {
const labColor = color.lab();
const lightness = labColor.l();
// For the light theme, limit the maximum lightness
const lightThemeColor = labColor.l(Math.min(lightness, lightThemeMaxLightness)).hex();
2025-10-19 11:38:34 +03:00
// For the dark theme, limit the minimum lightness
const darkThemeColor = labColor.l(Math.max(lightness, darkThemeMinLightness)).hex();
return {lightThemeColor, darkThemeColor};
}
/** Returns the hue of the specified color, or undefined if the color is grayscale. */
function getHue(color: ColorInstance) {
const hslColor = color.hsl();
if (hslColor.saturationl() > 0) {
return hslColor.hue();
}
}
2022-09-25 14:19:30 +02:00
export default {
createClassForColor
2025-10-19 11:38:34 +03:00
};