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%;
}
/* 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 */
.inp :is(input, textarea, select) {
.inp :is(input, textarea, select), .inp:is(input, textarea, select) {
display: block;
width: 100%;
font-family: inherit;
@ -52,7 +21,7 @@
margin: 0px;
}
.inp :is(input, textarea, select):focus {
:is(.inp :is(input, textarea, select), .inp:is(input, textarea, select)):focus {
outline: none;
border-color: var(--synergy-border-active);
}
@ -79,8 +48,8 @@
pointer-events: none;
}
.inp textarea {
.inp textarea, textarea.inp {
height: 100px;
max-width: 100%;
resize: vertical;
}
}

View file

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

View file

@ -2,17 +2,17 @@
<div class="preview">
<form class="form" @submit.prevent>
<div class="inp">
<div class="inp inp-fancy">
<input type="text" placeholder=" ">
<label>Name</label>
</div>
<div class="inp">
<div class="inp inp-fancy">
<input type="text" placeholder=" ">
<label>Surname</label>
</div>
<div class="inp select">
<div class="inp inp-fancy select">
<select>
<option disabled>Disabled</option>
<option>Guest</option>
@ -22,7 +22,7 @@
<label>Role</label>
</div>
<div class="inp">
<div class="inp inp-fancy">
<textarea placeholder=" ">Some very long text...</textarea>
<label>Long text</label>
</div>
@ -67,21 +67,6 @@
</label>
</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">
<button class="btn btn-primary">
Send

View file

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

View file

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

View file

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

View file

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