From 799d41de8f61eab9dd45d979f01c6ce9de8033e3 Mon Sep 17 00:00:00 2001 From: "Samuel M. Bednarz" Date: Fri, 5 Jan 2024 16:20:41 +0100 Subject: [PATCH] lots or organization --- packages/core/engine/primitives/attach.ts | 119 ++++++++++------------ packages/playground/src/App.vue | 26 ++--- 2 files changed, 62 insertions(+), 83 deletions(-) diff --git a/packages/core/engine/primitives/attach.ts b/packages/core/engine/primitives/attach.ts index 7b94e8d..0eddfdd 100644 --- a/packages/core/engine/primitives/attach.ts +++ b/packages/core/engine/primitives/attach.ts @@ -96,98 +96,91 @@ function getMeta(selector?: string) { export function attach({ outputs, target, alias }: Attach) { const meta = getMeta(target.selector) - const filtered = outputs.flattened.filter(({ name }) => !invalidColor(name)) - if (target.element) setElementColors(target.element, filtered) - if (target.selector) setColorSheet(target.selector, filtered, meta) + const colors = outputs.flattened.filter(({ name }) => !invalidColor(name)) + if (target.element) setElementColors(target.element, colors) + if (target.selector) setColorSheet(target.selector, colors, meta) if (alias) { - const ali = alias === true ? defaultAliases : alias - const aliasesArray = makeAliasArray(ali) - if (target.element) setElementAliases(target.element, aliasesArray) - if (target.selector) setAliasesSheet(target.selector, aliasesArray, meta) + const aliases = Object.entries(alias === true ? defaultAliases : alias) + const array = aliases.map(([key, value]) => ({ name: '--' + key, color: `var(${value})` })) + if (target.element) setElementAliases(target.element, array) + if (target.selector) setAliasSheet(target.selector, array, meta) } return outputs } -interface SetProperty { - name: 'foreground' | 'background' | 'accents' | string - color: string -} - -const setProperty = (element: HTMLElement, { name, color }: SetProperty) => { - element.style.setProperty(name, color) -} - -type AliasObject = { - name: string - value: string -} - -const makeAliasArray = (obj: Alias): AliasObject[] => { - const objArray = Object.entries(obj) - return objArray.map(([key, value]) => { - return { name: key, value: value } - }) -} - function invalidColor(name: string) { const regex = /(?:background|foreground).*contrast/i return regex.test(name) } -function setColorSheet(selector = ':root', flattened: FlattenColor[], meta?: string) { - const sheet = new CSSStyleSheet() - sheet.replace( - `theme-${meta}, ${selector} {${flattened - .map(({ name, color }) => `${name}: ${color};`) - .join('')}}` - ) - setSheet(sheet, selector) -} +//sheet functions -function setElementColors(element: HTMLElement | null, colors: FlattenColor[]) { - if (!element) return - colors.forEach(({ name, color }) => setProperty(element, { name, color })) - //Ensure that the foreground color is always set to the attached element - setProperty(element, { - name: 'color', - color: 'var(--foreground)' - }) +interface MTS { + meta?: string + marker?: string + selector?: string } -function setAliasesSheet(selector = ':root', aliases: AliasObject[], meta?: string) { - function camelToVariable(name: string) { - return '--' + name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() - } - +function makeThemeSheet( + colors: FlattenColor[], + { selector = ':root', meta = '1', marker = 'theme' }: MTS +) { const sheet = new CSSStyleSheet() sheet.replace( - `theme-alias-${meta}, :${selector} {${aliases - .map(({ name, value }) => `${camelToVariable(name)}: var(--${value});`) + `${marker}-${meta}, ${selector} {${colors + .map(({ name, color }) => `${name}: ${color};`) .join('')}}` ) + return sheet +} - setSheet(sheet, selector) +function setColorSheet(selector = ':root', colors: FlattenColor[], meta?: string) { + const marker = 'theme' + const sheet = makeThemeSheet(colors, { meta, marker, selector }) + setSheet(sheet, selector, marker) } -function setElementAliases(element: HTMLElement | null, aliases: AliasObject[]) { - if (!element) return - aliases.forEach(({ name, value }) => { - setProperty(element, { - name: name, - color: `var(--${value})` - }) - }) +function setAliasSheet(selector = ':root', colors: FlattenColor[], meta?: string) { + const marker = 'theme-alias' + const sheet = makeThemeSheet(colors, { meta, marker, selector }) + setSheet(sheet, selector, marker) } -function setSheet(sheet: CSSStyleSheet, selector: string) { +function setSheet(sheet: CSSStyleSheet, selector: string, marker = 'theme') { //this is only possible because of ...spreading the adoptedStylesheets. //Normally, you can't access the cssRules of an adopted stylesheet const filtered = [...document.adoptedStyleSheets].filter((sheet) => { - const includesUmbra = sheet.cssRules[0].cssText.includes('theme') + console.log(sheet) + const includesUmbra = sheet.cssRules[0].cssText.includes(marker) const sameTarget = sheet.cssRules[0].cssText.includes(selector) return !includesUmbra || !sameTarget }) document.adoptedStyleSheets = [...filtered, sheet] } + +//element functions + +interface SetProperty { + name: 'foreground' | 'background' | 'accents' | string + color: string +} + +const setProperty = (element: HTMLElement, { name, color }: SetProperty) => { + element.style.setProperty(name, color) +} + +function setElementColors(element: HTMLElement | null, colors: FlattenColor[]) { + if (!element) return + colors.forEach(({ name, color }) => setProperty(element, { name, color })) + //Ensure that the foreground color is always set to the attached element + setProperty(element, { + name: 'color', + color: 'var(--base-contrast)' + }) +} + +function setElementAliases(element: HTMLElement | null, aliases: FlattenColor[]) { + element && aliases.forEach((p) => setProperty(element, p)) +} diff --git a/packages/playground/src/App.vue b/packages/playground/src/App.vue index 14809f8..7083845 100644 --- a/packages/playground/src/App.vue +++ b/packages/playground/src/App.vue @@ -54,31 +54,17 @@ const theme = umbra({ background: '#000000', foreground: '#ffffff', accents: [radixBlue, radixRed, radixYellow, success, royal, brown, something, accent] -}).apply('html') - -umbra({ - background: '#000000', - foreground: '#ffffff', - accents: [radixBlue, radixRed, radixYellow, success, royal, brown, something, accent] -}).apply() - -umbra({ - background: '#000000', - foreground: '#ffffff', - accents: [radixBlue, radixRed, radixYellow, success, royal, brown, something, accent] -}).apply('body') - -umbra({ - background: '#000000', - foreground: '#ffffff', - accents: [radixBlue, radixRed, radixYellow, success, royal, brown, something, accent] -}).apply('.umbra') +}).apply('html', { + alias: true +}) const t = ref(theme.input) const formated = ref(theme.formated) function inverse() { - const newTheme = umbra(t.value.scheme).inverse().apply('body') + const newTheme = umbra(t.value.scheme).inverse().apply('body', { + alias: true + }) t.value = newTheme.input }