Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

40 Implemented dynamic global css variables #89

Merged
merged 17 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions src/lib/GlobalCssProperties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{
"default": {
"mediaFeature": "default",
"color": {
"--navigationbar-text-color": ["display-p3", 1, 1, 1, 0],
"--console-scrollbar-thumb-color": [
"display-p3",
0.22745098039,
0.27450980392,
0.30588235294
],
"--console-scrollbar-thumbhover-color": [
"display-p3",
0.2862745098,
0.34901960784,
0.38823529411
],
"--query-success-color": [
"display-p3",
0.31372549019,
0.54901960784,
0.27450980392
],
"--query-warning-color": [
"display-p3",
0.98431372549,
0.75294117647,
0.17647058823
],
"--query-error-color": [
"display-p3",
0.82745098039,
0.18431372549,
0.18431372549
],
"--main-navigationbar-color": [
"display-p3",
0.22745098039,
0.27450980392,
0.30588235294
],
"--canvas-topbar-color": [
"display-p3",
0.2862745098,
0.34901960784,
0.38823529411
],
"--canvas-text-color": ["display-p3", 0, 0, 0],
"--sidebar-text-color": ["display-p3", 0, 0, 0],
"--background-color": [
"display-p3",
0.95686274509,
0.95686274509,
0.95686274509
],
"--console-selectedtab-color": [
"display-p3",
0.2862745098,
0.34901960784,
0.38823529411
],
"--console-unselectedtab-color": [
"display-p3",
0.22745098039,
0.27450980392,
0.30588235294
],
"--console-topbar-background-color": [
"display-p3",
0.22745098039,
0.27450980392,
0.30588235294
],
"--console-text-color": ["display-p3", 0, 0, 0],
"--sidebar-element-color": [
"display-p3",
0.93333333333,
0.93333333333,
0.93333333333
],
"--sidebar-element-hover-color": [
"display-p3",
0.81176470588,
0.84705882352,
0.86274509803
],
"--queries-input-background-color": ["display-p3", 1, 1, 1],
"--canvas-action-color": ["display-p3", 0, 0, 0],
"--console-tab-hover-color": [
"display-p3",
0.3362745098,
0.39901960784,
0.43823529411
]
},
"fontSize": {
"--sidebar-fontsize": [1, "rem"],
"--sidebar-navigationbar-fontsize": [1, "rem"]
},
"border": {
"--main-navigationbar-border": [
"solid",
[0.1, "em"],
["display-p3", 0.18823529411, 0.22745098039, 0.25098039215]
],
"--main-innernavigationbar-border": [
"none solid solid solid",
[0.1, "em"],
["display-p3", 0.18823529411, 0.22745098039, 0.25098039215]
]
}
},
"schemes": [
{
"mediaFeature": "prefers-color-scheme: dark",
"color": {
"--main-navigationbar-color": [
"display-p3",
0.0156862745,
0.02352941176,
0.03529411764
],
"--canvas-topbar-color": [
"display-p3",
0.05490196078,
0.06666666666,
0.09019607843
],
"--canvas-text-color": ["display-p3", 1, 1, 1],
"--sidebar-text-color": ["display-p3", 1, 1, 1],
"--background-color": [
"display-p3",
0.09019607843,
0.10196078431,
0.13333333333
],
"--console-selectedtab-color": [
"display-p3",
0.08490196078,
0.09666666666,
0.12019607843
],
"--console-unselectedtab-color": [
"display-p3",
0.0156862745,
0.02352941176,
0.03529411764
],
"--console-topbar-background-color": [
"display-p3",
0.0156862745,
0.02352941176,
0.03529411764
],
"--console-text-color": ["display-p3", 1, 1, 1],
"--sidebar-element-color": [
"display-p3",
0.19215686274,
0.21176470588,
0.23529411764
],
"--sidebar-element-hover-color": [
"display-p3",
0.12215686274,
0.23176470588,
0.25529411764
],
"--queries-input-background-color": [
"display-p3",
0.05490196078,
0.06666666666,
0.09019607843
],
"--canvas-action-color": ["display-p3", 1, 1, 1],
"--console-tab-hover-color": [
"display-p3",
0.13490196078,
0.14666666666,
0.17019607843
]
}
}
]
}
156 changes: 156 additions & 0 deletions src/lib/classes/styling/GlobalCssSchemesLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import type ColorValue from "./ZodSchemas/AttributeSchemas/ColorAttribute";
import type MediaScheme from "./ZodSchemas/MediaScheme";

