From 66216786a70e415775cf7e4b84cfd7d74b07aad0 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Fri, 12 Aug 2022 21:57:01 +0200 Subject: feat(frontend): light/dark mode switch --- subprojects/frontend/src/App.tsx | 22 +------- subprojects/frontend/src/ToggleDarkModeButton.tsx | 24 +++++++++ subprojects/frontend/src/TopBar.tsx | 29 ++++++++++ subprojects/frontend/src/editor/EditorParent.ts | 25 ++++----- subprojects/frontend/src/theme/ThemeProvider.tsx | 65 +++++++++++++++++------ 5 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 subprojects/frontend/src/ToggleDarkModeButton.tsx create mode 100644 subprojects/frontend/src/TopBar.tsx (limited to 'subprojects/frontend') diff --git a/subprojects/frontend/src/App.tsx b/subprojects/frontend/src/App.tsx index d3ec63eb..12cf9311 100644 --- a/subprojects/frontend/src/App.tsx +++ b/subprojects/frontend/src/App.tsx @@ -1,11 +1,7 @@ -import MenuIcon from '@mui/icons-material/Menu'; -import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; -import IconButton from '@mui/material/IconButton'; -import Toolbar from '@mui/material/Toolbar'; -import Typography from '@mui/material/Typography'; import React from 'react'; +import TopBar from './TopBar'; import EditorArea from './editor/EditorArea'; import EditorButtons from './editor/EditorButtons'; import GenerateButton from './editor/GenerateButton'; @@ -13,21 +9,7 @@ import GenerateButton from './editor/GenerateButton'; export default function App(): JSX.Element { return ( - - - - - - - Refinery - - - + themeStore.toggleDarkMode()} + aria-label={darkMode ? 'Switch to light mode' : 'Switch to dark mode'} + > + {darkMode ? : } + + ); +} + +export default observer(ToggleDarkModeButton); diff --git a/subprojects/frontend/src/TopBar.tsx b/subprojects/frontend/src/TopBar.tsx new file mode 100644 index 00000000..5ac74e7a --- /dev/null +++ b/subprojects/frontend/src/TopBar.tsx @@ -0,0 +1,29 @@ +import MenuIcon from '@mui/icons-material/Menu'; +import AppBar from '@mui/material/AppBar'; +import IconButton from '@mui/material/IconButton'; +import Toolbar from '@mui/material/Toolbar'; +import Typography from '@mui/material/Typography'; +import React from 'react'; + +import ToggleDarkModeButton from './ToggleDarkModeButton'; + +export default function TopBar(): JSX.Element { + return ( + + + + + + + Refinery + + + + + ); +} diff --git a/subprojects/frontend/src/editor/EditorParent.ts b/subprojects/frontend/src/editor/EditorParent.ts index a4cdfa38..805065fc 100644 --- a/subprojects/frontend/src/editor/EditorParent.ts +++ b/subprojects/frontend/src/editor/EditorParent.ts @@ -90,12 +90,12 @@ export default styled('div', { borderLeft: `2px solid ${theme.palette.primary.main}`, }, '.cm-selectionBackground': { - background: '#3e4453', + background: theme.palette.selection.main, }, '.cm-focused': { outline: 'none', '.cm-selectionBackground': { - background: '#3e4453', + background: theme.palette.selection.main, }, }, '.cm-panels-top': { @@ -123,10 +123,11 @@ export default styled('div', { li: { borderBottom: `1px solid ${theme.palette.divider}`, cursor: 'pointer', + color: theme.palette.text.primary, }, '[aria-selected]': { - background: '#3e4453', - color: theme.palette.text.primary, + background: theme.palette.selection.main, + color: theme.palette.selection.contrastText, }, '&:focus [aria-selected]': { background: theme.palette.primary.main, @@ -161,7 +162,7 @@ export default styled('div', { color: theme.palette.text.disabled, }, '.tok-number': { - color: '#6188a6', + color: theme.palette.highlight.number, }, '.tok-string': { color: theme.palette.secondary.dark, @@ -173,7 +174,7 @@ export default styled('div', { color: theme.palette.text.primary, }, '.tok-variableName': { - color: '#c8ae9d', + color: theme.palette.highlight.parameter, }, '.tok-problem-node': { '&, & .tok-variableName': { @@ -224,9 +225,9 @@ export default styled('div', { fontStyle: 'normal', }, '[aria-selected]': { - background: `${theme.palette.primary.main} !important`, + background: `${theme.palette.selection.main} !important`, '.cm-completionIcon, .cm-completionLabel, .cm-completionDetail': { - color: theme.palette.primary.contrastText, + color: theme.palette.selection.contrastText, }, }, }, @@ -237,11 +238,11 @@ export default styled('div', { textAlign: 'center', }, ...codeMirrorLintStyle, - '.cm-problem-write': { - background: 'rgba(255, 255, 128, 0.3)', - }, '.cm-problem-read': { - background: 'rgba(255, 255, 255, 0.15)', + background: theme.palette.highlight.occurences.read, + }, + '.cm-problem-write': { + background: theme.palette.highlight.occurences.write, }, }; }); diff --git a/subprojects/frontend/src/theme/ThemeProvider.tsx b/subprojects/frontend/src/theme/ThemeProvider.tsx index cf18e21c..1b8e49f0 100644 --- a/subprojects/frontend/src/theme/ThemeProvider.tsx +++ b/subprojects/frontend/src/theme/ThemeProvider.tsx @@ -5,27 +5,70 @@ import { ThemeProvider as MaterialUiThemeProvider, } from '@mui/material/styles'; import { observer } from 'mobx-react-lite'; -import React, { type ReactNode } from 'react'; +import React, { type CSSProperties, type ReactNode } from 'react'; import { useRootStore } from '../RootStore'; import EditorTheme from './EditorTheme'; +interface HighlightStyles { + number: CSSProperties['color']; + parameter: CSSProperties['color']; + occurences: { + read: CSSProperties['color']; + write: CSSProperties['color']; + }; +} + +declare module '@mui/material/styles' { + interface Palette { + selection: Palette['primary']; + highlight: HighlightStyles; + } + + interface PaletteOptions { + selection: PaletteOptions['primary']; + highlight: HighlightStyles; + } +} + function getMUIThemeOptions(currentTheme: EditorTheme): ThemeOptions { switch (currentTheme) { case EditorTheme.Light: return { palette: { - primary: { - main: '#56b6c2', + mode: 'light', + primary: { main: '#0097a7' }, + selection: { + main: '#c8e4fb', + contrastText: '#000', + }, + highlight: { + number: '#1976d2', + parameter: '#6a3e3e', + occurences: { + read: '#ceccf7', + write: '#f0d8a8', + }, }, }, }; case EditorTheme.Dark: return { palette: { - primary: { - main: '#56b6c2', + mode: 'dark', + primary: { main: '#56b6c2' }, + selection: { + main: '#3e4453', + contrastText: '#fff', + }, + highlight: { + number: '#6188a6', + parameter: '#c8ae9d', + occurences: { + read: 'rgba(255, 255, 255, 0.15)', + write: 'rgba(255, 255, 128, 0.4)', + }, }, }, }; @@ -36,19 +79,11 @@ function getMUIThemeOptions(currentTheme: EditorTheme): ThemeOptions { function ThemeProvider({ children }: { children?: ReactNode }) { const { - themeStore: { currentTheme, darkMode }, + themeStore: { currentTheme }, } = useRootStore(); const themeOptions = getMUIThemeOptions(currentTheme); - const theme = responsiveFontSizes( - createTheme({ - ...themeOptions, - palette: { - mode: darkMode ? 'dark' : 'light', - ...(themeOptions.palette ?? {}), - }, - }), - ); + const theme = responsiveFontSizes(createTheme(themeOptions)); return ( {children} -- cgit v1.2.3-70-g09d2