From 0938612678ba83c73764dc336f282d6debe45728 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Mar 2022 17:19:54 -0600 Subject: [PATCH] Use colors from soapbox.json at runtime --- app/soapbox/actions/soapbox.js | 1 + app/soapbox/containers/soapbox.js | 6 ++++- app/soapbox/utils/theme.js | 26 ++++++++++++++++++ app/styles/themes.scss | 44 ------------------------------- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index 91e1a26f2..ac8749221 100644 --- a/app/soapbox/actions/soapbox.js +++ b/app/soapbox/actions/soapbox.js @@ -41,6 +41,7 @@ export const makeDefaultConfig = features => { banner: '', brandColor: '', // Empty accentColor: '', + colors: ImmutableMap(), customCss: ImmutableList(), promoPanel: ImmutableMap({ items: ImmutableList(), diff --git a/app/soapbox/containers/soapbox.js b/app/soapbox/containers/soapbox.js index a86573be7..c702ea12c 100644 --- a/app/soapbox/containers/soapbox.js +++ b/app/soapbox/containers/soapbox.js @@ -25,6 +25,7 @@ import { createGlobals } from 'soapbox/globals'; import messages from 'soapbox/locales/messages'; import { makeGetAccount } from 'soapbox/selectors'; import SoapboxPropTypes from 'soapbox/utils/soapbox_prop_types'; +import { colorsToCss } from 'soapbox/utils/theme'; import { INTRODUCTION_VERSION } from '../actions/onboarding'; import { preload } from '../actions/preload'; @@ -83,6 +84,7 @@ const mapStateToProps = (state) => { dyslexicFont: settings.get('dyslexicFont'), demetricator: settings.get('demetricator'), locale: validLocale(locale) ? locale : 'en', + themeCss: colorsToCss(soapboxConfig.get('colors').toJS()), brandColor: soapboxConfig.get('brandColor'), themeMode: settings.get('themeMode'), singleUserMode, @@ -103,6 +105,7 @@ class SoapboxMount extends React.PureComponent { dyslexicFont: PropTypes.bool, demetricator: PropTypes.bool, locale: PropTypes.string.isRequired, + themeCss: PropTypes.string, themeMode: PropTypes.string, brandColor: PropTypes.string, dispatch: PropTypes.func, @@ -139,7 +142,7 @@ class SoapboxMount extends React.PureComponent { } render() { - const { me, account, instanceLoaded, locale, singleUserMode } = this.props; + const { me, account, instanceLoaded, themeCss, locale, singleUserMode } = this.props; if (me === null) return null; if (me && !account) return null; if (!instanceLoaded) return null; @@ -169,6 +172,7 @@ class SoapboxMount extends React.PureComponent { {/* */} + {themeCss && } diff --git a/app/soapbox/utils/theme.js b/app/soapbox/utils/theme.js index 1b3c85dfe..0f3d63b4f 100644 --- a/app/soapbox/utils/theme.js +++ b/app/soapbox/utils/theme.js @@ -65,6 +65,32 @@ const rgbToHsl = value => { }; }; +const parseShades = (obj, color, shades) => { + if (typeof shades === 'string') { + const { r, g, b } = hexToRgb(shades); + return obj[`--color-${color}`] = `${r} ${g} ${b}`; + } + + return Object.keys(shades).forEach(shade => { + const { r, g, b } = hexToRgb(shades[shade]); + obj[`--color-${color}-${shade}`] = `${r} ${g} ${b}`; + }); +}; + +const parseColors = colors => { + return Object.keys(colors).reduce((obj, color) => { + parseShades(obj, color, colors[color]); + return obj; + }, {}); +}; + +export const colorsToCss = colors => { + const parsed = parseColors(colors); + return Object.keys(parsed).reduce((css, variable) => { + return css + `${variable}:${parsed[variable]};`; + }, ''); +}; + export const brandColorToThemeData = brandColor => { const { h, s, l } = rgbToHsl(hexToRgb(brandColor)); return ImmutableMap({ diff --git a/app/styles/themes.scss b/app/styles/themes.scss index 112c2abc1..97a9b5f95 100644 --- a/app/styles/themes.scss +++ b/app/styles/themes.scss @@ -26,50 +26,6 @@ Examples: body, .site-preview { - // Tailwind color variables - --color-gray-50: 249 250 251; - --color-gray-100: 243 244 246; - --color-gray-200: 229 231 235; - --color-gray-300: 209 213 219; - --color-gray-400: 156 163 175; - --color-gray-500: 107 114 128; - --color-gray-600: 75 85 99; - --color-gray-700: 55 65 81; - --color-gray-800: 31 41 55; - --color-gray-900: 17 24 39; - --color-primary-50: 238 242 255; - --color-primary-100: 224 231 255; - --color-primary-200: 199 210 254; - --color-primary-300: 165 180 252; - --color-primary-400: 129 140 248; - --color-primary-500: 99 102 241; - --color-primary-600: 84 72 238; - --color-primary-700: 67 56 202; - --color-primary-800: 55 48 163; - --color-primary-900: 49 46 129; - --color-success-50: 240 253 244; - --color-success-100: 220 252 231; - --color-success-200: 187 247 208; - --color-success-300: 134 239 172; - --color-success-400: 74 222 128; - --color-success-500: 34 197 94; - --color-success-600: 22 163 74; - --color-success-700: 21 128 61; - --color-success-800: 22 101 52; - --color-success-900: 20 83 45; - --color-danger-50: 254 242 242; - --color-danger-100: 254 226 226; - --color-danger-200: 254 202 202; - --color-danger-300: 252 165 165; - --color-danger-400: 248 113 113; - --color-danger-500: 239 68 68; - --color-danger-600: 220 38 38; - --color-danger-700: 185 28 28; - --color-danger-800: 153 27 27; - --color-danger-900: 127 29 29; - --color-accent-300: 255 95 135; - --color-accent-500: 255 71 117; - // Primary variables --brand-color: hsl(var(--brand-color_hsl)); --accent-color: hsl(var(--accent-color_hsl));