diff options
-rw-r--r-- | subprojects/frontend/src/App.tsx | 22 | ||||
-rw-r--r-- | subprojects/frontend/src/ToggleDarkModeButton.tsx | 24 | ||||
-rw-r--r-- | subprojects/frontend/src/TopBar.tsx | 29 | ||||
-rw-r--r-- | subprojects/frontend/src/editor/EditorParent.ts | 25 | ||||
-rw-r--r-- | subprojects/frontend/src/theme/ThemeProvider.tsx | 65 |
5 files changed, 118 insertions, 47 deletions
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 @@ | |||
1 | import MenuIcon from '@mui/icons-material/Menu'; | ||
2 | import AppBar from '@mui/material/AppBar'; | ||
3 | import Box from '@mui/material/Box'; | 1 | import Box from '@mui/material/Box'; |
4 | import IconButton from '@mui/material/IconButton'; | ||
5 | import Toolbar from '@mui/material/Toolbar'; | ||
6 | import Typography from '@mui/material/Typography'; | ||
7 | import React from 'react'; | 2 | import React from 'react'; |
8 | 3 | ||
4 | import TopBar from './TopBar'; | ||
9 | import EditorArea from './editor/EditorArea'; | 5 | import EditorArea from './editor/EditorArea'; |
10 | import EditorButtons from './editor/EditorButtons'; | 6 | import EditorButtons from './editor/EditorButtons'; |
11 | import GenerateButton from './editor/GenerateButton'; | 7 | import GenerateButton from './editor/GenerateButton'; |
@@ -13,21 +9,7 @@ import GenerateButton from './editor/GenerateButton'; | |||
13 | export default function App(): JSX.Element { | 9 | export default function App(): JSX.Element { |
14 | return ( | 10 | return ( |
15 | <Box display="flex" flexDirection="column" sx={{ height: '100vh' }}> | 11 | <Box display="flex" flexDirection="column" sx={{ height: '100vh' }}> |
16 | <AppBar position="static" color="inherit"> | 12 | <TopBar /> |
17 | <Toolbar> | ||
18 | <IconButton | ||
19 | edge="start" | ||
20 | sx={{ mr: 2 }} | ||
21 | color="inherit" | ||
22 | aria-label="menu" | ||
23 | > | ||
24 | <MenuIcon /> | ||
25 | </IconButton> | ||
26 | <Typography variant="h6" component="h1" flexGrow={1}> | ||
27 | Refinery | ||
28 | </Typography> | ||
29 | </Toolbar> | ||
30 | </AppBar> | ||
31 | <Box | 13 | <Box |
32 | display="flex" | 14 | display="flex" |
33 | justifyContent="space-between" | 15 | justifyContent="space-between" |
diff --git a/subprojects/frontend/src/ToggleDarkModeButton.tsx b/subprojects/frontend/src/ToggleDarkModeButton.tsx new file mode 100644 index 00000000..1685ec80 --- /dev/null +++ b/subprojects/frontend/src/ToggleDarkModeButton.tsx | |||
@@ -0,0 +1,24 @@ | |||
1 | import DarkModeIcon from '@mui/icons-material/DarkMode'; | ||
2 | import LightModeIcon from '@mui/icons-material/LightMode'; | ||
3 | import IconButton from '@mui/material/IconButton'; | ||
4 | import { observer } from 'mobx-react-lite'; | ||
5 | import React from 'react'; | ||
6 | |||
7 | import { useRootStore } from './RootStore'; | ||
8 | |||
9 | function ToggleDarkModeButton(): JSX.Element { | ||
10 | const { themeStore } = useRootStore(); | ||
11 | const { darkMode } = themeStore; | ||
12 | |||
13 | return ( | ||
14 | <IconButton | ||
15 | color="inherit" | ||
16 | onClick={() => themeStore.toggleDarkMode()} | ||
17 | aria-label={darkMode ? 'Switch to light mode' : 'Switch to dark mode'} | ||
18 | > | ||
19 | {darkMode ? <LightModeIcon /> : <DarkModeIcon />} | ||
20 | </IconButton> | ||
21 | ); | ||
22 | } | ||
23 | |||
24 | 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 @@ | |||
1 | import MenuIcon from '@mui/icons-material/Menu'; | ||
2 | import AppBar from '@mui/material/AppBar'; | ||
3 | import IconButton from '@mui/material/IconButton'; | ||
4 | import Toolbar from '@mui/material/Toolbar'; | ||
5 | import Typography from '@mui/material/Typography'; | ||
6 | import React from 'react'; | ||
7 | |||
8 | import ToggleDarkModeButton from './ToggleDarkModeButton'; | ||
9 | |||
10 | export default function TopBar(): JSX.Element { | ||
11 | return ( | ||
12 | <AppBar position="static" color="primary"> | ||
13 | <Toolbar> | ||
14 | <IconButton | ||
15 | edge="start" | ||
16 | sx={{ mr: 2 }} | ||
17 | color="inherit" | ||
18 | aria-label="menu" | ||
19 | > | ||
20 | <MenuIcon /> | ||
21 | </IconButton> | ||
22 | <Typography variant="h6" component="h1" flexGrow={1}> | ||
23 | Refinery | ||
24 | </Typography> | ||
25 | <ToggleDarkModeButton /> | ||
26 | </Toolbar> | ||
27 | </AppBar> | ||
28 | ); | ||
29 | } | ||
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', { | |||
90 | borderLeft: `2px solid ${theme.palette.primary.main}`, | 90 | borderLeft: `2px solid ${theme.palette.primary.main}`, |
91 | }, | 91 | }, |
92 | '.cm-selectionBackground': { | 92 | '.cm-selectionBackground': { |
93 | background: '#3e4453', | 93 | background: theme.palette.selection.main, |
94 | }, | 94 | }, |
95 | '.cm-focused': { | 95 | '.cm-focused': { |
96 | outline: 'none', | 96 | outline: 'none', |
97 | '.cm-selectionBackground': { | 97 | '.cm-selectionBackground': { |
98 | background: '#3e4453', | 98 | background: theme.palette.selection.main, |
99 | }, | 99 | }, |
100 | }, | 100 | }, |
101 | '.cm-panels-top': { | 101 | '.cm-panels-top': { |
@@ -123,10 +123,11 @@ export default styled('div', { | |||
123 | li: { | 123 | li: { |
124 | borderBottom: `1px solid ${theme.palette.divider}`, | 124 | borderBottom: `1px solid ${theme.palette.divider}`, |
125 | cursor: 'pointer', | 125 | cursor: 'pointer', |
126 | color: theme.palette.text.primary, | ||
126 | }, | 127 | }, |
127 | '[aria-selected]': { | 128 | '[aria-selected]': { |
128 | background: '#3e4453', | 129 | background: theme.palette.selection.main, |
129 | color: theme.palette.text.primary, | 130 | color: theme.palette.selection.contrastText, |
130 | }, | 131 | }, |
131 | '&:focus [aria-selected]': { | 132 | '&:focus [aria-selected]': { |
132 | background: theme.palette.primary.main, | 133 | background: theme.palette.primary.main, |
@@ -161,7 +162,7 @@ export default styled('div', { | |||
161 | color: theme.palette.text.disabled, | 162 | color: theme.palette.text.disabled, |
162 | }, | 163 | }, |
163 | '.tok-number': { | 164 | '.tok-number': { |
164 | color: '#6188a6', | 165 | color: theme.palette.highlight.number, |
165 | }, | 166 | }, |
166 | '.tok-string': { | 167 | '.tok-string': { |
167 | color: theme.palette.secondary.dark, | 168 | color: theme.palette.secondary.dark, |
@@ -173,7 +174,7 @@ export default styled('div', { | |||
173 | color: theme.palette.text.primary, | 174 | color: theme.palette.text.primary, |
174 | }, | 175 | }, |
175 | '.tok-variableName': { | 176 | '.tok-variableName': { |
176 | color: '#c8ae9d', | 177 | color: theme.palette.highlight.parameter, |
177 | }, | 178 | }, |
178 | '.tok-problem-node': { | 179 | '.tok-problem-node': { |
179 | '&, & .tok-variableName': { | 180 | '&, & .tok-variableName': { |
@@ -224,9 +225,9 @@ export default styled('div', { | |||
224 | fontStyle: 'normal', | 225 | fontStyle: 'normal', |
225 | }, | 226 | }, |
226 | '[aria-selected]': { | 227 | '[aria-selected]': { |
227 | background: `${theme.palette.primary.main} !important`, | 228 | background: `${theme.palette.selection.main} !important`, |
228 | '.cm-completionIcon, .cm-completionLabel, .cm-completionDetail': { | 229 | '.cm-completionIcon, .cm-completionLabel, .cm-completionDetail': { |
229 | color: theme.palette.primary.contrastText, | 230 | color: theme.palette.selection.contrastText, |
230 | }, | 231 | }, |
231 | }, | 232 | }, |
232 | }, | 233 | }, |
@@ -237,11 +238,11 @@ export default styled('div', { | |||
237 | textAlign: 'center', | 238 | textAlign: 'center', |
238 | }, | 239 | }, |
239 | ...codeMirrorLintStyle, | 240 | ...codeMirrorLintStyle, |
240 | '.cm-problem-write': { | ||
241 | background: 'rgba(255, 255, 128, 0.3)', | ||
242 | }, | ||
243 | '.cm-problem-read': { | 241 | '.cm-problem-read': { |
244 | background: 'rgba(255, 255, 255, 0.15)', | 242 | background: theme.palette.highlight.occurences.read, |
243 | }, | ||
244 | '.cm-problem-write': { | ||
245 | background: theme.palette.highlight.occurences.write, | ||
245 | }, | 246 | }, |
246 | }; | 247 | }; |
247 | }); | 248 | }); |
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 { | |||
5 | ThemeProvider as MaterialUiThemeProvider, | 5 | ThemeProvider as MaterialUiThemeProvider, |
6 | } from '@mui/material/styles'; | 6 | } from '@mui/material/styles'; |
7 | import { observer } from 'mobx-react-lite'; | 7 | import { observer } from 'mobx-react-lite'; |
8 | import React, { type ReactNode } from 'react'; | 8 | import React, { type CSSProperties, type ReactNode } from 'react'; |
9 | 9 | ||
10 | import { useRootStore } from '../RootStore'; | 10 | import { useRootStore } from '../RootStore'; |
11 | 11 | ||
12 | import EditorTheme from './EditorTheme'; | 12 | import EditorTheme from './EditorTheme'; |
13 | 13 | ||
14 | interface HighlightStyles { | ||
15 | number: CSSProperties['color']; | ||
16 | parameter: CSSProperties['color']; | ||
17 | occurences: { | ||
18 | read: CSSProperties['color']; | ||
19 | write: CSSProperties['color']; | ||
20 | }; | ||
21 | } | ||
22 | |||
23 | declare module '@mui/material/styles' { | ||
24 | interface Palette { | ||
25 | selection: Palette['primary']; | ||
26 | highlight: HighlightStyles; | ||
27 | } | ||
28 | |||
29 | interface PaletteOptions { | ||
30 | selection: PaletteOptions['primary']; | ||
31 | highlight: HighlightStyles; | ||
32 | } | ||
33 | } | ||
34 | |||
14 | function getMUIThemeOptions(currentTheme: EditorTheme): ThemeOptions { | 35 | function getMUIThemeOptions(currentTheme: EditorTheme): ThemeOptions { |
15 | switch (currentTheme) { | 36 | switch (currentTheme) { |
16 | case EditorTheme.Light: | 37 | case EditorTheme.Light: |
17 | return { | 38 | return { |
18 | palette: { | 39 | palette: { |
19 | primary: { | 40 | mode: 'light', |
20 | main: '#56b6c2', | 41 | primary: { main: '#0097a7' }, |
42 | selection: { | ||
43 | main: '#c8e4fb', | ||
44 | contrastText: '#000', | ||
45 | }, | ||
46 | highlight: { | ||
47 | number: '#1976d2', | ||
48 | parameter: '#6a3e3e', | ||
49 | occurences: { | ||
50 | read: '#ceccf7', | ||
51 | write: '#f0d8a8', | ||
52 | }, | ||
21 | }, | 53 | }, |
22 | }, | 54 | }, |
23 | }; | 55 | }; |
24 | case EditorTheme.Dark: | 56 | case EditorTheme.Dark: |
25 | return { | 57 | return { |
26 | palette: { | 58 | palette: { |
27 | primary: { | 59 | mode: 'dark', |
28 | main: '#56b6c2', | 60 | primary: { main: '#56b6c2' }, |
61 | selection: { | ||
62 | main: '#3e4453', | ||
63 | contrastText: '#fff', | ||
64 | }, | ||
65 | highlight: { | ||
66 | number: '#6188a6', | ||
67 | parameter: '#c8ae9d', | ||
68 | occurences: { | ||
69 | read: 'rgba(255, 255, 255, 0.15)', | ||
70 | write: 'rgba(255, 255, 128, 0.4)', | ||
71 | }, | ||
29 | }, | 72 | }, |
30 | }, | 73 | }, |
31 | }; | 74 | }; |
@@ -36,19 +79,11 @@ function getMUIThemeOptions(currentTheme: EditorTheme): ThemeOptions { | |||
36 | 79 | ||
37 | function ThemeProvider({ children }: { children?: ReactNode }) { | 80 | function ThemeProvider({ children }: { children?: ReactNode }) { |
38 | const { | 81 | const { |
39 | themeStore: { currentTheme, darkMode }, | 82 | themeStore: { currentTheme }, |
40 | } = useRootStore(); | 83 | } = useRootStore(); |
41 | 84 | ||
42 | const themeOptions = getMUIThemeOptions(currentTheme); | 85 | const themeOptions = getMUIThemeOptions(currentTheme); |
43 | const theme = responsiveFontSizes( | 86 | const theme = responsiveFontSizes(createTheme(themeOptions)); |
44 | createTheme({ | ||
45 | ...themeOptions, | ||
46 | palette: { | ||
47 | mode: darkMode ? 'dark' : 'light', | ||
48 | ...(themeOptions.palette ?? {}), | ||
49 | }, | ||
50 | }), | ||
51 | ); | ||
52 | 87 | ||
53 | return ( | 88 | return ( |
54 | <MaterialUiThemeProvider theme={theme}>{children}</MaterialUiThemeProvider> | 89 | <MaterialUiThemeProvider theme={theme}>{children}</MaterialUiThemeProvider> |