Skip to content

Commit

Permalink
40 Implemented dynamic global css variables (#89)
Browse files Browse the repository at this point in the history
* Implemented everything

I made a huge mistake and merge comitted the branch linked to issue #50 into my original CSS branch. This included every individual commits from the other branch into my CSS branch. I tried to revert it but failed and was therefore forced to use this solution.

* Added dark mode color to edges

* Created a CSS variable support check

This makes sure that no unsupported CSS variables are used. The supported CSS variables are specified  in CSSVariables.ts

* Changed resizer size

* Removed unnecessary media schemes

* Removed mediaFeature check

* Corrrect the parsed error type

* Removed the passing of the global window variable

* Removed the need for range checking by using zod

* Improved the zod schemes

The zod schemes now enforce:
- The color value range
- That the "default" mediascheme contains a specification of all specified CSS variables

and more...

* Fix typo

* Did some color styling to the navbar
  • Loading branch information
BaBrixx authored and TSKsmiley committed Nov 9, 2023
1 parent aeafd0e commit 70af58a
Show file tree
Hide file tree
Showing 20 changed files with 647 additions and 101 deletions.
196 changes: 196 additions & 0 deletions src/lib/GlobalCssProperties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
{
"default": {
"mediaFeature": "default",
"color": {
"--navigationbar-text-color": ["display-p3", 1, 1, 1],
"--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
],
"--navigationbar-button-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
],
"--navigationbar-button-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>;
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

0 comments on commit 70af58a

Please sign in to comment.