fixed eslint, made mod work properly depending on context including in shadows

This commit is contained in:
Henry Jameson 2020-02-11 00:34:30 +02:00
parent 611da13a4b
commit 38c34b8b51
3 changed files with 49 additions and 34 deletions

View file

@ -1,6 +1,6 @@
import { times } from 'lodash' import { times } from 'lodash'
import { convert } from 'chromatism' import { convert } from 'chromatism'
import { rgb2hex, hex2rgb, rgba2css, getCssColor } from '../color_convert/color_convert.js' import { rgb2hex, hex2rgb, rgba2css, getCssColor, relativeLuminance } from '../color_convert/color_convert.js'
import { getColors, computeDynamicColor } from '../theme_data/theme_data.service.js' import { getColors, computeDynamicColor } from '../theme_data/theme_data.service.js'
// While this is not used anymore right now, I left it in if we want to do custom // While this is not used anymore right now, I left it in if we want to do custom
@ -133,8 +133,7 @@ export const generateColors = (themeData) => {
theme: { theme: {
colors: htmlColors.solid, colors: htmlColors.solid,
opacity opacity
}, }
mod
} }
} }
@ -281,7 +280,18 @@ export const DEFAULT_SHADOWS = {
alpha: 1 alpha: 1
}] }]
} }
export const generateShadows = (input, colors, mod) => { export const generateShadows = (input, colors) => {
// TODO this is a small hack for `mod` to work with shadows
// this is used to get the "context" of shadow, i.e. for `mod` properly depend on background color of element
const hackContextDict = {
button: 'btn',
panel: 'bg',
top: 'topBar',
popup: 'popover',
avatar: 'bg',
panelHeader: 'panel',
input: 'input'
}
const inputShadows = input.shadows && !input.themeEngineVersion const inputShadows = input.shadows && !input.themeEngineVersion
? shadows2to3(input.shadows) ? shadows2to3(input.shadows)
: input.shadows || {} : input.shadows || {}
@ -289,6 +299,10 @@ export const generateShadows = (input, colors, mod) => {
...DEFAULT_SHADOWS, ...DEFAULT_SHADOWS,
...inputShadows ...inputShadows
}).reduce((shadowsAcc, [slotName, shadowDefs]) => { }).reduce((shadowsAcc, [slotName, shadowDefs]) => {
const slotFirstWord = slotName.replace(/[A-Z].*$/, '')
const colorSlotName = hackContextDict[slotFirstWord]
const isLightOnDark = relativeLuminance(convert(colors[colorSlotName]).rgb) < 0.5
const mod = isLightOnDark ? 1 : -1
const newShadow = shadowDefs.reduce((shadowAcc, def) => [ const newShadow = shadowDefs.reduce((shadowAcc, def) => [
...shadowAcc, ...shadowAcc,
{ {

View file

@ -259,13 +259,34 @@ export const computeDynamicColor = (sourceColor, getColor, mod) => {
* value and uses inheritance data to figure out color needed for the slot. * value and uses inheritance data to figure out color needed for the slot.
*/ */
export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({ colors, opacity }, key) => { export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({ colors, opacity }, key) => {
const value = SLOT_INHERITANCE[key]
const isObject = typeof value === 'object'
const isString = typeof value === 'string'
const sourceColor = sourceColors[key] const sourceColor = sourceColors[key]
const variant = value.variant || value.layer || 'bg' const value = expandSlotValue(SLOT_INHERITANCE[key])
const isLightOnDark = relativeLuminance(colors[variant] || sourceColors[variant]) < 0.5 const deps = getDependencies(key, SLOT_INHERITANCE)
const isTextColor = !!value.textColor
const variant = value.variant || value.layer
let backgroundColor = null
if (isTextColor) {
backgroundColor = alphaBlendLayers(
{ ...(colors[deps[0]] || convert(sourceColors[key] || '#FF00FF').rgb) },
getLayers(
getLayerSlot(key) || 'bg',
variant || 'bg',
getOpacitySlot(variant),
colors,
opacity
)
)
} else if (variant && variant !== key) {
backgroundColor = colors[variant] || convert(sourceColors[variant]).rgb
} else {
backgroundColor = colors.bg || convert(sourceColors.bg)
}
const isLightOnDark = relativeLuminance(backgroundColor) < 0.5
const mod = isLightOnDark ? 1 : -1 const mod = isLightOnDark ? 1 : -1
let outputColor = null let outputColor = null
if (sourceColor) { if (sourceColor) {
// Color is defined in source color // Color is defined in source color
@ -280,7 +301,6 @@ export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({
opacity opacity
).slice(0, -1) ).slice(0, -1)
targetColor = { targetColor = {
// TODO: try to use alpha-blended background here
...alphaBlendLayers( ...alphaBlendLayers(
convert('#FF00FF').rgb, convert('#FF00FF').rgb,
layers layers
@ -297,43 +317,24 @@ export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({
targetColor = convert(targetColor).rgb targetColor = convert(targetColor).rgb
} }
outputColor = { ...targetColor } outputColor = { ...targetColor }
} else if (isString && value.startsWith('#')) { } else if (value.default) {
// slot: '#000000' shorthand
outputColor = convert(value).rgb
} else if (isObject && value.default) {
// same as above except in object form // same as above except in object form
outputColor = convert(value.default).rgb outputColor = convert(value.default).rgb
} else { } else {
// calculate color // calculate color
const defaultColorFunc = (mod, dep) => ({ ...dep }) const defaultColorFunc = (mod, dep) => ({ ...dep })
const deps = getDependencies(key, SLOT_INHERITANCE) const colorFunc = value.color || defaultColorFunc
const colorFunc = (isObject && value.color) || defaultColorFunc
if (value.textColor) { if (value.textColor) {
// textColor case
const bg = alphaBlendLayers(
{ ...colors[deps[0]] },
getLayers(
value.layer,
value.variant || value.layer,
getOpacitySlot(value.variant || value.layer),
colors,
opacity
)
)
const isLightOnDark = relativeLuminance(bg) > 0.5
const mod = isLightOnDark ? 1 : -1
if (value.textColor === 'bw') { if (value.textColor === 'bw') {
outputColor = contrastRatio(bg).rgb outputColor = contrastRatio(backgroundColor).rgb
} else { } else {
let color = { ...colors[deps[0]] } let color = { ...colors[deps[0]] }
if (value.color) { if (value.color) {
color = colorFunc(mod, ...deps.map((dep) => ({ ...colors[dep] }))) color = colorFunc(mod, ...deps.map((dep) => ({ ...colors[dep] })))
} }
outputColor = getTextColor( outputColor = getTextColor(
bg, backgroundColor,
{ ...color }, { ...color },
value.textColor === 'preserve' value.textColor === 'preserve'
) )