Add support for calculating intermediary shades.

This commit is contained in:
Matt Swensen 2018-10-27 20:24:37 -06:00
parent af87ef4856
commit 699fad01d0
No known key found for this signature in database
GPG Key ID: 3F9E482BFC526F35
6 changed files with 92 additions and 31 deletions

@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"color": "^3.1.0",
"color-steps": "^1.0.1",
"history": "^4.7.2",
"lodash": "^4.17.11",
"qs": "^6.5.2",

@ -1,33 +1,65 @@
import React, { PureComponent } from 'react';
import { UrlStateConsumer } from './UrlState';
import { get } from 'lodash';
import colorSteps from 'color-steps';
import Color from 'color';
import CalculateIntermediaryShadesState from './CalculateIntermediaryShadesState';
export default class ColorState extends PureComponent {
render() {
return (
<UrlStateConsumer>
{ ({ getValueOrFallback, mergeState, rawState }) => this.props.children({
getColor: (...args) => getValueOrFallback(
[...args].map(colorKey => [
'colors',
getValueOrFallback([['activeColorSet']]),
colorKey
]),
v => Color(v).hex(),
),
setColor: (key, value) => {
mergeState({
colors: {
[getValueOrFallback([['activeColorSet']])]: {
[key]: value,
}
}
});
},
getRawColor: key => get(rawState, ['colors', getValueOrFallback([['activeColorSet']]), key], ''),
}) }
</UrlStateConsumer>
<CalculateIntermediaryShadesState>
{ ({ getValue: shouldCalculateIntermediaryShades }) => (
<UrlStateConsumer>
{ ({ getValueOrFallback, mergeState, rawState }) => this.props.children({
getColor: (...args) => {
const parse = v => Color(v).hex();
const calculatedState = (() => {
if (shouldCalculateIntermediaryShades()) {
try {
const calculatedColors = colorSteps(
parse(get(rawState, ['colors', getValueOrFallback([['activeColorSet']]), 'shade0'], '')),
parse(get(rawState, ['colors', getValueOrFallback([['activeColorSet']]), 'shade7'], '')),
);
return {
colors: {
[getValueOrFallback([['activeColorSet']])]: calculatedColors.reduce(
(shades, color, idx) => ({
...shades,
[`shade${idx+1}`]: color,
}),
{},
)
},
};
} catch {}
}
return {};
})();
return getValueOrFallback(
args.map(colorKey => [
'colors',
getValueOrFallback([['activeColorSet']]),
colorKey
]),
parse,
calculatedState,
);
},
setColor: (key, value) => {
mergeState({
colors: {
[getValueOrFallback([['activeColorSet']])]: {
[key]: value,
}
}
});
},
getRawColor: key => get(rawState, ['colors', getValueOrFallback([['activeColorSet']]), key], ''),
}) }
</UrlStateConsumer>
) }
</CalculateIntermediaryShadesState>
);
}
}

@ -75,9 +75,10 @@ export class UrlStateProvider extends Component {
);
}
getValueOrFallback = (paths, parse) => {
getValueOrFallback = (paths, parse, calculatedState) => {
return getValueOrFallback(
this.state,
calculatedState,
fallbackState,
paths,
parse,

@ -1,6 +1,6 @@
import { has, get } from 'lodash';
export default function getValueOrFallback(state, fallbackState, paths, parse) {
export default function getValueOrFallback(state, calculatedState, fallbackState, paths, parse) {
for (let path of paths) {
if (has(state, path)) {
if (parse) {
@ -15,6 +15,9 @@ export default function getValueOrFallback(state, fallbackState, paths, parse) {
return get(state, path);
}
}
else if (has(calculatedState, path)) {
return get(calculatedState, path);
}
else {
continue;
}

@ -6,6 +6,12 @@ const state = {
baz: 3,
};
const calculatedState =
Object.entries(state).reduce((calc, [key, value]) => ({
...calc,
[`${key}2`]: value * 2,
}), {});
const fallbackState = {
foo: 'one',
bar: 'two',
@ -15,25 +21,31 @@ const fallbackState = {
describe('getValueOrFallback', () => {
test('get existing value', () => {
expect(getValueOrFallback(state, fallbackState, [['foo']])).toBe(1);
expect(getValueOrFallback(state, calculatedState, fallbackState, [['foo']])).toBe(1);
});
test('get calculated value', () => {
expect(getValueOrFallback(state, calculatedState, fallbackState, [['foo2']])).toBe(2);
});
test('get fallback value', () => {
expect(getValueOrFallback(state, fallbackState, [['qux']])).toBe('four');
expect(getValueOrFallback(state, calculatedState, fallbackState, [['qux']])).toBe('four');
});
test('get existing secondary value', () => {
expect(getValueOrFallback(state, fallbackState, [['xxx'], ['bar']])).toBe(2);
expect(getValueOrFallback(state, calculatedState, fallbackState, [['xxx'], ['bar']])).toBe(2);
});
test('get existing calculated value', () => {
expect(getValueOrFallback(state, calculatedState, fallbackState, [['xxx'], ['bar2']])).toBe(4);
});
test('get fallback secondary value', () => {
expect(getValueOrFallback(state, fallbackState, [['xxx'], ['qux']])).toBe('four');
expect(getValueOrFallback(state, calculatedState, fallbackState, [['xxx'], ['qux']])).toBe('four');
});
test('get existing value with parser', () => {
expect(getValueOrFallback(state, fallbackState, [['foo']], v => v.toString())).toBe('1');
expect(getValueOrFallback(state, calculatedState, fallbackState, [['foo']], v => v.toString())).toBe('1');
});
test('get secondary value with parser', () => {
expect(getValueOrFallback(state, fallbackState, [['xxx'], ['baz']], v => v.toString())).toBe('3');
expect(getValueOrFallback(state, calculatedState, fallbackState, [['xxx'], ['baz']], v => v.toString())).toBe('3');
});
test('get valid value with parser', () => {
expect(getValueOrFallback(state, fallbackState, [['foo'], ['bar']], v => {
expect(getValueOrFallback(state, calculatedState, fallbackState, [['foo'], ['bar']], v => {
if (v % 2 === 0) { return v; }
else { throw new Error(); }
})).toBe(2);

@ -2223,6 +2223,13 @@ color-name@^1.0.0:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-steps@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/color-steps/-/color-steps-1.0.1.tgz#d640b9b19aada10f9eaa5d98ac9087cb46167b4e"
integrity sha512-hty37bNHvUcNkkMCfrecjJWd2tQU8XfbZVVGB6VGt2pF3JQH65zaThEZpCBARYfDxUXtcOwiu4IubJAd8b8gXg==
dependencies:
onecolor "^3.0.5"
color-string@^1.5.2:
version "1.5.3"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
@ -6427,6 +6434,11 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
onecolor@^3.0.5:
version "3.1.0"
resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.1.0.tgz#b72522270a49569ac20d244b3cd40fe157fda4d2"
integrity sha512-YZSypViXzu3ul5LMu/m6XjJ9ol8qAy9S2VjHl5E6UlhUH1KGKWabyEJifn0Jjpw23bYDzC2ucKMPGiH5kfwSGQ==
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"