diff --git a/packages/web/src/Screen.js b/packages/web/src/Screen.js index aa5d8ad04..513194bb6 100644 --- a/packages/web/src/Screen.js +++ b/packages/web/src/Screen.js @@ -60,7 +60,7 @@ const TabsPanelContainer = styled.div` height: ${dimensions.tabsPanel.height}px; right: 0; background-color: ${(props) => props.theme.tabs_background2}; - border-top: 1px solid #ccc; + border-top: 1px solid ${(props) => props.theme.border}; overflow-x: auto; diff --git a/packages/web/src/TabsPanel.js b/packages/web/src/TabsPanel.js index c70c3f6e6..da446e23b 100644 --- a/packages/web/src/TabsPanel.js +++ b/packages/web/src/TabsPanel.js @@ -31,8 +31,8 @@ const DbWrapperHandler = styled.div` const DbNameWrapper = styled.div` text-align: center; font-size: 8pt; - border-bottom: 1px solid #ccc; - border-right: 1px solid white; + border-bottom: 1px solid ${(props) => props.theme.border}; + border-right: 1px solid ${(props) => props.theme.border}; cursor: pointer; user-select: none; padding: 1px; @@ -57,7 +57,7 @@ const DbNameWrapper = styled.div` // `; const FileTabItem = styled.div` - border-right: 1px solid white; + border-right: 1px solid ${(props) => props.theme.border}; padding-left: 15px; padding-right: 15px; flex-shrink: 1; diff --git a/packages/web/src/theme/colorUtil.js b/packages/web/src/theme/colorUtil.js index 10a2d9237..6518b1b79 100644 --- a/packages/web/src/theme/colorUtil.js +++ b/packages/web/src/theme/colorUtil.js @@ -1,7 +1,14 @@ // https://css-tricks.com/using-javascript-to-adjust-saturation-and-brightness-of-rgb-colors/ export function hexToRgb(rgb) { - return (rgb = [rgb.substring(1, 3), rgb.substring(3, 5), rgb.substring(5, 7)].map((x) => parseInt(x, 16))); + if (!rgb) throw new Error(`Ivalid RGB color: ${rgb}`); + if (rgb.match(/^#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$/)) { + rgb = `#${rgb[1]}${rgb[1]}${rgb[2]}${rgb[2]}${rgb[3]}${rgb[3]}`; + } + if (!rgb.match(/^#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$/)) { + throw new Error(`Ivalid RGB color: ${rgb}`); + } + return [rgb.substring(1, 3), rgb.substring(3, 5), rgb.substring(5, 7)].map((x) => parseInt(x, 16)); } function componentToHex(c) { @@ -28,6 +35,10 @@ export function getLightnessOfRGB(rgb) { return (highest + lowest) / 2 / 255; } +export function getColorType(rgb) { + return getLightnessOfRGB(rgb) > 0.5 ? 'light' : 'dark'; +} + export function saturateByTenth(rgb) { const rgbIntArray = hexToRgb(rgb); const grayVal = getLightnessOfRGB(rgb) * 255; diff --git a/packages/web/src/theme/dark.js b/packages/web/src/theme/dark.js index 075fb3f61..ffe8122e5 100644 --- a/packages/web/src/theme/dark.js +++ b/packages/web/src/theme/dark.js @@ -1,20 +1,24 @@ -export default { - background: '#000', - iconFontColor: '#eee', - backgroundHover: '#555', - backgroundSelected: '#4CAF50', +import fillTheme from './fillTheme'; - leftPanelBackground: '#ccc', +const theme = { + main_type: 'dark', + main_background: '#fff', - widgetBackground: '#222', - widgetIconFontColor: '#eee', - widgetBackgroundHover: '#555', - widgetBackgroundSelected: '#4CAF50', + selectionAntName: 'blue', - tabsPanelBackground: '#ccc', - tabsPanelHoverFont: '#338', + border: '#555', + + toolbar_background: '#333', + content_background: '#333', + left_background: '#333', + widget_background: '#222', + title_background: '#555', + manager_background: '#000', + tabs_background: '#444', + gridheader_background: '#222', + gridbody_background: '#000', statusBarBackground: '#00c', - toolBarBackground: '#eee', - mainAreaBackground: '#333', }; + +export default fillTheme(theme); diff --git a/packages/web/src/theme/fillTheme.js b/packages/web/src/theme/fillTheme.js index 09072c2f1..2225027d8 100644 --- a/packages/web/src/theme/fillTheme.js +++ b/packages/web/src/theme/fillTheme.js @@ -1,5 +1,5 @@ import _ from 'lodash'; -import { accentColor, darkenByTenth, lightenByTenth } from './colorUtil'; +import { accentColor, darkenByTenth, getColorType, lightenByTenth } from './colorUtil'; import { generate, presetPalettes, presetDarkPalettes, presetPrimaryColors } from '@ant-design/colors'; function fillOne(theme, name, type, add, background, fontName, invFontName, changeLightFunc, fontPalettes) { @@ -40,26 +40,29 @@ function fillOne(theme, name, type, add, background, fontName, invFontName, chan add[`${name}_font_link`] = add[`${name}_font_geekblue`][7]; if (background) { - add[`${name}_background_alt2`] = changeLightFunc(add[`${name}_background1`], 0.05); - add[`${name}_background_alt3`] = add[`${name}_background_geekblue`][0]; + add[`${name}_background_alt2`] = changeLightFunc(add[`${name}_background1`], type == 'light' ? 0.05 : 0.1); + add[`${name}_background_alt3`] = add[`${name}_background_geekblue`][type == 'light' ? 0 : 1]; } } -export default function fillTheme(theme) { - const add = {}; - add.fontWhite1 = theme.fontWhite1 || '#FFFFFF'; - add.fontWhite2 = theme.fontWhite2 || darkenByTenth(add.fontWhite1, 0.3); - add.fontWhite3 = theme.fontWhite3 || darkenByTenth(add.fontWhite2, 0.2); +function fillThemeCore(theme) { + const add = { ...theme }; + add.fontWhite1 = add.fontWhite1 || '#FFFFFF'; + add.fontWhite2 = add.fontWhite2 || darkenByTenth(add.fontWhite1, 0.3); + add.fontWhite3 = add.fontWhite3 || darkenByTenth(add.fontWhite2, 0.2); - add.fontBlack1 = theme.fontBlack1 || '#000000'; - add.fontBlack2 = theme.fontBlack2 || lightenByTenth(add.fontBlack1, 0.3); - add.fontBlack3 = theme.fontBlack3 || lightenByTenth(add.fontBlack2, 0.2); + add.fontBlack1 = add.fontBlack1 || '#000000'; + add.fontBlack2 = add.fontBlack2 || lightenByTenth(add.fontBlack1, 0.3); + add.fontBlack3 = add.fontBlack3 || lightenByTenth(add.fontBlack2, 0.2); for (const key of _.keys(theme)) { - const match = key.match(/(.*)_type/); - if (!match) continue; - const name = match[1]; - const type = theme[key]; + const matchType = key.match(/^(.*)_type$/); + const matchBg = key.match(/^(.*)_background$/); + if (!matchType && !matchBg) continue; + const name = matchType ? matchType[1] : matchBg[1]; + if (matchBg && theme[`${name}_type`]) continue; + + const type = matchType ? theme[key] : getColorType(theme[key]); if (type != 'light' && type != 'dark') continue; const background = theme[`${name}_background`]; @@ -69,22 +72,15 @@ export default function fillTheme(theme) { if (type == 'dark') { fillOne(theme, name, type, add, background, 'fontWhite', 'fontBlack', lightenByTenth, presetDarkPalettes); } - // add[`${name}_fontr`] = accentColor(add[`${name}_font1`], 0, 0.6); - // add[`${name}_fontg`] = accentColor(add[`${name}_font1`], 1, 0.6); - // add[`${name}_fontb`] = accentColor(add[`${name}_font1`], 2, 0.6); - - // if (background) { - // add[`${name}_backgroundr`] = accentColor(add[`${name}_background1`], 0); - // add[`${name}_backgroundg`] = accentColor(add[`${name}_background1`], 1); - // add[`${name}_backgroundb`] = accentColor(add[`${name}_background1`], 2); - // } } - console.log('COLORS', { - ...add, - ...theme, - }); return { ...add, ...theme, }; } + +export default function fillTheme(theme) { + theme = fillThemeCore(theme); + console.log('THEME', theme); + return theme; +} diff --git a/packages/web/src/theme/light.js b/packages/web/src/theme/light.js index b4f9768f0..a2ffaad60 100644 --- a/packages/web/src/theme/light.js +++ b/packages/web/src/theme/light.js @@ -2,78 +2,24 @@ import fillTheme from './fillTheme'; const theme = { main_type: 'light', + main_background: '#fff', + selectionAntName: 'blue', - // main_background: - - // fontWhite1: '#FFFFFF', - // fontWhite2: '#CCCCCC', - // fontWhite3: '#AAAAAA', - - // fontBlack1: '#000000', - // fontBlack2: '#333333', - // fontBlack3: '#666666', border: '#ccc', - toolbar_background: '#eeeeee', - toolbar_type: 'light', - + toolbar_background: '#eee', content_background: '#eee', - content_type: 'light', - // mainAreaBackground: '#eee', - // mainFont: 'black', - // mainFontGray: 'gray', - // mainFontActive: 'blue', - - left_background: '#cccccc', - left_type: 'light', - - // leftPanelBackground: '#ccc', - - widget_type: 'dark', - widget_background: '#222222', - - // widgetBackground: '#222', - // widgetIconFontColor: '#eee', - // widgetBackgroundHover: '#555', - // widgetBackgroundSelected: '#4CAF50', - // widgetTitleBackground: 'gray', - - title_type: 'dark', - title_background: '#888888', - - manager_type: 'light', - manager_background: '#ffffff', - - tabs_type: 'light', - tabs_background: '#eeeeee', - // tabsPanelBackground: '#ddd', - // tabsPanelBackgroundHover: '#ccc', - // tabsPanelBackgroundHoverClick: '#aaa', - // tabsPanelSelectedBackground: '#eee', - // tabsPanelHoverFont: '#338', - - statusBarBackground: '#00c', - + left_background: '#ccc', + widget_background: '#222', + title_background: '#888', + manager_background: '#fff', + tabs_background: '#eee', gridheader_background: '#f6f7f9', gridheader_type: 'light', + gridbody_background: '#fff', - gridbody_type: 'light', - gridbody_background: '#ffffff', - // TRADITIONAL ALTERNATIVES: - // gridbody_background_alt2: '#ebebeb', - // gridbody_background_alt3: '#ebf5ff', - - // gridHeaderBackground: '#f6f7f9', - // gridRowCountLabel: 'lightgoldenrodyellow', - // gridSelectionBackground: 'deepskyblue', - // gridSelectionFont: 'white', - // gridModifiedRowBackground: '#FFFFDB', - // gridModifiedCellBackground: 'bisque', - // gridInsertedRowBackground: '#DBFFDB', - // gridDeletedRowBackground: '#FFDBFF', - // gridFocusedColumnBackground: 'lightgoldenrodyellow', - // gridAutoFillBackground: '#1a73e8', + statusBarBackground: '#00c', }; export default fillTheme(theme); diff --git a/packages/web/src/theme/useTheme.js b/packages/web/src/theme/useTheme.js index 8576a2b42..518eb0991 100644 --- a/packages/web/src/theme/useTheme.js +++ b/packages/web/src/theme/useTheme.js @@ -6,5 +6,5 @@ const themes = { light, dark }; export default function useTheme() { const currentTheme = useCurrentTheme(); - return themes[currentTheme]; + return themes[currentTheme] || light; } diff --git a/packages/web/src/utility/globalState.js b/packages/web/src/utility/globalState.js index 488be23dc..9a5f576f8 100644 --- a/packages/web/src/utility/globalState.js +++ b/packages/web/src/utility/globalState.js @@ -120,6 +120,6 @@ const [CurrentArchiveProvider, useCurrentArchive, useSetCurrentArchive] = create export { CurrentArchiveProvider, useCurrentArchive, useSetCurrentArchive }; -const [CurrentThemeProvider, useCurrentTheme, useSetCurrentTheme] = createGlobalState('light'); +const [CurrentThemeProvider, useCurrentTheme, useSetCurrentTheme] = createStorageState('selectedTheme', 'light'); export { CurrentThemeProvider, useCurrentTheme, useSetCurrentTheme }; diff --git a/packages/web/src/widgets/Splitter.js b/packages/web/src/widgets/Splitter.js index 4dd852aef..fcc08a706 100644 --- a/packages/web/src/widgets/Splitter.js +++ b/packages/web/src/widgets/Splitter.js @@ -3,6 +3,7 @@ import React from 'react'; import styled from 'styled-components'; import useDimensions from '../utility/useDimensions'; import dimensions from '../theme/dimensions'; +import useTheme from '../theme/useTheme'; const SplitterMainBase = styled.div` flex: 1; @@ -27,20 +28,20 @@ const HorizontalMainContainer = styled(SplitterMainBase)` `; export const VerticalSplitHandle = styled.div` - background-color: #ccc; - height: ${dimensions.splitter.thickness}px; +background-color: ${(props) => props.theme.border}; +height: ${dimensions.splitter.thickness}px; cursor: row-resize; &:hover { - background-color: #AAA; + background-color: #aaa; } `; export const HorizontalSplitHandle = styled.div` - background-color: #ccc; + background-color: ${(props) => props.theme.border}; width: ${dimensions.splitter.thickness}px; cursor: col-resize; &:hover { - background-color: #AAA; + background-color: #aaa; } `; @@ -107,6 +108,7 @@ function SplitterCore({ size = undefined, setSize = undefined, }) { + const theme = useTheme(); const childrenArray = _.isArray(children) ? children : [children]; if (childrenArray.length !== 1 && childrenArray.length != 2) { throw new Error('Splitter must have 1 or 2 children'); @@ -130,7 +132,7 @@ function SplitterCore({ return (
{childrenArray[0]} - {isSplitter && } + {isSplitter && } {isSplitter && {childrenArray[1]}}
); diff --git a/packages/web/src/widgets/TabControl.js b/packages/web/src/widgets/TabControl.js index 6e490f85c..2e2b0c748 100644 --- a/packages/web/src/widgets/TabControl.js +++ b/packages/web/src/widgets/TabControl.js @@ -5,7 +5,7 @@ import useTheme from '../theme/useTheme'; import dimensions from '../theme/dimensions'; const TabItem = styled.div` - border-right: 1px solid white; + border-right: 1px solid ${(props) => props.theme.border}; padding-left: 15px; padding-right: 15px; display: flex;