Separated fancy inputs & better backend

This commit is contained in:
Filip Znachor 2024-08-19 00:47:44 +02:00
parent 39c2e30f29
commit 4a178006b8
8 changed files with 70 additions and 88 deletions

32
src/fancy_input.css Normal file
View file

@ -0,0 +1,32 @@
/* Label */
.inp.inp-fancy label {
position: absolute;
top: 7px;
left: 5px;
font-size: 1em;
font-weight: 700;
transform-origin: 0 0;
transform: translate3d(0, 0, 0);
transition: all .2s ease;
pointer-events: none;
background: var(--synergy-bg);
padding: 3px 8px;
border-radius: 10px;
line-height: 1.2em;
color: var(--synergy-label);
margin: var(--synergy-border-width);
}
.inp.inp-fancy :is(
:is(input, textarea, select):not(:placeholder-shown) + label,
:is(input, textarea):not(:-ms-input-placeholder) + label,
:is(input, textarea):not(:-moz-placeholder-shown) + label
),
.inp.inp-fancy :is(input, textarea):focus + label {
color: var(--synergy-label-active);
transform: scale(.8);
top: -.7em;
}

View file

@ -3,40 +3,9 @@
width: 100%; width: 100%;
} }
/* Label */
.inp label {
position: absolute;
top: 7px;
left: 5px;
font-size: 1em;
font-weight: 700;
transform-origin: 0 0;
transform: translate3d(0, 0, 0);
transition: all .2s ease;
pointer-events: none;
background: var(--synergy-bg);
padding: 3px 8px;
border-radius: 10px;
line-height: 1.2em;
color: var(--synergy-label);
margin: var(--synergy-border-width);
}
.inp :is(
:is(input, textarea, select):not(:placeholder-shown) + label,
:is(input, textarea):not(:-ms-input-placeholder) + label,
:is(input, textarea):not(:-moz-placeholder-shown) + label
),
.inp :is(input, textarea):focus + label {
color: var(--synergy-label-active);
transform: scale(.8);
top: -.7em;
}
/* Common styles */ /* Common styles */
.inp :is(input, textarea, select) { .inp :is(input, textarea, select), .inp:is(input, textarea, select) {
display: block; display: block;
width: 100%; width: 100%;
font-family: inherit; font-family: inherit;
@ -52,7 +21,7 @@
margin: 0px; margin: 0px;
} }
.inp :is(input, textarea, select):focus { :is(.inp :is(input, textarea, select), .inp:is(input, textarea, select)):focus {
outline: none; outline: none;
border-color: var(--synergy-border-active); border-color: var(--synergy-border-active);
} }
@ -79,8 +48,8 @@
pointer-events: none; pointer-events: none;
} }
.inp textarea { .inp textarea, textarea.inp {
height: 100px; height: 100px;
max-width: 100%; max-width: 100%;
resize: vertical; resize: vertical;
} }

View file