import MediaSchemes from "./ZodSchemas/MediaSchemes";
import GlobalCssProperties from "../../GlobalCssProperties.json";

import type { z } from "zod";

/**
* Class for handling the loading of different properties based on active media features
*/
class GlobalCssSchemesLoader {
private _mediaSchemes: z.infer<typeof MediaSchemes>;
BaBrixx marked this conversation as resolved.
Show resolved Hide resolved
private _propertyNames: string[] = [];

constructor() {
if (!("window" in globalThis))
throw new Error(
"The CSS loader needs access to the window and DOM elements",
);

// Parse and apply the different properties
this._mediaSchemes = this.parseMediaFeatures();
this.applySchemes();

// Add event listeners to supported features
this.addEventListeners();
}

/**
* Method for applying the specified styles
*/
applySchemes() {
// Apply standard css variables
this.applyCssVariables(this._mediaSchemes.default);

// Apply each of the mediafeatures in the order in which they are specified in the .json file
this._mediaSchemes.schemes.forEach((scheme) => {
// Return early if the medie feature does not match
if (window.matchMedia(`(${scheme.mediaFeature})`).matches) {
this.applyCssVariables(scheme);
}
});
}

/**
* Method for applying CSS variabels for a specific mediafeature
* @param feature
*/
applyCssVariables(feature: z.infer<typeof MediaScheme>) {
// Apply color variables
if (feature.color) {
for (const [key, val] of Object.entries(feature.color)) {
window.document.documentElement.style.setProperty(
key,
this.createCssColor(val),
);
this._propertyNames.push(key);
}
}

// Apply font size variables
if (feature.fontSize) {
for (const [key, val] of Object.entries(feature.fontSize)) {
window.document.documentElement.style.setProperty(
key,
val[0] + val[1], //TODO: Check the font size number
);
this._propertyNames.push(key);
}
}

// Apply border variables
if (feature.border) {
for (const [key, val] of Object.entries(feature.border)) {
window.document.documentElement.style.setProperty(
key,
this.createCssColor(val[2]) /* Border color */ +
" " +
val[0] /* Border style */ +
" " +
val[1][0] /* Border size */ +
val[1][1] /* Border size unit */,
);
this._propertyNames.push(key);
}
}
}

/**
* Method for clearing the applied styles
*/
private clearAppliedProperties() {
this._propertyNames.forEach((attribute) => {
window.document.documentElement.style.removeProperty(attribute);
});

this._propertyNames = [];
}

/**
* Method for re-applying the specified styles
*/
reapplyMediaFeatures() {
this.clearAppliedProperties();
this.applySchemes();
}

/**
* Method for loading the GlobalCssProperties.json file
*/
private parseMediaFeatures(): z.infer<typeof MediaSchemes> {
// Parsing media features
const parsedMediaFeatures = MediaSchemes.safeParse(GlobalCssProperties);

// Throwing error if the parsing failed
if (!parsedMediaFeatures.success) {
throw new TypeError(parsedMediaFeatures.error.message);
}

return parsedMediaFeatures.data;
}

/**
* Method for adding appropriate event listeners
*/
private addEventListeners() {
this._mediaSchemes.schemes.forEach((scheme) => {
window
.matchMedia(`(${scheme.mediaFeature})`)
.addEventListener("change", () => {
this.reapplyMediaFeatures();
});
});
}

/**
* Method for checking and creating CSS color string
* @param color
* @returns CSS color string
*/
private createCssColor(color: z.infer<typeof ColorValue>): string {
let cssColor: string;

// Create CSS color string
if (color[4]) {
cssColor = `color(${color[0]} ${color[1]} ${color[2]} ${color[3]} / ${color[4]})`;
} else {
cssColor = `color(${color[0]} ${color[1]} ${color[2]} ${color[3]})`;
}

return cssColor;
}
}

export default GlobalCssSchemesLoader;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { z } from "zod";
import ColorAttribute from "./ColorAttribute";
import SizeAttribute from "./SizeAttribute";

/**
* Represents a border in CSS.
* A border has a string containing the styles of the border, a width representing the thickness of the border and a color.
*/

const BorderAttribute = z.tuple([
z.string(), // Border style string
SizeAttribute, // Thickness of the border
ColorAttribute, // The color of the border
]);

export default BorderAttribute;
Loading