Added README and improved color mixing script

This commit is contained in:
Filip Znachor 2023-10-22 01:08:15 +02:00
parent ae9738d084
commit 1144d4b8cd
5 changed files with 66 additions and 22 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ node_modules
dist
.vercel
pnpm-lock.yaml
bun.lockb

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# Synergy
Simple, lightweight, and customizable modern CSS-only framework with UI components.
## Features
- Very lightweight (<2kb gzip) with no dependencies
- Modular components, use just what you need
- Customizable main color, so it fits your sites design (maybe add more)
- 8+ CSS-only components with no JavaScript required

View file

@ -15,14 +15,14 @@
<span class="color">Synergy</span> UI
</h1>
<p>Simple framework with CSS-only UI components</p>
<div class="colorselector">
<form autocomplete="off" class="colorselector">
<input type="color" v-model="data.preset.main" @change="applyPreset(data.preset);" title="Main color">
<input type="color" v-model="data.preset.text" @change="applyPreset(data.preset);" title="Text color">
<input type="color" v-model="data.preset.bg" @change="applyPreset(data.preset);" title="Background color">
<div class="config" title="Settings" @click="settings = !settings;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M13.875 22h-3.75q-.375 0-.65-.25t-.325-.625l-.3-2.325q-.325-.125-.613-.3t-.562-.375l-2.175.9q-.35.125-.7.025t-.55-.425L2.4 15.4q-.2-.325-.125-.7t.375-.6l1.875-1.425Q4.5 12.5 4.5 12.337v-.674q0-.163.025-.338L2.65 9.9q-.3-.225-.375-.6t.125-.7l1.85-3.225q.175-.35.537-.438t.713.038l2.175.9q.275-.2.575-.375t.6-.3l.3-2.325q.05-.375.325-.625t.65-.25h3.75q.375 0 .65.25t.325.625l.3 2.325q.325.125.613.3t.562.375l2.175-.9q.35-.125.7-.025t.55.425L21.6 8.6q.2.325.125.7t-.375.6l-1.875 1.425q.025.175.025.338v.674q0 .163-.05.338l1.875 1.425q.3.225.375.6t-.125.7l-1.85 3.2q-.2.325-.563.438t-.712-.013l-2.125-.9q-.275.2-.575.375t-.6.3l-.3 2.325q-.05.375-.325.625t-.65.25Zm-1.825-6.5q1.45 0 2.475-1.025T15.55 12q0-1.45-1.025-2.475T12.05 8.5q-1.475 0-2.488 1.025T8.55 12q0 1.45 1.012 2.475T12.05 15.5Z"/></svg>
</div>
</div>
</form>
</header>
<aside class="settings" :class="{ open: settings }">
@ -128,6 +128,21 @@
<span>Check me!</span>
</label>
<div class="tabs">
<label>
<input type="radio" name="tabs-a" checked>
<div>Ahoj</div>
</label>
<label>
<input type="radio" name="tabs-a">
<div>Ahoj</div>
</label>
<label>
<input type="radio" name="tabs-a">
<div>Ahoj</div>
</label>
</div>
<div class="btn-row">
<button class="btn btn-primary">
Send

View file

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es2016",
"target": "es2017",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,

View file

