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));