Separated fancy inputs & better backend
This commit is contained in:
parent
39c2e30f29
commit
4a178006b8
8 changed files with 70 additions and 88 deletions
32
src/fancy_input.css
Normal file
32
src/fancy_input.css
Normal 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;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in a new issue