diff --git a/components/viewer/ViewProjectRow.vue b/components/viewer/ViewProjectRow.vue index 5f28eea..7400815 100644 --- a/components/viewer/ViewProjectRow.vue +++ b/components/viewer/ViewProjectRow.vue @@ -33,7 +33,7 @@ diff --git a/components/viewer/StyleRow.vue b/components/viewer/style/StyleRow.vue similarity index 100% rename from components/viewer/StyleRow.vue rename to components/viewer/style/StyleRow.vue diff --git a/components/viewer/style/engine.ts b/components/viewer/style/engine.ts new file mode 100644 index 0000000..a98a16c --- /dev/null +++ b/components/viewer/style/engine.ts @@ -0,0 +1,126 @@ +import Handlebars from 'handlebars'; +import { join, map } from 'ramda'; + +import { ObjStyles, ProjectStyles, RowStyles } from '~/composables/project'; + +export abstract class StyleGenerator { + abstract name: string; + abstract gen(styling: T): string; +} + +export function createStyles( + styling: T, + generators: StyleGenerator[], +): string { + const styles = map((generator) => generator.gen(styling).trim(), generators); + console.log('Generated Styles', styles); + return join('\n', styles); +} + +export class ProjectStylesGen extends StyleGenerator { + name = 'project'; + + private readonly _template; + constructor() { + super(); + this._template = Handlebars.compile(ProjectStylesGen.TEMPLATE); + } + + gen(styling: ProjectStyles): string { + return this._template(styling); + } + + static TEMPLATE: string = ` + .project { + background-color: {{backgroundColor}}; + } + `; +} + +export class RowStylesGen extends StyleGenerator { + name = 'row'; + + private readonly _template; + constructor() { + super(); + this._template = Handlebars.compile(RowStylesGen.TEMPLATE); + } + + gen(styling: ObjStyles): string { + return this._template(styling); + } + + static TEMPLATE: string = ` + .project-row { + {{#if rowBgColorIsOn}} + background-color: {{rowBgColor}}; + {{/if}} + + color: {{rowTextColor}}; + .row-title { + color: {{rowTitleColor}}; + } + } + `; +} + +export class ObjStylesGen extends StyleGenerator { + name = 'obj'; + + private readonly _template; + constructor() { + super(); + this._template = Handlebars.compile(ObjStylesGen.TEMPLATE); + } + + gen(styling: ObjStyles): string { + // Ugly Hack but the origina format is cursed + const computed = { + objectBorderRadiusUnit: styling.objectBorderRadiusIsPixels ? 'px' : '%', + objectBorderRadiusTopLeft: + Number.parseFloat(styling.objectBorderRadiusTopLeft) * 10, + objectBorderRadiusTopRight: + Number.parseFloat(styling.objectBorderRadiusTopRight) * 10, + objectBorderRadiusBottomLeft: + Number.parseFloat(styling.objectBorderRadiusBottomLeft) * 10, + objectBorderRadiusBottomRight: + Number.parseFloat(styling.objectBorderRadiusBottomRight) * 10, + }; + return this._template({ ...styling, ...computed }); + } + + static TEMPLATE: string = ` + .project-obj { + {{#if objectBgColorIsOn}} + background-color: {{objectBgColor}}; + {{/if}} + + color: {{objectTextColor}}; + .object-title { + color: {{objectTitleColor}}; + } + + {{#if objectBorderIsOn}} + border-color: {{objectBorderColor}}; + border-style: {{objectBorderStyle}}; + border-width: {{objectBorderWidth}}px; + + border-top-left-radius: {{objectBorderRadiusTopLeft}}{{objectBorderRadiusUnit}}; + border-top-right-radius: {{objectBorderRadiusTopRight}}{{objectBorderRadiusUnit}}; + border-bottom-left-radius: {{objectBorderRadiusBottomLeft}}{{objectBorderRadiusUnit}}; + border-bottom-right-radius: {{objectBorderRadiusBottomRight}}{{objectBorderRadiusUnit}}; + {{/if}} + + {{#if selBgColorIsOn}} + &.selected { + background-color: {{selFilterBgColor}} + } + {{/if}} + {{#if reqBgColorIsOn}} + &.disabled { + background-color: {{reqFilterBgColor}} + } + {{/if}} + } + `; +} diff --git a/composables/project.ts b/composables/project.ts index 3035114..0735cf5 100644 --- a/composables/project.ts +++ b/composables/project.ts @@ -6,6 +6,28 @@ export type AddonStyles = { export type ObjStyles = { objectTitle: string; objectText: string; + + objectTitleColor: string; + objectTextColor: string; + + objectBgColorIsOn: boolean; + objectBgColor: string; + + objectBorderIsOn: boolean; + objectBorderColor: string; + objectBorderStyle: string; + objectBorderWidth: number; + objectBorderRadiusTopLeft: string; + objectBorderRadiusTopRight: string; + objectBorderRadiusBottomRight: string; + objectBorderRadiusBottomLeft: string; + objectBorderRadiusIsPixels: boolean; + + selBgColorIsOn: boolean; + selFilterBgColor: string; + + reqBgColorIsOn: boolean; + reqFilterBgColor: string; }; export type RowStyles = ObjStyles & diff --git a/package.json b/package.json index 0e9cad3..893cea3 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@vueuse/core": "^10.7.2", "@vueuse/nuxt": "^10.7.2", "bootstrap": "5.3.*", + "handlebars": "^4.7.8", "perfect-debounce": "^1.0.0", "pinia": "^2.1.6", "ramda": "^0.29.0", diff --git a/pages/index.vue b/pages/index.vue index 04a6222..6e7319b 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -75,7 +75,7 @@ import { ref } from '#imports'; import ViewBackpack from '~/components/viewer/modal/ViewBackpack.vue'; import ViewSearch from '~/components/viewer/modal/ViewSearch.vue'; -import StyleProject from '~/components/viewer/StyleProject.vue'; +import StyleProject from '~/components/viewer/style/StyleProject.vue'; import ViewMenuBar from '~/components/viewer/ViewMenuBar.vue'; import { useProjectRefs, useProjectStore } from '~/composables/store/project'; diff --git a/yarn.lock b/yarn.lock index 959e7e7..2a7764e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6454,6 +6454,24 @@ __metadata: languageName: node linkType: hard +"handlebars@npm:^4.7.8": + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" + dependencies: + minimist: ^1.2.5 + neo-async: ^2.6.2 + source-map: ^0.6.1 + uglify-js: ^3.1.4 + wordwrap: ^1.0.0 + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 00e68bb5c183fd7b8b63322e6234b5ac8fbb960d712cb3f25587d559c2951d9642df83c04a1172c918c41bcfc81bfbd7a7718bbce93b893e0135fc99edea93ff + languageName: node + linkType: hard + "has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -7805,7 +7823,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.6, minimist@npm:^1.2.7": +"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.7": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -8027,6 +8045,13 @@ __metadata: languageName: node linkType: hard +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 + languageName: node + linkType: hard + "nitropack@npm:^2.5.2": version: 2.6.0 resolution: "nitropack@npm:2.6.0" @@ -8432,6 +8457,7 @@ __metadata: eslint-plugin-import: ^2.28.1 eslint-plugin-prettier: ^5.0.0 eslint-plugin-unused-imports: ^3.0.0 + handlebars: ^4.7.8 nuxt: ^3.6.5 perfect-debounce: ^1.0.0 pinia: ^2.1.6 @@ -10167,7 +10193,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:~0.6.1": +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 @@ -10867,6 +10893,15 @@ __metadata: languageName: node linkType: hard +"uglify-js@npm:^3.1.4": + version: 3.18.0 + resolution: "uglify-js@npm:3.18.0" + bin: + uglifyjs: bin/uglifyjs + checksum: 887733d05d4139a94dffd04a5f07ee7d8be70201c016ea48cb82703778b5c48fadbe6e5e7ac956425522f72e657d3eade23f06ae8a0e2eeed2d684bf6cc25e36 + languageName: node + linkType: hard + "ultrahtml@npm:^1.2.0": version: 1.3.0 resolution: "ultrahtml@npm:1.3.0" @@ -11802,6 +11837,13 @@ __metadata: languageName: node linkType: hard +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 2a44b2788165d0a3de71fd517d4880a8e20ea3a82c080ce46e294f0b68b69a2e49cff5f99c600e275c698a90d12c5ea32aff06c311f0db2eb3f1201f3e7b2a04 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0"