From 8c17d730eff3bb59313a2f9f7aa469fe6fff95b2 Mon Sep 17 00:00:00 2001 From: Sascha Date: Tue, 23 Feb 2021 16:03:07 +0100 Subject: Add button to toggle between light- and dark-mode --- webui/src/components/Themer.tsx | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 webui/src/components/Themer.tsx (limited to 'webui/src/components/Themer.tsx') diff --git a/webui/src/components/Themer.tsx b/webui/src/components/Themer.tsx new file mode 100644 index 00000000..13d098da --- /dev/null +++ b/webui/src/components/Themer.tsx @@ -0,0 +1,64 @@ +import React, { createContext, useCallback, useContext, useState } from 'react'; + +import { ThemeProvider } from '@material-ui/core'; +import IconButton from '@material-ui/core/IconButton/IconButton'; +import Tooltip from '@material-ui/core/Tooltip/Tooltip'; +import { createMuiTheme, ThemeOptions } from '@material-ui/core/styles'; +import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons'; + +const defaultTheme: ThemeOptions = { + palette: { + type: 'light', + primary: { + main: '#263238', + }, + }, +}; + +const ThemeContext = createContext({ + toggleMode: () => {}, + mode: '', +}); + +const LightSwitch = () => { + const { mode, toggleMode } = useContext(ThemeContext); + + return ( + + + {mode === 'light' ? ( + + ) : ( + + )} + + + ); +}; + +type Props = { children: React.ReactNode }; +const Themer = ({ children }: Props) => { + const [theme, setTheme] = useState(defaultTheme); + + const toggleMode = useCallback(() => { + const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark'; + const adjustedTheme: ThemeOptions = { + ...theme, + palette: { + ...theme.palette, + type: newMode, + }, + }; + setTheme(adjustedTheme); + }, [theme, setTheme]); + + const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark'; + + return ( + + {children} + + ); +}; + +export { Themer as default, LightSwitch }; -- cgit From c834c03b809f226801423d726c62608297cd6fc4 Mon Sep 17 00:00:00 2001 From: Sascha Date: Thu, 25 Feb 2021 14:41:17 +0100 Subject: Use brower preference and persist theme mode --- webui/src/components/Themer.tsx | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'webui/src/components/Themer.tsx') diff --git a/webui/src/components/Themer.tsx b/webui/src/components/Themer.tsx index 13d098da..78e20564 100644 --- a/webui/src/components/Themer.tsx +++ b/webui/src/components/Themer.tsx @@ -1,12 +1,12 @@ -import React, { createContext, useCallback, useContext, useState } from 'react'; +import React, { createContext, useContext, useState } from 'react'; -import { ThemeProvider } from '@material-ui/core'; +import { PaletteType, ThemeProvider, useMediaQuery } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton/IconButton'; import Tooltip from '@material-ui/core/Tooltip/Tooltip'; -import { createMuiTheme, ThemeOptions } from '@material-ui/core/styles'; +import { createMuiTheme } from '@material-ui/core/styles'; import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons'; -const defaultTheme: ThemeOptions = { +const defaultTheme = { palette: { type: 'light', primary: { @@ -39,24 +39,37 @@ const LightSwitch = () => { type Props = { children: React.ReactNode }; const Themer = ({ children }: Props) => { const [theme, setTheme] = useState(defaultTheme); + const preferseDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); + const browserMode = preferseDarkMode ? 'dark' : 'light'; + const preferedMode = localStorage.getItem('themeMode'); + const curMode = preferedMode != null ? preferedMode : browserMode; - const toggleMode = useCallback(() => { - const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark'; - const adjustedTheme: ThemeOptions = { + const adjustedTheme = { + ...theme, + palette: { + ...theme.palette, + type: (curMode === 'dark' ? 'dark' : 'light') as PaletteType, + }, + }; + + const toggleMode = () => { + const preferedMode = curMode === 'dark' ? 'light' : 'dark'; + localStorage.setItem('themeMode', preferedMode); + const adjustedTheme = { ...theme, palette: { ...theme.palette, - type: newMode, + type: preferedMode as PaletteType, }, }; setTheme(adjustedTheme); - }, [theme, setTheme]); - - const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark'; + }; return ( - - {children} + + + {children} + ); }; -- cgit From 9cac03652c410f943abe1e3a6b55dce0d79e48d6 Mon Sep 17 00:00:00 2001 From: Sascha Date: Mon, 1 Mar 2021 17:47:57 +0100 Subject: Inject theme instead of defining it in Themer.tsx --- webui/src/components/Themer.tsx | 57 ++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 38 deletions(-) (limited to 'webui/src/components/Themer.tsx') diff --git a/webui/src/components/Themer.tsx b/webui/src/components/Themer.tsx index 78e20564..d831fca9 100644 --- a/webui/src/components/Themer.tsx +++ b/webui/src/components/Themer.tsx @@ -1,20 +1,11 @@ import React, { createContext, useContext, useState } from 'react'; -import { PaletteType, ThemeProvider, useMediaQuery } from '@material-ui/core'; +import { ThemeProvider, useMediaQuery } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton/IconButton'; import Tooltip from '@material-ui/core/Tooltip/Tooltip'; -import { createMuiTheme } from '@material-ui/core/styles'; +import { Theme } from '@material-ui/core/styles'; import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons'; -const defaultTheme = { - palette: { - type: 'light', - primary: { - main: '#263238', - }, - }, -}; - const ThemeContext = createContext({ toggleMode: () => {}, mode: '', @@ -22,10 +13,11 @@ const ThemeContext = createContext({ const LightSwitch = () => { const { mode, toggleMode } = useContext(ThemeContext); + const description = `Switch to ${mode === 'light' ? 'dark' : 'light'} theme`; return ( - - + + {mode === 'light' ? ( ) : ( @@ -36,40 +28,29 @@ const LightSwitch = () => { ); }; -type Props = { children: React.ReactNode }; -const Themer = ({ children }: Props) => { - const [theme, setTheme] = useState(defaultTheme); +type Props = { + children: React.ReactNode; + lightTheme: Theme; + darkTheme: Theme; +}; +const Themer = ({ children, lightTheme, darkTheme }: Props) => { const preferseDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); const browserMode = preferseDarkMode ? 'dark' : 'light'; - const preferedMode = localStorage.getItem('themeMode'); - const curMode = preferedMode != null ? preferedMode : browserMode; - - const adjustedTheme = { - ...theme, - palette: { - ...theme.palette, - type: (curMode === 'dark' ? 'dark' : 'light') as PaletteType, - }, - }; + const savedMode = localStorage.getItem('themeMode'); + const preferedMode = savedMode != null ? savedMode : browserMode; + const [curMode, setMode] = useState(preferedMode); const toggleMode = () => { - const preferedMode = curMode === 'dark' ? 'light' : 'dark'; + const preferedMode = curMode === 'light' ? 'dark' : 'light'; localStorage.setItem('themeMode', preferedMode); - const adjustedTheme = { - ...theme, - palette: { - ...theme.palette, - type: preferedMode as PaletteType, - }, - }; - setTheme(adjustedTheme); + setMode(preferedMode); }; + const preferedTheme = preferedMode === 'dark' ? darkTheme : lightTheme; + return ( - - {children} - + {children} ); }; -- cgit From 680ede3df68b868f38b0207f4c0829e93181f161 Mon Sep 17 00:00:00 2001 From: Sascha Date: Mon, 1 Mar 2021 18:55:01 +0100 Subject: Fix (hopefully) eslint error on node 14.x pipeline --- webui/src/components/Themer.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'webui/src/components/Themer.tsx') diff --git a/webui/src/components/Themer.tsx b/webui/src/components/Themer.tsx index d831fca9..4adef24a 100644 --- a/webui/src/components/Themer.tsx +++ b/webui/src/components/Themer.tsx @@ -13,7 +13,8 @@ const ThemeContext = createContext({ const LightSwitch = () => { const { mode, toggleMode } = useContext(ThemeContext); - const description = `Switch to ${mode === 'light' ? 'dark' : 'light'} theme`; + const nextMode = mode === 'light' ? 'dark' : 'light'; + const description = `Switch to ${nextMode} theme`; return ( -- cgit From 188ee0567cf374cb0bb3deb0bb3dcb78ffccc140 Mon Sep 17 00:00:00 2001 From: Sascha Date: Sat, 6 Mar 2021 17:04:20 +0100 Subject: Ignore system prefered colorscheme mode Currently this introduces to much state problems. --- webui/src/components/Themer.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'webui/src/components/Themer.tsx') diff --git a/webui/src/components/Themer.tsx b/webui/src/components/Themer.tsx index 4adef24a..badd543b 100644 --- a/webui/src/components/Themer.tsx +++ b/webui/src/components/Themer.tsx @@ -1,6 +1,6 @@ import React, { createContext, useContext, useState } from 'react'; -import { ThemeProvider, useMediaQuery } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton/IconButton'; import Tooltip from '@material-ui/core/Tooltip/Tooltip'; import { Theme } from '@material-ui/core/styles'; @@ -35,22 +35,20 @@ type Props = { darkTheme: Theme; }; const Themer = ({ children, lightTheme, darkTheme }: Props) => { - const preferseDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); - const browserMode = preferseDarkMode ? 'dark' : 'light'; const savedMode = localStorage.getItem('themeMode'); - const preferedMode = savedMode != null ? savedMode : browserMode; - const [curMode, setMode] = useState(preferedMode); + const preferedMode = savedMode != null ? savedMode : 'light'; + const [mode, setMode] = useState(preferedMode); const toggleMode = () => { - const preferedMode = curMode === 'light' ? 'dark' : 'light'; + const preferedMode = mode === 'light' ? 'dark' : 'light'; localStorage.setItem('themeMode', preferedMode); setMode(preferedMode); }; - const preferedTheme = preferedMode === 'dark' ? darkTheme : lightTheme; + const preferedTheme = mode === 'dark' ? darkTheme : lightTheme; return ( - + {children} ); -- cgit From c2c5c40e752663e238bdd29c54d3a5634ba9615c Mon Sep 17 00:00:00 2001 From: Sascha Date: Sat, 6 Mar 2021 17:25:23 +0100 Subject: Change color of ModeIcon Will use contrastText which should always make the icon visible, but use fade to dimme the contrast down. --- webui/src/components/Themer.tsx | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'webui/src/components/Themer.tsx') diff --git a/webui/src/components/Themer.tsx b/webui/src/components/Themer.tsx index badd543b..b4877974 100644 --- a/webui/src/components/Themer.tsx +++ b/webui/src/components/Themer.tsx @@ -1,29 +1,37 @@ import React, { createContext, useContext, useState } from 'react'; -import { ThemeProvider } from '@material-ui/core'; +import { fade, ThemeProvider } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton/IconButton'; import Tooltip from '@material-ui/core/Tooltip/Tooltip'; import { Theme } from '@material-ui/core/styles'; import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons'; +import { makeStyles } from '@material-ui/styles'; const ThemeContext = createContext({ toggleMode: () => {}, mode: '', }); +const useStyles = makeStyles((theme: Theme) => ({ + iconButton: { + color: fade(theme.palette.primary.contrastText, 0.5), + }, +})); + const LightSwitch = () => { const { mode, toggleMode } = useContext(ThemeContext); const nextMode = mode === 'light' ? 'dark' : 'light'; const description = `Switch to ${nextMode} theme`; + const classes = useStyles(); return ( - - {mode === 'light' ? ( - - ) : ( - - )} + + {mode === 'light' ? : } ); -- cgit