@ -113,7 +113,13 @@ export class Color {
}
rgbFormat() {
return `rgba(${this.r*255}, ${this.g*255}, ${this.b*255}, ${this.a})`;
let rgb = `${this.r*255}, ${this.g*255}, ${this.b*255}`;
return this.a == 1 ? `rgb(${rgb})` : `rgba(${rgb}, ${this.a})`;
}
hexFormat() {
let hex = `#${(1 << 24 | (this.r*255) << 16 | (this.g*255) << 8 | (this.b*255)).toString(16).slice(1)}`;
return this.a != 1 ? `${hex}${(Math.floor(this.a * 255).toString(16).padStart(2, '0'))}` : hex;
}
contrast(otherColor: Color) {
@ -132,7 +138,14 @@ export class Color {
}
equals(otherColor: Color) {
return this.r == otherColor.r && this.g == otherColor.g && this.b == otherColor.b && this.a == otherColor.a;
return this.r == otherColor.r && this.g == otherColor.g && this.b == otherColor.b;
}
mix(color: Color, ratio: number): Color {
const r = Math.round(this.r*255 * (1 - ratio) + color.r*255 * ratio);
const g = Math.round(this.g*255 * (1 - ratio) + color.g*255 * ratio);
const b = Math.round(this.b*255 * (1 - ratio) + color.b*255 * ratio);
return new Color(r/255, g/255, b/255);
}
}
@ -159,25 +172,25 @@ export class Theme {
let variables = [];
variables.push(this.var("border", this.cArgb(this.main, .4)));
variables.push(this.var("border-active", this.cArgb(this.main)));
variables.push(this.var("border", this.cAlpha(this.main, .4)));
variables.push(this.var("border-active", this.cAlpha(this.main)));
variables.push(this.var("focus-highlight", this.cArgb(this.main, .25)));
variables.push(this.var("focus-highlight", this.cMix(this.main, this.bg, .25)));
variables.push(this.var("label", this.cArgb(this.main, .8)));
variables.push(this.var("label-active", this.cArgb(this.main)));
variables.push(this.var("label", this.cMix(this.main, this.bg, .8)));
variables.push(this.var("label-active", this.cMix(this.main, this.bg)));
variables.push(this.var("btn-primary-bg", this.cArgb(this.main, .8)));
variables.push(this.var("btn-primary-bg-active", this.cArgb(this.main, .5)));
variables.push(this.var("btn-primary-bg-hover", this.cArgb(this.main)));
variables.push(this.var("btn-primary-bg", this.cMix(this.main, this.bg, .8)));
variables.push(this.var("btn-primary-bg-active", this.cMix(this.main, this.bg, .5)));
variables.push(this.var("btn-primary-bg-hover", this.cMix(this.main, this.bg)));
let btnBg = new Color(.6, .6, .6);
variables.push(this.var("btn-bg", this.cArgb(btnBg, .3)));
variables.push(this.var("btn-bg-active", this.cArgb(btnBg, .6)));
variables.push(this.var("btn-bg-hover", this.cArgb(btnBg, .4)));
let btnBg = this.bg.mix(new Color(.6, .6, .6), .8).mix(this.main, .1);
variables.push(this.var("btn-bg", this.cMix(btnBg, this.bg, .3)));
variables.push(this.var("btn-bg-active", this.cMix(btnBg, this.bg, .6)));
variables.push(this.var("btn-bg-hover", this.cMix(btnBg, this.bg, .4)));
variables.push(this.var("text-color", this.text.rgbFormat()));
variables.push(this.var("bg", this.bg.rgbFormat()));
variables.push(this.var("text-color", this.text.hexFormat()));
variables.push(this.var("bg", this.bg.hexFormat()));
if(this.main.contrast(this.bg) < .3) alert("Contrast between main color and the background is low!");
if(this.bg.contrast(this.text) < .3) alert("Contrast between text color and the background is low!");
@ -185,7 +198,7 @@ export class Theme {
let styles = [`:root {\n${variables.join("\n")}\n}`];
let btnColor = this.getBtnColor(this.main, this.text);
if(btnColor != this.text) styles.push(`.btn.btn-primary {\n${this.var("text-color", btnColor.rgbFormat())}\n}`);
if(btnColor != this.text) styles.push(`.btn.btn-primary {\n${this.var("text-color", btnColor.hexFormat())}\n}`);
return styles.join("\n\n");
@ -199,10 +212,15 @@ export class Theme {
return cWhite > .3 ? white : cText > .3 ? text : black;
}
cArgb(color: Color, alpha: number = 1) {
cMix(color: Color, color2: Color, ratio: number = 1) {
let c = color2.mix(color, ratio);
return c.hexFormat();
}
cAlpha(color: Color, alpha: number = 1) {
let c = color.clone();
c.a = alpha;
return c.rgbFormat();
return c.hexFormat();
}
var(name: string, value: string) {