more dynamic vars, PROPER ICON COLORS
This commit is contained in:
parent
1229bbd855
commit
a7d771e8c8
|
@ -6,10 +6,8 @@ export default {
|
||||||
{
|
{
|
||||||
component: 'Icon',
|
component: 'Icon',
|
||||||
directives: {
|
directives: {
|
||||||
textColor: '--text',
|
textColor: '$blend(--parent, 0.5, --parent--text)',
|
||||||
// textAuto: 'no-auto', // doesn't work well with mixrgb?
|
textAuto: 'no-auto'
|
||||||
textOpacity: 0.5,
|
|
||||||
textOpacityMode: 'mixrgb'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -141,12 +141,12 @@ export const ruleToSelector = (rule, ignoreOutOfTreeSelector, isParent) => {
|
||||||
return selectors.trim()
|
return selectors.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
const combinationsMatch = (criteria, subject) => {
|
const combinationsMatch = (criteria, subject, strict) => {
|
||||||
if (criteria.component !== subject.component) return false
|
if (criteria.component !== subject.component) return false
|
||||||
|
|
||||||
// All variants inherit from normal
|
// All variants inherit from normal
|
||||||
const subjectVariant = Object.prototype.hasOwnProperty.call(subject, 'variant') ? subject.variant : 'normal'
|
const subjectVariant = Object.prototype.hasOwnProperty.call(subject, 'variant') ? subject.variant : 'normal'
|
||||||
if (subjectVariant !== 'normal') {
|
if (subjectVariant !== 'normal' || strict) {
|
||||||
if (criteria.variant !== subject.variant) return false
|
if (criteria.variant !== subject.variant) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ const combinationsMatch = (criteria, subject) => {
|
||||||
const criteriaStatesSet = new Set(['normal', ...(criteria.state || [])])
|
const criteriaStatesSet = new Set(['normal', ...(criteria.state || [])])
|
||||||
|
|
||||||
// Subject states > 1 essentially means state is "normal" and therefore matches
|
// Subject states > 1 essentially means state is "normal" and therefore matches
|
||||||
if (subjectStatesSet.size > 1) {
|
if (subjectStatesSet.size > 1 || strict) {
|
||||||
const setsAreEqual =
|
const setsAreEqual =
|
||||||
[...criteriaStatesSet].every(state => subjectStatesSet.has(state)) &&
|
[...criteriaStatesSet].every(state => subjectStatesSet.has(state)) &&
|
||||||
[...subjectStatesSet].every(state => criteriaStatesSet.has(state))
|
[...subjectStatesSet].every(state => criteriaStatesSet.has(state))
|
||||||
|
@ -164,13 +164,13 @@ const combinationsMatch = (criteria, subject) => {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const findRules = criteria => subject => {
|
const findRules = (criteria, strict) => subject => {
|
||||||
// If we searching for "general" rules - ignore "specific" ones
|
// If we searching for "general" rules - ignore "specific" ones
|
||||||
if (criteria.parent === null && !!subject.parent) return false
|
if (criteria.parent === null && !!subject.parent) return false
|
||||||
if (!combinationsMatch(criteria, subject)) return false
|
if (!combinationsMatch(criteria, subject, strict)) return false
|
||||||
|
|
||||||
if (criteria.parent !== undefined && criteria.parent !== null) {
|
if (criteria.parent !== undefined && criteria.parent !== null) {
|
||||||
if (!subject.parent) return true
|
if (!subject.parent && !strict) return true
|
||||||
const pathCriteria = unroll(criteria)
|
const pathCriteria = unroll(criteria)
|
||||||
const pathSubject = unroll(subject)
|
const pathSubject = unroll(subject)
|
||||||
if (pathCriteria.length < pathSubject.length) return false
|
if (pathCriteria.length < pathSubject.length) return false
|
||||||
|
@ -182,7 +182,7 @@ const findRules = criteria => subject => {
|
||||||
const criteriaParent = pathCriteria[i]
|
const criteriaParent = pathCriteria[i]
|
||||||
const subjectParent = pathSubject[i]
|
const subjectParent = pathSubject[i]
|
||||||
if (!subjectParent) return true
|
if (!subjectParent) return true
|
||||||
if (!combinationsMatch(criteriaParent, subjectParent)) return false
|
if (!combinationsMatch(criteriaParent, subjectParent, strict)) return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -205,21 +205,24 @@ export const init = (extraRuleset, palette) => {
|
||||||
rules.push(rule)
|
rules.push(rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
const findColor = (color, inheritedBackground, lowerLevelBackground) => {
|
const findColor = (color, dynamicVars) => {
|
||||||
if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color
|
if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color
|
||||||
let targetColor = null
|
let targetColor = null
|
||||||
if (color.startsWith('--')) {
|
if (color.startsWith('--')) {
|
||||||
const [variable, modifier] = color.split(/,/g).map(str => str.trim())
|
const [variable, modifier] = color.split(/,/g).map(str => str.trim())
|
||||||
const variableSlot = variable.substring(2)
|
const variableSlot = variable.substring(2)
|
||||||
if (variableSlot.startsWith('parent')) {
|
if (variableSlot.startsWith('parent')) {
|
||||||
// TODO support more than just background?
|
|
||||||
if (variableSlot === 'parent') {
|
if (variableSlot === 'parent') {
|
||||||
targetColor = lowerLevelBackground
|
targetColor = dynamicVars.lowerLevelBackground
|
||||||
|
} else {
|
||||||
|
const virtualSlot = variableSlot.replace(/^parent/, '')
|
||||||
|
targetColor = dynamicVars.lowerLevelVirtualDirectives[virtualSlot]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// TODO add support for --current prefix
|
||||||
switch (variableSlot) {
|
switch (variableSlot) {
|
||||||
case 'background':
|
case 'background':
|
||||||
targetColor = inheritedBackground
|
targetColor = dynamicVars.inheritedBackground
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
targetColor = palette[variableSlot]
|
targetColor = palette[variableSlot]
|
||||||
|
@ -227,12 +230,13 @@ export const init = (extraRuleset, palette) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifier) {
|
if (modifier) {
|
||||||
const effectiveBackground = lowerLevelBackground ?? targetColor
|
const effectiveBackground = dynamicVars.lowerLevelBackground ?? targetColor
|
||||||
const isLightOnDark = relativeLuminance(convert(effectiveBackground).rgb) < 0.5
|
const isLightOnDark = relativeLuminance(convert(effectiveBackground).rgb) < 0.5
|
||||||
const mod = isLightOnDark ? 1 : -1
|
const mod = isLightOnDark ? 1 : -1
|
||||||
targetColor = brightness(Number.parseFloat(modifier) * mod, targetColor).rgb
|
targetColor = brightness(Number.parseFloat(modifier) * mod, targetColor).rgb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color.startsWith('$')) {
|
if (color.startsWith('$')) {
|
||||||
try {
|
try {
|
||||||
const { funcName, argsString } = /\$(?<funcName>\w+)\((?<argsString>[a-zA-Z0-9-,.'"\s]*)\)/.exec(color).groups
|
const { funcName, argsString } = /\$(?<funcName>\w+)\((?<argsString>[a-zA-Z0-9-,.'"\s]*)\)/.exec(color).groups
|
||||||
|
@ -242,9 +246,10 @@ export const init = (extraRuleset, palette) => {
|
||||||
if (args.length !== 3) {
|
if (args.length !== 3) {
|
||||||
throw new Error(`$blend requires 3 arguments, ${args.length} were provided`)
|
throw new Error(`$blend requires 3 arguments, ${args.length} were provided`)
|
||||||
}
|
}
|
||||||
const backgroundArg = findColor(args[2], inheritedBackground, lowerLevelBackground)
|
const backgroundArg = convert(findColor(args[2], dynamicVars)).rgb
|
||||||
const foregroundArg = findColor(args[0], inheritedBackground, lowerLevelBackground)
|
const foregroundArg = convert(findColor(args[0], dynamicVars)).rgb
|
||||||
const amount = Number(args[1])
|
const amount = Number(args[1])
|
||||||
|
console.log('ASS', backgroundArg, foregroundArg, amount)
|
||||||
targetColor = alphaBlend(backgroundArg, amount, foregroundArg)
|
targetColor = alphaBlend(backgroundArg, amount, foregroundArg)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -260,17 +265,17 @@ export const init = (extraRuleset, palette) => {
|
||||||
|
|
||||||
const cssColorString = (color, alpha) => rgba2css({ ...convert(color).rgb, a: alpha })
|
const cssColorString = (color, alpha) => rgba2css({ ...convert(color).rgb, a: alpha })
|
||||||
|
|
||||||
const getTextColorAlpha = (rule, lowerColor, value) => {
|
const getTextColorAlpha = (directives, intendedTextColor, dynamicVars) => {
|
||||||
const opacity = rule.directives.textOpacity
|
const opacity = directives.textOpacity
|
||||||
const backgroundColor = convert(lowerColor).rgb
|
const backgroundColor = convert(dynamicVars.lowerLevelBackground).rgb
|
||||||
const textColor = convert(findColor(value, backgroundColor)).rgb
|
const textColor = convert(findColor(intendedTextColor, dynamicVars)).rgb
|
||||||
if (opacity === null || opacity === undefined || opacity >= 1) {
|
if (opacity === null || opacity === undefined || opacity >= 1) {
|
||||||
return convert(textColor).hex
|
return convert(textColor).hex
|
||||||
}
|
}
|
||||||
if (opacity === 0) {
|
if (opacity === 0) {
|
||||||
return convert(backgroundColor).hex
|
return convert(backgroundColor).hex
|
||||||
}
|
}
|
||||||
const opacityMode = rule.directives.textOpacityMode
|
const opacityMode = directives.textOpacityMode
|
||||||
switch (opacityMode) {
|
switch (opacityMode) {
|
||||||
case 'fake':
|
case 'fake':
|
||||||
return convert(alphaBlend(textColor, opacity, backgroundColor)).hex
|
return convert(alphaBlend(textColor, opacity, backgroundColor)).hex
|
||||||
|
@ -341,6 +346,16 @@ export const init = (extraRuleset, palette) => {
|
||||||
const soloSelector = ruleToSelector({ component: component.name, ...combination }, true)
|
const soloSelector = ruleToSelector({ component: component.name, ...combination }, true)
|
||||||
const selector = ruleToSelector({ component: component.name, ...combination, parent }, true)
|
const selector = ruleToSelector({ component: component.name, ...combination, parent }, true)
|
||||||
|
|
||||||
|
const lowerLevelSelector = selector.split(/ /g).slice(0, -1).join(' ')
|
||||||
|
const lowerLevelBackground = cache[lowerLevelSelector]?.background
|
||||||
|
const lowerLevelVirtualDirectives = cache[lowerLevelSelector]?.virtualDirectives
|
||||||
|
// console.log('ASS', lowerLevelVirtualDirectives)
|
||||||
|
|
||||||
|
const dynamicVars = {
|
||||||
|
lowerLevelBackground,
|
||||||
|
lowerLevelVirtualDirectives
|
||||||
|
}
|
||||||
|
|
||||||
// Inheriting all of the applicable rules
|
// Inheriting all of the applicable rules
|
||||||
const existingRules = ruleset.filter(findRules({ component: component.name, ...combination, parent }))
|
const existingRules = ruleset.filter(findRules({ component: component.name, ...combination, parent }))
|
||||||
const { directives: computedDirectives } = existingRules.reduce((acc, rule) => merge(acc, rule), {})
|
const { directives: computedDirectives } = existingRules.reduce((acc, rule) => merge(acc, rule), {})
|
||||||
|
@ -389,11 +404,10 @@ export const init = (extraRuleset, palette) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const lowerLevelSelector = selector.split(/ /g).slice(0, -1).join(' ')
|
dynamicVars.inheritedBackground = lowerLevelBackground
|
||||||
const lowerLevelBackground = cache[lowerLevelSelector].background
|
|
||||||
|
|
||||||
// TODO properly provide "parent" text color?
|
// TODO properly provide "parent" text color?
|
||||||
const intendedTextColor = convert(findColor(inheritedTextColor, null, lowerLevelBackground)).rgb
|
const intendedTextColor = convert(findColor(inheritedTextColor, dynamicVars)).rgb
|
||||||
const textColor = newTextRule.directives.textAuto === 'no-auto'
|
const textColor = newTextRule.directives.textAuto === 'no-auto'
|
||||||
? intendedTextColor
|
? intendedTextColor
|
||||||
: getTextColor(
|
: getTextColor(
|
||||||
|
@ -402,23 +416,25 @@ export const init = (extraRuleset, palette) => {
|
||||||
newTextRule.directives.textAuto === 'preserve'
|
newTextRule.directives.textAuto === 'preserve'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Updating previously added rule
|
||||||
|
const earlyLowerLevelRules = rules.filter(findRules(parent, true))
|
||||||
|
const earlyLowerLevelRule = earlyLowerLevelRules.slice(-1)[0]
|
||||||
|
|
||||||
|
const virtualDirectives = earlyLowerLevelRule.virtualDirectives || {}
|
||||||
|
|
||||||
// Storing color data in lower layer to use as custom css properties
|
// Storing color data in lower layer to use as custom css properties
|
||||||
cache[lowerLevelSelector].textDefined = cache[lowerLevelSelector].textDefined || {}
|
virtualDirectives[virtualName] = getTextColorAlpha(newTextRule.directives, textColor, dynamicVars)
|
||||||
cache[lowerLevelSelector].textDefined[selector] = textColor
|
earlyLowerLevelRule.virtualDirectives = virtualDirectives
|
||||||
|
cache[lowerLevelSelector].virtualDirectives = virtualDirectives
|
||||||
|
|
||||||
const virtualDirectives = {}
|
// Debug: lets you see what it think background color should be
|
||||||
virtualDirectives[virtualName] = getTextColorAlpha(newTextRule, lowerLevelBackground, textColor)
|
|
||||||
|
|
||||||
// lastRule.computed = lastRule.computed || {}
|
|
||||||
|
|
||||||
const directives = {
|
const directives = {
|
||||||
textColor,
|
textColor,
|
||||||
|
background: convert(cache[lowerLevelSelector].background).hex,
|
||||||
...inheritedTextOpacity
|
...inheritedTextOpacity
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug: lets you see what it think background color should be
|
|
||||||
// directives.background = convert(cache[lowerLevelSelector].background).hex
|
|
||||||
|
|
||||||
addRule({
|
addRule({
|
||||||
parent,
|
parent,
|
||||||
virtual: true,
|
virtual: true,
|
||||||
|
@ -445,15 +461,16 @@ export const init = (extraRuleset, palette) => {
|
||||||
|
|
||||||
const inheritSelector = ruleToSelector({ ...inheritRule, parent }, true)
|
const inheritSelector = ruleToSelector({ ...inheritRule, parent }, true)
|
||||||
const inheritedBackground = cache[inheritSelector].background
|
const inheritedBackground = cache[inheritSelector].background
|
||||||
const lowerLevelSelector = selector.split(/ /g).slice(0, -1).join(' ')
|
|
||||||
|
|
||||||
// TODO: DEFAULT TEXT COLOR
|
// TODO: DEFAULT TEXT COLOR
|
||||||
const bg = cache[lowerLevelSelector]?.background || convert('#FFFFFF').rgb
|
const lowerLevelComputedBackground = computed[lowerLevelSelector]?.background || convert('#FFFFFF').rgb
|
||||||
|
|
||||||
const rgb = convert(findColor(computedDirectives.background, inheritedBackground, cache[lowerLevelSelector].background)).rgb
|
dynamicVars.inheritedBackground = inheritedBackground
|
||||||
|
|
||||||
|
const rgb = convert(findColor(computedDirectives.background, dynamicVars)).rgb
|
||||||
|
|
||||||
if (!cache[selector].background) {
|
if (!cache[selector].background) {
|
||||||
const blend = computedDirectives.opacity < 1 ? alphaBlend(rgb, computedDirectives.opacity, bg) : rgb
|
const blend = computedDirectives.opacity < 1 ? alphaBlend(rgb, computedDirectives.opacity, lowerLevelComputedBackground) : rgb
|
||||||
cache[selector].background = blend
|
cache[selector].background = blend
|
||||||
computed[selector].background = rgb
|
computed[selector].background = rgb
|
||||||
|
|
||||||
|
@ -479,7 +496,7 @@ export const init = (extraRuleset, palette) => {
|
||||||
return {
|
return {
|
||||||
raw: rules,
|
raw: rules,
|
||||||
css: rules.map(rule => {
|
css: rules.map(rule => {
|
||||||
// if (rule.virtual) return ''
|
if (rule.virtual) return ''
|
||||||
|
|
||||||
let selector = ruleToSelector(rule).replace(/\/\*.*\*\//g, '')
|
let selector = ruleToSelector(rule).replace(/\/\*.*\*\//g, '')
|
||||||
if (!selector) {
|
if (!selector) {
|
||||||
|
|
Loading…
Reference in New Issue