@ -2,8 +2,7 @@
import { reactive } from 'vue'; import { reactive } from 'vue';
import { Export, Result } from "../ts/Export"; import { Export, Result } from "../ts/Export";
import { components } from "../ts/Synergy"; import { variableValues, components } from "../ts/Shared";
import { variableValues, selectedComponents } from "../ts/Shared";
let data = reactive<Data>({ let data = reactive<Data>({
results: [], results: [],
@ -16,7 +15,7 @@ interface Data {
} }
async function exportCss() { async function exportCss() {
let exp = new Export(variableValues, selectedComponents); let exp = new Export(variableValues, components);
data.results = await exp.process(); data.results = await exp.process();
data.vars = exp.vars; data.vars = exp.vars;
} }
@ -45,7 +44,7 @@ function showVars() {
<form class="box" @submit.prevent="exportCss"> <form class="box" @submit.prevent="exportCss">
<div class="item" v-for="component in components"> <div class="item" v-for="component in components">
<label class="cbox"> <label class="cbox">
<input type="checkbox" v-model="selectedComponents[component.id]"> <input type="checkbox" v-model="component.selected">
<span>{{ component.name }}</span> <span>{{ component.name }}</span>
</label> </label>
</div> </div>

View file

@ -2,17 +2,17 @@
<div class="preview"> <div class="preview">
<form class="form" @submit.prevent> <form class="form" @submit.prevent>
<div class="inp"> <div class="inp inp-fancy">
<input type="text" placeholder=" "> <input type="text" placeholder=" ">
<label>Name</label> <label>Name</label>
</div> </div>
<div class="inp"> <div class="inp inp-fancy">
<input type="text" placeholder=" "> <input type="text" placeholder=" ">
<label>Surname</label> <label>Surname</label>
</div> </div>
<div class="inp select"> <div class="inp inp-fancy select">
<select> <select>
<option disabled>Disabled</option> <option disabled>Disabled</option>
<option>Guest</option> <option>Guest</option>
@ -22,7 +22,7 @@
<label>Role</label> <label>Role</label>
</div> </div>
<div class="inp"> <div class="inp inp-fancy">
<textarea placeholder=" ">Some very long text...</textarea> <textarea placeholder=" ">Some very long text...</textarea>
<label>Long text</label> <label>Long text</label>
</div> </div>
@ -67,21 +67,6 @@
</label> </label>
</div> </div>
<div class="tabs tabs-full">
<label>
<input type="radio" name="tabs2" checked>
<div>Home</div>
</label>
<label>
<input type="radio" name="tabs2">
<div>Account</div>
</label>
<label>
<input type="radio" name="tabs2">
<div>Settings</div>
</label>
</div>
<div class="btn-row"> <div class="btn-row">
<button class="btn btn-primary"> <button class="btn btn-primary">
Send Send

View file

@ -51,8 +51,6 @@ header .grid {max-width: 450px;}
.settings .variables label {margin: 20px 0 10px;} .settings .variables label {margin: 20px 0 10px;}
} }
.preview {margin: 70px 0;}
.form {display: flex; flex-direction: column; gap: 15px; max-width: 450px;} .form {display: flex; flex-direction: column; gap: 15px; max-width: 450px;}
.form > * {margin: 0;} .form > * {margin: 0;}

View file

@ -1,31 +1,34 @@
import { Variable, components, variables } from "./Synergy"; import { Component, Variable, variables } from "./Synergy";
export class Export { export class Export {
private variables: ComboObject; private variables: ComboObject;
private components: ComboObject; private components: Component[];
public vars: string | null = null; public vars: string | null = null;
public css: Result[] = []; public css: Result[] = [];
constructor(variables: ComboObject, components: ComboObject) { constructor(variables: ComboObject, components: Component[]) {
this.variables = variables; this.variables = variables;
this.components = components; this.components = components;
} }
async process() { async process() {
this.vars = this.getVariables(); let cssParts = [];
let cssParts = [this.vars]; let selectedComponents = new Set<string>();
for (let c of this.components) {
for (let c of components) { if (!c.selected) continue;
if (!this.components[c.id]) continue;
let value = await (await fetch(`./${c.id}.css`)).text(); let value = await (await fetch(`./${c.id}.css`)).text();
value = `/* ${c.name} */\n\n${value}`; value = `/* ${c.name} */\n\n${value}`;
cssParts.push(value); cssParts.push(value);
selectedComponents.add(c.id);
} }
let css = cssParts.join("\n\n/* ------------------- */\n\n"); let css = cssParts.join("\n\n/* ------------------- */\n\n");
this.vars = this.getVariables(selectedComponents);
cssParts.unshift(this.vars);
this.css = []; this.css = [];
await this.addResult("synergy.min.css", this.minify(css)); await this.addResult("synergy.min.css", this.minify(css));
await this.addResult("synergy.css", css); await this.addResult("synergy.css", css);
@ -34,19 +37,19 @@ export class Export {
} }
getVariables() { getVariables(selectedComponents: Set<string>) {
let root: string[] = []; let root: string[] = [];
for (let v of variables) { for (let v of variables) {
if (!this.required(v)) continue; if (!this.required(v, selectedComponents)) continue;
root.push(`\t--synergy-${v.name}: ${this.variables[v.name]};`); root.push(`\t--synergy-${v.name}: ${this.variables[v.name]};`);
} }
return `:root {\n${root.join("\n")}\n}`; return `:root {\n${root.join("\n")}\n}`;
} }
required(variable: Variable) { required(variable: Variable, selectedComponents: Set<string>) {
if (!variable.requiredBy) return true; if (!variable.requiredBy) return true;
for (let id of variable.requiredBy) { for (let id of variable.requiredBy) {
if (this.components[id]) return true; if (selectedComponents.has(id)) return true;
} }
return false; return false;
} }

View file

@ -1,13 +1,13 @@
import { reactive, watch } from "vue"; import { reactive, watch } from "vue";
import { getDefaultComponents, getDefaultVariables } from "./Synergy"; import { components as synergyComponents, getDefaultVariables, Component } from "./Synergy";
import { setVariables } from "./Styles"; import { setVariables } from "./Styles";
export let variableValues = reactive<ComboObject>(getDefaultVariables()); export let variableValues = reactive<ComboObject>(getDefaultVariables());
export let selectedComponents = reactive<ComboObject>(getDefaultComponents()); export let components = reactive<Component[]>(synergyComponents);
watch(() => variableValues, () => { watch(() => variableValues, () => {
setVariables(variableValues); setVariables(variableValues);
}, {deep: true}); }, {deep: true});
setVariables(variableValues); setVariables(variableValues);

View file

@ -22,11 +22,12 @@ export const variables: Variable[] = [
]; ];
export const components: Component[] = [ export const components: Component[] = [
{name: "Button", id: "button"}, {name: "Button", id: "button", selected: true},
{name: "Input", id: "input"}, {name: "Input", id: "input", selected: true},
{name: "Checkbox & radio", id: "checkbox"}, {name: "Checkbox & radio", id: "checkbox", selected: true},
{name: "Tabs", id: "tabs"}, {name: "Fancy input", id: "fancy_input"},
{name: "Toggle", id: "toggle"}, {name: "Tabs", id: "tabs", selected: true},
{name: "Toggle", id: "toggle", selected: true},
]; ];
export interface Variable { export interface Variable {
@ -35,11 +36,12 @@ export interface Variable {
requiredBy?: ComponentID[] requiredBy?: ComponentID[]
} }
export type ComponentID = "button" | "input" | "checkbox" | "tabs" | "toggle"; export type ComponentID = "button" | "input" | "fancy_input" | "checkbox" | "tabs" | "toggle";
export interface Component { export interface Component {
name: string, name: string,
id: ComponentID id: ComponentID,
selected?: boolean
} }
export type VariableType = "color" | "number"; export type VariableType = "color" | "number";
@ -52,9 +54,3 @@ export function getDefaultVariables() {
...Preset.getRandom().getColorVariables() ...Preset.getRandom().getColorVariables()
}; };
} }
export function getDefaultComponents() {
let res: ComboObject = {};
components.forEach(c => res[c.id] = true);
return res;
}