From 0415751046a04296903795e178298cc8eae3d8f5 Mon Sep 17 00:00:00 2001 From: Filip Znachor Date: Mon, 19 Aug 2024 19:26:34 +0200 Subject: [PATCH] Initial commit --- .gitignore | 23 ++++++++ app.vue | 33 +++++++++++ components/Components.vue | 71 +++++++++++++++++++++++ components/Example.vue | 53 +++++++++++++++++ components/Header.vue | 25 ++++++++ components/Logo.vue | 12 ++++ components/Nav.vue | 8 +++ components/Preview.vue | 81 ++++++++++++++++++++++++++ components/Settings.vue | 63 ++++++++++++++++++++ declaration.d.ts | 5 ++ nuxt.config.ts | 15 +++++ package.json | 21 +++++++ pages/components/button.vue | 60 +++++++++++++++++++ pages/components/checkbox.vue | 22 +++++++ pages/components/index.vue | 44 ++++++++++++++ pages/components/input.vue | 57 ++++++++++++++++++ pages/components/radio.vue | 22 +++++++ pages/components/select.vue | 35 ++++++++++++ pages/components/tabs.vue | 56 ++++++++++++++++++ pages/components/textarea.vue | 17 ++++++ pages/components/toggle.vue | 28 +++++++++ pages/get-started.vue | 9 +++ pages/index.vue | 21 +++++++ plugins/highlight.client.ts | 10 ++++ src/css/demo.css | 66 +++++++++++++++++++++ src/css/style.css | 6 ++ src/ts/Color.ts | 72 +++++++++++++++++++++++ src/ts/Export.ts | 92 +++++++++++++++++++++++++++++ src/ts/Preset.ts | 105 ++++++++++++++++++++++++++++++++++ src/ts/Shared.ts | 11 ++++ src/ts/Styles.ts | 15 +++++ src/ts/Synergy.ts | 56 ++++++++++++++++++ tsconfig.json | 4 ++ 33 files changed, 1218 insertions(+) create mode 100644 .gitignore create mode 100644 app.vue create mode 100644 components/Components.vue create mode 100644 components/Example.vue create mode 100644 components/Header.vue create mode 100644 components/Logo.vue create mode 100644 components/Nav.vue create mode 100644 components/Preview.vue create mode 100644 components/Settings.vue create mode 100644 declaration.d.ts create mode 100644 nuxt.config.ts create mode 100644 package.json create mode 100644 pages/components/button.vue create mode 100644 pages/components/checkbox.vue create mode 100644 pages/components/index.vue create mode 100644 pages/components/input.vue create mode 100644 pages/components/radio.vue create mode 100644 pages/components/select.vue create mode 100644 pages/components/tabs.vue create mode 100644 pages/components/textarea.vue create mode 100644 pages/components/toggle.vue create mode 100644 pages/get-started.vue create mode 100644 pages/index.vue create mode 100644 plugins/highlight.client.ts create mode 100644 src/css/demo.css create mode 100644 src/css/style.css create mode 100644 src/ts/Color.ts create mode 100644 src/ts/Export.ts create mode 100644 src/ts/Preset.ts create mode 100644 src/ts/Shared.ts create mode 100644 src/ts/Styles.ts create mode 100644 src/ts/Synergy.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9faf4c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* diff --git a/app.vue b/app.vue new file mode 100644 index 0000000..e34d522 --- /dev/null +++ b/app.vue @@ -0,0 +1,33 @@ + + + \ No newline at end of file diff --git a/components/Components.vue b/components/Components.vue new file mode 100644 index 0000000..e069ff6 --- /dev/null +++ b/components/Components.vue @@ -0,0 +1,71 @@ + + + diff --git a/components/Example.vue b/components/Example.vue new file mode 100644 index 0000000..5a41461 --- /dev/null +++ b/components/Example.vue @@ -0,0 +1,53 @@ + + + + + \ No newline at end of file diff --git a/components/Header.vue b/components/Header.vue new file mode 100644 index 0000000..9ca65c1 --- /dev/null +++ b/components/Header.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/components/Logo.vue b/components/Logo.vue new file mode 100644 index 0000000..13a009c --- /dev/null +++ b/components/Logo.vue @@ -0,0 +1,12 @@ + diff --git a/components/Nav.vue b/components/Nav.vue new file mode 100644 index 0000000..afa0e80 --- /dev/null +++ b/components/Nav.vue @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/components/Preview.vue b/components/Preview.vue new file mode 100644 index 0000000..b0052c9 --- /dev/null +++ b/components/Preview.vue @@ -0,0 +1,81 @@ + diff --git a/components/Settings.vue b/components/Settings.vue new file mode 100644 index 0000000..6659a2b --- /dev/null +++ b/components/Settings.vue @@ -0,0 +1,63 @@ + + + diff --git a/declaration.d.ts b/declaration.d.ts new file mode 100644 index 0000000..2bba51e --- /dev/null +++ b/declaration.d.ts @@ -0,0 +1,5 @@ +declare module '*.css'; + +declare interface ComboObject { + [U: string]: any +}; diff --git a/nuxt.config.ts b/nuxt.config.ts new file mode 100644 index 0000000..b2ad44f --- /dev/null +++ b/nuxt.config.ts @@ -0,0 +1,15 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + compatibilityDate: "2024-08-19", + + css: [ + "~/src/css/style.css", + "~/src/css/demo.css" + ], + modules: [ + "@nuxt/icon" + ], + devtools: { + enabled: false + } +}) \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..e11510d --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "nuxt-app", + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@highlightjs/vue-plugin": "^2.1.0", + "@iconify-json/ic": "^1.1.18", + "@iconify-json/mdi": "^1.1.68", + "@nuxt/icon": "^1.4.5", + "html": "^1.0.0", + "nuxt": "^3.12.4", + "nuxt-icon": "^1.0.0-beta.7", + "vue": "latest" + } +} diff --git a/pages/components/button.vue b/pages/components/button.vue new file mode 100644 index 0000000..af7342a --- /dev/null +++ b/pages/components/button.vue @@ -0,0 +1,60 @@ + diff --git a/pages/components/checkbox.vue b/pages/components/checkbox.vue new file mode 100644 index 0000000..361e169 --- /dev/null +++ b/pages/components/checkbox.vue @@ -0,0 +1,22 @@ + diff --git a/pages/components/index.vue b/pages/components/index.vue new file mode 100644 index 0000000..9c9880f --- /dev/null +++ b/pages/components/index.vue @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/pages/components/input.vue b/pages/components/input.vue new file mode 100644 index 0000000..aa3e5c7 --- /dev/null +++ b/pages/components/input.vue @@ -0,0 +1,57 @@ + diff --git a/pages/components/radio.vue b/pages/components/radio.vue new file mode 100644 index 0000000..cfb5ce7 --- /dev/null +++ b/pages/components/radio.vue @@ -0,0 +1,22 @@ + diff --git a/pages/components/select.vue b/pages/components/select.vue new file mode 100644 index 0000000..a938495 --- /dev/null +++ b/pages/components/select.vue @@ -0,0 +1,35 @@ + diff --git a/pages/components/tabs.vue b/pages/components/tabs.vue new file mode 100644 index 0000000..155f85a --- /dev/null +++ b/pages/components/tabs.vue @@ -0,0 +1,56 @@ + diff --git a/pages/components/textarea.vue b/pages/components/textarea.vue new file mode 100644 index 0000000..4c8afe4 --- /dev/null +++ b/pages/components/textarea.vue @@ -0,0 +1,17 @@ + diff --git a/pages/components/toggle.vue b/pages/components/toggle.vue new file mode 100644 index 0000000..bb24764 --- /dev/null +++ b/pages/components/toggle.vue @@ -0,0 +1,28 @@ + diff --git a/pages/get-started.vue b/pages/get-started.vue new file mode 100644 index 0000000..2de3237 --- /dev/null +++ b/pages/get-started.vue @@ -0,0 +1,9 @@ + diff --git a/pages/index.vue b/pages/index.vue new file mode 100644 index 0000000..945d52c --- /dev/null +++ b/pages/index.vue @@ -0,0 +1,21 @@ + diff --git a/plugins/highlight.client.ts b/plugins/highlight.client.ts new file mode 100644 index 0000000..3d7be3b --- /dev/null +++ b/plugins/highlight.client.ts @@ -0,0 +1,10 @@ +import hljs from 'highlight.js/lib/core' +import xml from 'highlight.js/lib/languages/xml' +import highlightJS from '@highlightjs/vue-plugin' +import 'highlight.js/styles/atom-one-dark.css' +import { defineNuxtPlugin } from 'nuxt/app'; + +export default defineNuxtPlugin((nuxtApp) => { + hljs.registerLanguage('html', xml) + nuxtApp.vueApp.use(highlightJS) +}); diff --git a/src/css/demo.css b/src/css/demo.css new file mode 100644 index 0000000..1b59bbe --- /dev/null +++ b/src/css/demo.css @@ -0,0 +1,66 @@ +:root { + --site-padding: 40px; +} + +@media screen and (max-width: 700px) { + :root { + --site-padding: 20px; + } +} + +html {background: var(--synergy-site-bg);} +html, body {color: var(--synergy-text-color); font-family: Cantarell, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Open Sans, Helvetica Neue, Arial, Noto Sans, Roboto, sans-serif; font-size: 18px; margin: 0;} + +*, *::before, *::after {box-sizing: border-box;} + +:is(header, section, footer, nav) > .inner {margin: 70px auto; padding: 0 var(--site-padding); max-width: 1000px;} + +nav {background: var(--synergy-tab-highlight); border-bottom: var(--synergy-border-width) solid var(--synergy-border); overflow: hidden;} +nav > .inner {margin: 15px auto; display: flex; gap: 25px; flex-wrap: wrap; align-items: center;} +nav a {text-decoration: none;} +nav svg {max-height: 33px;} + +.logo {max-width: 200px;} + +.sec-bg {background-color: var(--synergy-tab-highlight); padding: .1px; border: var(--synergy-border-width) solid var(--synergy-border); border-right-width: 0; border-left-width: 0;} + +.settings {display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: start;} +.settings > * {position: sticky; top: 0;} +.settings h2 {text-align: center;} +.settings > * > :first-child {margin-top: 0;} +.settings .variables {display: grid; gap: 10px 20px; align-items: center; grid-template-columns: max-content 1fr;} +.settings .variables > * {display: flex; gap: 10px; align-items: center;} + +.settings .presets {display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px;} +.settings .presets > * {display: flex; border-radius: 10px; overflow: hidden; cursor: pointer; box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .1);} +.settings .presets > * > * {height: 100px; flex: 1;} + +.settings .components .item {margin-bottom: 10px;} +.settings .components .btn-row {margin-top: 15px;} +.settings .components .box {margin-top: 15px; background-color: var(--synergy-bg); border: var(--synergy-border-width) solid var(--synergy-border); padding: 15px; border-radius: var(--synergy-border-radius);} +.settings .components .btn small {display: block; font-weight: 400; font-size: 11px; margin-top: 3px;} +.settings .components .export .btn-row {margin: 15px 0;} + +@media screen and (max-width: 850px) { + .settings {display: flex; flex-direction: column-reverse; align-items: normal;} + .settings > * {position: static;} +} + +@media screen and (max-width: 500px) { + .settings .variables {display: block;} + .settings .variables label {margin: 20px 0 10px;} +} + +.form {display: flex; flex-direction: column; gap: 15px; max-width: 450px;} +.form > * {margin: 0;} + +.colori {aspect-ratio: 1 / 1; height: 36px; border-radius: var(--synergy-border-radius);} + +a {color: inherit;} + +h1 {font-size: 2em;} +h2 {font-size: 1.5em;} + +code:not(.hljs) {font-size: .9em; background-color: #aaa2; padding: 3px 5px; border-radius: var(--synergy-border-radius);} + +.text-center {text-align: center;} diff --git a/src/css/style.css b/src/css/style.css new file mode 100644 index 0000000..2c87b42 --- /dev/null +++ b/src/css/style.css @@ -0,0 +1,6 @@ +@import url("~/public/src/button.css"); +@import url("~/public/src/input.css"); +@import url("~/public/src/fancy-input.css"); +@import url("~/public/src/toggle.css"); +@import url("~/public/src/checkbox.css"); +@import url("~/public/src/tabs.css"); diff --git a/src/ts/Color.ts b/src/ts/Color.ts new file mode 100644 index 0000000..faf2b59 --- /dev/null +++ b/src/ts/Color.ts @@ -0,0 +1,72 @@ +export class Color { + + r: number; + g: number; + b: number; + a: number; + + constructor(r: number, g: number, b: number, a: number = 1) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + clone() { + return new Color(this.r, this.g, this.b, this.a); + } + + static fromHex(hex: string) { + let [r, g, b] = this.hexToRgb(hex); + return new Color(r, g, b); + } + + static hexToRgb(hex: string) { + hex = hex.replace(/^#/, ''); + const r = parseInt(hex.slice(0, 2), 16) / 255; + const g = parseInt(hex.slice(2, 4), 16) / 255; + const b = parseInt(hex.slice(4, 6), 16) / 255; + return [r, g, b]; + } + + alpha(alpha: number) { + return new Color(this.r, this.g, this.b, alpha); + } + + rgbFormat() { + 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) { + const getRelativeLuminance = (rgb: number) => { + const sRGB = rgb / 255; + return sRGB <= 0.03928 ? sRGB / 12.92 : Math.pow((sRGB + 0.055) / 1.055, 2.4); + }; + const luminance1 = getRelativeLuminance(this.r) * 0.2126 + + getRelativeLuminance(this.g) * 0.7152 + + getRelativeLuminance(this.b) * 0.0722; + const luminance2 = getRelativeLuminance(otherColor.r) * 0.2126 + + getRelativeLuminance(otherColor.g) * 0.7152 + + getRelativeLuminance(otherColor.b) * 0.0722; + const contrastRatio = (Math.max(luminance1, luminance2) + 0.05) / (Math.min(luminance1, luminance2) + 0.05); + return (contrastRatio*100)-100; + } + + equals(otherColor: Color) { + 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); + } + +} diff --git a/src/ts/Export.ts b/src/ts/Export.ts new file mode 100644 index 0000000..bbb3b81 --- /dev/null +++ b/src/ts/Export.ts @@ -0,0 +1,92 @@ +import { type Component, type Variable, variables } from "./Synergy"; + +export class Export { + + private variables: ComboObject; + private components: Component[]; + + public vars: string | null = null; + public css: Result[] = []; + + constructor(variables: ComboObject, components: Component[]) { + this.variables = variables; + this.components = components; + } + + async process() { + + let cssParts = []; + let selectedComponents = new Set(); + for (let c of this.components) { + if (!c.selected) continue; + let value = await (await fetch(`./src/${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); + + return this.css; + + } + + getVariables(selectedComponents: Set) { + let root: string[] = []; + for (let v of variables) { + 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, selectedComponents: Set) { + if (!variable.requiredBy) return true; + for (let id of variable.requiredBy) { + if (selectedComponents.has(id)) return true; + } + return false; + } + + async addResult(name: string, css: string) { + this.css.push({ + name, + css, + size: this.getSize(css), + size_gzip: await this.getCompressedSize(css) + }); + } + + async getCompressedSize(content: string) { + let ds = new CompressionStream("gzip"); + let blob = new Blob([content]); + let compressedStream = blob.stream().pipeThrough(ds); + return (await new Response(compressedStream).blob()).size; + } + + getSize(content: string) { + return (new TextEncoder().encode(content)).length + } + + minify(value: string) { + return value + .replace(/([^0-9a-zA-Z\.#])\s+/g, "$1") + .replace(/\s([^0-9a-zA-Z\.#]+)/g, "$1") + .replace(/;}/g, "}") + .replace(/\/\*.*?\*\//g, ""); + } + +} + +export interface Result { + name: string, + css: string, + size: number, + size_gzip: number +} diff --git a/src/ts/Preset.ts b/src/ts/Preset.ts new file mode 100644 index 0000000..d3ac6ed --- /dev/null +++ b/src/ts/Preset.ts @@ -0,0 +1,105 @@ +import { Color } from "./Color"; + +export class Preset { + + static readonly presets: Preset[] = [ + new Preset({main: "#337e2c", text: "#031601", bg: "#f3f7f2"}), + new Preset({main: "#1c71d8", text: "#030e1c", bg: "#ffffff"}), + new Preset({main: "#9141ac", text: "#613583", bg: "#ffffff", "site-bg": "#f6edf7"}), + new Preset({main: "#a51d2d", text: "#3d3846", bg: "#f6f2f1", "site-bg": "#f1e9e8"}), + new Preset({main: "#865e3c", text: "#63452c", bg: "#f9f7f4", "site-bg": "#ffffff"}), + new Preset({main: "#F45662", text: "#c4aeae", bg: "#181218"}), + new Preset({main: "#E66993", text: "#dddddd", bg: "#18181b"}), + new Preset({main: "#ffab9b", text: "#E8C3BC", bg: "#191e23"}), + new Preset({main: "#9b8fe4", text: "#cfcef4", bg: "#090818", "site-bg": "#100E22"}), + ]; + + readonly colors: Colors; + + constructor(colors: Colors) { + this.colors = Preset.convertColors(colors); + } + + private selectColor(colors: ColorType | ColorType[]): Color { + let input = Array.isArray(colors) ? colors : [colors]; + for (let key of input) { + let val = this.colors[key]; + if (val) return val; + } + return this.colors["main"]; + } + + public getColorVariables() { + const cMain = this.selectColor("main"); + const cBg = this.selectColor("bg"); + const cSiteBg = this.selectColor(["site-bg", "bg"]); + const cText = this.selectColor("text"); + const cGray = new Color(.6, .6, .6); + const cBtn = cBg.mix(cGray, .6).mix(cMain, .1); + const colors = { + "border": cMain.mix(cBg, .6), + "border-active": cMain, + "focus-highlight": cMain.alpha(.25), + "tab-highlight": cMain.alpha(.1), + "label": cMain.mix(cBg, .2), + "label-active": cMain, + "btn-primary-bg": cMain.mix(cBg, .2), + "btn-primary-bg-hover": cMain.mix(cBg, .1), + "btn-primary-text-color": this.cSelectContrast(cMain, cText, cBg, Color.fromHex("#fff"), Color.fromHex("#000")), + "btn-focus-highlight": cBtn.alpha(.25), + "btn-bg": cBtn.mix(cBg, .7), + "btn-bg-hover": cBtn.mix(cBg, .45), + "text-color": cText, + "bg": cBg, + "site-bg": cSiteBg + }; + return this.convertColorsToHex(colors); + } + + private cSelectContrast(color: Color, ...colors: Color[]) { + let bestContrast = 0; + let bestColor; + for (const otherColor of colors) { + const contrast = color.contrast(otherColor); + if (contrast > bestContrast) { + bestContrast = contrast; + bestColor = otherColor; + } + } + return bestColor; + } + + private convertColorsToHex(colors: ComboObject) { + const hexColors: ComboObject = {}; + for (const key in colors) { + if (colors.hasOwnProperty(key)) { + hexColors[key] = colors[key].hexFormat(); + } + } + return hexColors; + } + + public static convertColors(input: Colors) { + return Object.entries(input).reduce>>((acc, [key, value]) => { + acc[key as ColorType] = value instanceof Color ? value : Color.fromHex(value); + return acc; + }, {}) as Colors; + } + + public static getRandom() { + return this.presets[Math.floor(Math.random() * this.presets.length)]; + } + +} + +export type AcceptedColor = Color | string; + +// TODO: add more colors, use them if available and more specific +export interface Colors { + main: T, + text: T, + bg: T, + "site-bg"?: T +} + +type ColorType = keyof Colors; diff --git a/src/ts/Shared.ts b/src/ts/Shared.ts new file mode 100644 index 0000000..a7f583e --- /dev/null +++ b/src/ts/Shared.ts @@ -0,0 +1,11 @@ +import { reactive, watch } from "vue"; +import { components as synergyComponents, getDefaultVariables, type Component } from "./Synergy"; +import { setVariables } from "./Styles"; + +export let variableValues = reactive(getDefaultVariables()); + +export let components = reactive(synergyComponents); + +watch(() => variableValues, () => { + setVariables(variableValues); +}, {deep: true}); diff --git a/src/ts/Styles.ts b/src/ts/Styles.ts new file mode 100644 index 0000000..1922edb --- /dev/null +++ b/src/ts/Styles.ts @@ -0,0 +1,15 @@ +export let style = ref(""); + +function parseVariables(variables: ComboObject) { + let vars: string[] = []; + Object.keys(variables).forEach(key => { + if (variables[key] == null) return; + vars.push(`--synergy-${key}: ${variables[key]};`); + }); + return vars.join(""); +} + +export function setVariables(variables: ComboObject) { + const vars = parseVariables(variables); + style.value = `:root {${vars}}`; +} diff --git a/src/ts/Synergy.ts b/src/ts/Synergy.ts new file mode 100644 index 0000000..96f6a19 --- /dev/null +++ b/src/ts/Synergy.ts @@ -0,0 +1,56 @@ +import { Preset } from "./Preset"; + +export const variables: Variable[] = [ + {name: "border", type: "color", requiredBy: ["input", "checkbox", "toggle", "tabs"]}, + {name: "border-active", type: "color", requiredBy: ["input", "checkbox", "toggle", "tabs"]}, + {name: "border-width", type: "number", requiredBy: ["input", "checkbox", "toggle"]}, + {name: "border-radius", type: "number", requiredBy: ["input", "button", "checkbox", "tabs"]}, + {name: "focus-highlight", type: "color", requiredBy: ["input", "button", "checkbox"]}, + {name: "tab-highlight", type: "color", requiredBy: ["tabs"]}, + {name: "tab-bar-height", type: "number", requiredBy: ["tabs"]}, + {name: "label", type: "color", requiredBy: ["input"]}, + {name: "label-active", type: "color", requiredBy: ["input"]}, + {name: "btn-primary-bg", type: "color", requiredBy: ["button"]}, + {name: "btn-primary-bg-hover", type: "color", requiredBy: ["button"]}, + {name: "btn-primary-text-color", type: "color", requiredBy: ["button"]}, + {name: "btn-focus-highlight", type: "color", requiredBy: ["button"]}, + {name: "btn-bg", type: "color", requiredBy: ["button"]}, + {name: "btn-bg-hover", type: "color", requiredBy: ["button"]}, + {name: "text-color", type: "color", requiredBy: ["input", "button"]}, + {name: "bg", type: "color", requiredBy: ["input", "checkbox", "toggle"]}, + {name: "site-bg", type: "color"} +]; + +export const components: Component[] = [ + {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 { + name: string, + type: VariableType, + requiredBy?: ComponentID[] +} + +export type ComponentID = "button" | "input" | "fancy-input" | "checkbox" | "tabs" | "toggle"; + +export interface Component { + name: string, + id: ComponentID, + selected?: boolean +} + +export type VariableType = "color" | "number"; + +export function getDefaultVariables() { + return { + "border-width": "2px", + "border-radius": ".375rem", + "tab-bar-height": "2px", + ...Preset.getRandom().getColorVariables() + }; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a746f2a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +}