-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
40 Implemented dynamic global css variables (#89)
* 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
Showing
20 changed files
with
647 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
] | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
16 changes: 16 additions & 0 deletions
16
src/lib/classes/styling/ZodSchemas/AttributeSchemas/BorderAttribute.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.