import { THEME_SET, THEME_GENERATE, } from '../actions/theme'; import { Map as ImmutableMap } from 'immutable'; import { brightness, hue, convert } from 'chromatism'; const initialState = ImmutableMap(); const modes = ImmutableMap({ light: ImmutableMap({ 'primary-text-color': '#000000', 'primary-text-color-faint': 'rgba(0, 0, 0, 0.6)', 'background-color': '#f2f2f2', 'foreground-color': '#ffffff', }), dark: ImmutableMap({ 'primary-text-color': '#ffffff', 'primary-text-color-faint': 'rgba(255, 255, 255, 0.6)', 'background-color': '#333333', 'foreground-color': '#222222', }), }); const cssrgba = (color, a) => { const { r, g, b } = convert(color).rgb; return `rgba(${[r, g, b, a].join(',')})`; }; const makeContrast = (percent, color, mode) => { percent = mode === 'light' ? -percent : percent; return brightness(percent, color); }; export const generateTheme = (brandColor, mode) => { return modes.get(mode).merge(ImmutableMap({ 'brand-color': brandColor, 'accent-color': brightness(10, hue(-3, brandColor).hex).hex, 'brand-color-faint': cssrgba(brandColor, 0.1), 'brand-color-med': cssrgba(brandColor, 0.2), 'highlight-text-color': makeContrast(5, brandColor, mode).hex, 'brand-color-hicontrast': makeContrast(15, brandColor, mode).hex, })); }; export const setTheme = themeData => { const { 'brand-color': brandColor } = themeData.toObject(); return ImmutableMap(generateTheme(brandColor, 'light')).merge(themeData); }; export default function theme(state = initialState, action) { switch(action.type) { case THEME_GENERATE: return generateTheme(action.brandColor, action.mode); case THEME_SET: return setTheme(ImmutableMap(action.brandColor)); default: return state; } };