diff --git a/packages/core/engine/defaults.ts b/packages/core/engine/defaults.ts index e8068f6..3d7caf3 100644 --- a/packages/core/engine/defaults.ts +++ b/packages/core/engine/defaults.ts @@ -1,4 +1,4 @@ -import { UmbraScheme, UmbraSettings } from './types' +import { UmbraInput, UmbraSettings } from './types' export const defaultSettings: UmbraSettings = { readability: 10, @@ -8,8 +8,9 @@ export const defaultSettings: UmbraSettings = { tints: [5, 10, 10, 10, 15, 15, 25, 15, 15, 15, 15, 25] } -export const defaultScheme: UmbraScheme = { +export const defaultScheme: UmbraInput = { background: '#090233', foreground: '#ff5555', - accents: ['#5200ff'] + accents: ['#5200ff'], + settings: defaultSettings } diff --git a/packages/core/engine/generator.ts b/packages/core/engine/generator.ts index 0362413..670e854 100644 --- a/packages/core/engine/generator.ts +++ b/packages/core/engine/generator.ts @@ -60,7 +60,7 @@ function replaceAtIndex(array: (number | string)[], index: number, value: string function putAccentInRange(adjusted: UmbraAdjusted, accent: Accent | string, input: UmbraInput) { const isString = typeof accent === 'string' const color = isString ? accent : accent.color - const insertion = input.settings.insertion + const insertion = input.settings?.insertion const fallback = rangeValues(adjusted, input.settings) || [] const range = isString ? fallback : rangeValues(adjusted, accent) || fallback diff --git a/packages/core/engine/index.ts b/packages/core/engine/index.ts index afbc980..bb1b718 100644 --- a/packages/core/engine/index.ts +++ b/packages/core/engine/index.ts @@ -1,6 +1,6 @@ import { colord } from 'colord' import { defaultSettings, defaultScheme } from './defaults' -import type { UmbraScheme, UmbraSettings, UmbraInput, UmbraRange } from './types' +import type { UmbraSettings, UmbraInput, UmbraRange } from './types' import { format, Formater, UmbraOutputs, AttachProps } from './primitives/format' import { inverse, isDark } from './primitives/scheme' @@ -13,31 +13,23 @@ interface ApplyProps { formater?: Formater alias?: Alias | boolean } -interface RootSettings extends UmbraSettings { - inversed?: UmbraInput -} -export function umbra(scheme = defaultScheme, settings?: RootSettings) { - const input = umbraInput({ scheme, settings }) +export function umbra(scheme = defaultScheme, inversedScheme?: UmbraInput) { + const input = umbraInput(scheme) const adjustment = umbraAdjust(input.settings, scheme) - const output = umbraGenerate(input, adjustment) - return umbraHydrate(input, output) + return umbraHydrate({ + input, + output: umbraGenerate(input, adjustment), + inversed: umbraInput(inversedScheme) + }) } -function umbraInput({ - scheme = defaultScheme, - settings -}: { - scheme?: UmbraScheme - settings?: RootSettings -}): UmbraInput { - const { inversed, ...rest } = settings || {} +function umbraInput(scheme = defaultScheme) { return { - scheme, - inversed: inversed, + ...scheme, settings: { ...defaultSettings, - ...rest + ...scheme.settings } } } @@ -70,28 +62,40 @@ export interface Umbra { inverse: () => Umbra } -export function umbraHydrate(input: UmbraInput, output: UmbraRange[]): Umbra { +function getTarget(target?: string | HTMLElement | null) { + const targetIsString = typeof target === 'string' + const targetIsElement = target instanceof HTMLElement || target === null + return target + ? { + element: targetIsElement ? target : undefined, + selector: targetIsString ? target : undefined + } + : undefined +} + +export function umbraHydrate({ + input, + output, + inversed +}: { + input: UmbraInput + output: UmbraRange[] + inversed?: UmbraInput +}): Umbra { const apply = (target?: string | HTMLElement | null, props?: ApplyProps) => { const { alias, formater } = props || {} - const targetIsString = typeof target === 'string' - const targetIsElement = target instanceof HTMLElement || target === null return format({ output, formater, input }).attach({ alias, - target: target - ? { - element: targetIsElement ? target : undefined, - selector: targetIsString ? target : undefined - } - : undefined + target: getTarget(target) }) } return { input, output, - isDark: () => isDark(input.scheme), + isDark: () => isDark(input), format: (formater?: Formater) => format({ output, formater, input }), - inverse: () => umbra(inverse(input).scheme, input.settings), + inverse: () => umbra(inverse(input, inversed), input), apply } } diff --git a/packages/core/engine/primitives/scheme.ts b/packages/core/engine/primitives/scheme.ts index 8e91262..370a0bd 100644 --- a/packages/core/engine/primitives/scheme.ts +++ b/packages/core/engine/primitives/scheme.ts @@ -1,21 +1,26 @@ import { colord, Colord } from 'colord' -import type { UmbraInput, UmbraScheme, UmbraAdjusted } from '../types' +import type { UmbraInput, UmbraAdjusted } from '../types' import { increaseContrastUntil, getReadability, getReadable, mostReadable } from './color' function inverseValidator(theme: UmbraInput) { - const fgDark = colord(theme.scheme.foreground).isDark() - const bgDark = colord(theme.scheme.background).isDark() + const fgDark = colord(theme.foreground).isDark() + const bgDark = colord(theme.background).isDark() - const background = colord(theme.scheme.background) - const foreground = colord(theme.scheme.foreground) + const background = colord(theme.background) + const foreground = colord(theme.foreground) const readability = theme.settings?.readability - if (fgDark !== bgDark) return {} + if (fgDark !== bgDark) + return { + background: theme.foreground, + foreground: theme.background + } + const fg = getReadable({ foreground, background, readability }) if (fg.isDark() !== bgDark) { return { background: fg.toRgbString(), - foreground: theme.scheme.background + foreground: theme.background } } @@ -39,37 +44,19 @@ function inverseValidator(theme: UmbraInput) { return { background: createInvertedFlippingReadability(), - foreground: theme.scheme.foreground - } -} - -function basicInverse(scheme: UmbraScheme): UmbraScheme { - return { - ...scheme, - background: scheme.foreground, - foreground: scheme.background + foreground: theme.foreground } } -function makeInverse(theme: UmbraInput): UmbraInput { - const inversed = basicInverse(theme.scheme) +export const inverse = (theme: UmbraInput, inversed?: UmbraInput) => { + if (inversed) return inversed return { - inversed: theme, - settings: theme.settings, - scheme: { - ...inversed, - ...inverseValidator(theme) - } + ...theme, + ...inverseValidator(theme) } } -export const inverse = (theme: UmbraInput) => { - const hasInverse = theme.hasOwnProperty('inverse') - if (hasInverse) return theme.inversed as UmbraInput - return makeInverse(theme) -} - -export const isDark = (theme: UmbraScheme) => { +export const isDark = (theme: UmbraInput) => { return colord(theme.background).isDark() } diff --git a/packages/core/engine/primitives/utils.ts b/packages/core/engine/primitives/utils.ts index 6262572..04d015c 100644 --- a/packages/core/engine/primitives/utils.ts +++ b/packages/core/engine/primitives/utils.ts @@ -19,12 +19,10 @@ function randomHex() { export function randomScheme(randomSettings: RandomSettings = { amount: 1 }): UmbraInput { return { - settings: { ...defaultSettings, ...randomSettings }, - scheme: { - background: randomHex(), - foreground: randomHex(), - accents: Array.from({ length: randomSettings.amount }, () => randomHex()) - } + background: randomHex(), + foreground: randomHex(), + accents: Array.from({ length: randomSettings.amount }, () => randomHex()), + settings: { ...defaultSettings, ...randomSettings } } } diff --git a/packages/core/engine/types/index.ts b/packages/core/engine/types/index.ts index 892f466..9e50465 100644 --- a/packages/core/engine/types/index.ts +++ b/packages/core/engine/types/index.ts @@ -27,16 +27,11 @@ export interface Accent { readability?: number } -export interface UmbraScheme { +export interface UmbraInput { background: string foreground: string accents: (Accent | string)[] -} - -export interface UmbraInput { - scheme: UmbraScheme - settings: UmbraSettings - inversed?: UmbraInput + settings?: UmbraSettings } export interface UmbraAdjusted { diff --git a/packages/core/index.ts b/packages/core/index.ts index 71a8268..7ca8e93 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -15,7 +15,6 @@ import { mostReadable, colorMix } from './engine/primitives/color' import type { UmbraOutput, UmbraSettings, - UmbraScheme, UmbraInput, UmbraRange, FormatedRange @@ -45,7 +44,6 @@ export { export type { Umbra, UmbraInput, - UmbraScheme, UmbraSettings, UmbraOutput, UmbraOutputs, diff --git a/packages/core/package.json b/packages/core/package.json index ae0d91c..95d6c0f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@umbrajs/core", - "version": "0.0.4", + "version": "0.0.44", "description": "Umbra is a theme managment library that allows you to create semantic color themes that are easy to dynamically customize, change retroactively and scale progressively", "author": "Samuel M. Bednarz", "repository": { diff --git a/packages/playground/src/App.vue b/packages/playground/src/App.vue index 0065130..9f1af8a 100644 --- a/packages/playground/src/App.vue +++ b/packages/playground/src/App.vue @@ -41,10 +41,6 @@ const brown = { color: '#87533e' } -const something = { - shades: [5, 5, 5, 5, 15, 10, 10, 25, '#e5484d', 25, 25, 25] -} - const accent = { color: '#ff0157' } @@ -53,22 +49,17 @@ const accent3 = { color: '#e5484d' } -const theme = umbra({ +const theme2 = umbra({ background: '#000000', foreground: '#ffffff', - accents: [ - royal, - accent, - radixRed, - radixYellow, - radixBlue, - accent3, - radixRed, - success, - brown, - something - ] -}).apply('body', { + accents: [royal, accent, radixRed, radixYellow, radixBlue, accent3, radixRed, success, brown] +}) + +const theme = umbra({ + foreground: '#ffffff', + background: '#000000', + accents: ['#ff88ff'] +}).apply(undefined, { alias: true }) @@ -76,7 +67,7 @@ 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).inverse().apply('body') t.value = newTheme.input }