aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-03 03:34:31 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-09 00:07:39 +0100
commitd02125201f39a0620aedab9f350cff84fca22bd3 (patch)
tree1b2c829323572782ebc792837a4307d72f2e46bf
parentrefactor(frontend): scrollbar improvements (diff)
downloadrefinery-d02125201f39a0620aedab9f350cff84fca22bd3.tar.gz
refinery-d02125201f39a0620aedab9f350cff84fca22bd3.tar.zst
refinery-d02125201f39a0620aedab9f350cff84fca22bd3.zip
refactor(frontend): theme improvements
-rw-r--r--subprojects/frontend/src/TopBar.tsx18
-rw-r--r--subprojects/frontend/src/editor/AnimatedButton.tsx14
-rw-r--r--subprojects/frontend/src/editor/EditorPane.tsx6
-rw-r--r--subprojects/frontend/src/editor/EditorTheme.ts10
-rw-r--r--subprojects/frontend/src/editor/GenerateButton.tsx13
-rw-r--r--subprojects/frontend/src/theme/ThemeProvider.tsx441
6 files changed, 275 insertions, 227 deletions
diff --git a/subprojects/frontend/src/TopBar.tsx b/subprojects/frontend/src/TopBar.tsx
index 5f72dc96..81e11ac8 100644
--- a/subprojects/frontend/src/TopBar.tsx
+++ b/subprojects/frontend/src/TopBar.tsx
@@ -58,7 +58,7 @@ export default observer(function TopBar(): JSX.Element {
58 const { editorStore } = useRootStore(); 58 const { editorStore } = useRootStore();
59 const overlayVisible = useWindowControlsOverlayVisible(); 59 const overlayVisible = useWindowControlsOverlayVisible();
60 const { breakpoints } = useTheme(); 60 const { breakpoints } = useTheme();
61 const showGenerateButton = useMediaQuery(breakpoints.down('sm')); 61 const small = useMediaQuery(breakpoints.down('sm'));
62 62
63 return ( 63 return (
64 <AppBar 64 <AppBar
@@ -90,17 +90,13 @@ export default observer(function TopBar(): JSX.Element {
90 }} 90 }}
91 > 91 >
92 <Typography variant="h6" component="h1" flexGrow={1}> 92 <Typography variant="h6" component="h1" flexGrow={1}>
93 Refinery 93 Refinery {import.meta.env.DEV && <DevModeBadge>Dev</DevModeBadge>}
94 {import.meta.env.DEV && (
95 <>
96 {' '}
97 <DevModeBadge>Dev</DevModeBadge>
98 </>
99 )}
100 </Typography> 94 </Typography>
101 {showGenerateButton && ( 95 <GenerateButton
102 <GenerateButton editorStore={editorStore} hideWarnings /> 96 editorStore={editorStore}
103 )} 97 hideWarnings={small}
98 sx={{ marginRight: 1 }}
99 />
104 <ToggleDarkModeButton /> 100 <ToggleDarkModeButton />
105 </Toolbar> 101 </Toolbar>
106 </AppBar> 102 </AppBar>
diff --git a/subprojects/frontend/src/editor/AnimatedButton.tsx b/subprojects/frontend/src/editor/AnimatedButton.tsx
index 7f6c61f0..f75d4617 100644
--- a/subprojects/frontend/src/editor/AnimatedButton.tsx
+++ b/subprojects/frontend/src/editor/AnimatedButton.tsx
@@ -1,6 +1,6 @@
1import Box from '@mui/material/Box'; 1import Box from '@mui/material/Box';
2import Button from '@mui/material/Button'; 2import Button from '@mui/material/Button';
3import { styled } from '@mui/material/styles'; 3import { styled, type SxProps, type Theme } from '@mui/material/styles';
4import { type ReactNode, useLayoutEffect, useState } from 'react'; 4import { type ReactNode, useLayoutEffect, useState } from 'react';
5 5
6const AnimatedButtonBase = styled(Button, { 6const AnimatedButtonBase = styled(Button, {
@@ -9,7 +9,9 @@ const AnimatedButtonBase = styled(Button, {
9 // Transition copied from `@mui/material/Button`. 9 // Transition copied from `@mui/material/Button`.
10 const colorTransition = theme.transitions.create( 10 const colorTransition = theme.transitions.create(
11 ['background-color', 'box-shadow', 'border-color', 'color'], 11 ['background-color', 'box-shadow', 'border-color', 'color'],
12 { duration: theme.transitions.duration.short }, 12 {
13 duration: theme.transitions.duration.short,
14 },
13 ); 15 );
14 return { 16 return {
15 width, 17 width,
@@ -19,7 +21,6 @@ const AnimatedButtonBase = styled(Button, {
19 ${colorTransition}, 21 ${colorTransition},
20 ${theme.transitions.create(['width'], { 22 ${theme.transitions.create(['width'], {
21 duration: theme.transitions.duration.short, 23 duration: theme.transitions.duration.short,
22 easing: theme.transitions.easing.easeOut,
23 })} 24 })}
24 `, 25 `,
25 '@media (prefers-reduced-motion: reduce)': { 26 '@media (prefers-reduced-motion: reduce)': {
@@ -34,6 +35,7 @@ export default function AnimatedButton({
34 color, 35 color,
35 disabled, 36 disabled,
36 startIcon, 37 startIcon,
38 sx,
37 children, 39 children,
38}: { 40}: {
39 'aria-label'?: string; 41 'aria-label'?: string;
@@ -41,6 +43,7 @@ export default function AnimatedButton({
41 color: 'error' | 'warning' | 'primary' | 'inherit'; 43 color: 'error' | 'warning' | 'primary' | 'inherit';
42 disabled?: boolean; 44 disabled?: boolean;
43 startIcon: JSX.Element; 45 startIcon: JSX.Element;
46 sx?: SxProps<Theme> | undefined;
44 children?: ReactNode; 47 children?: ReactNode;
45}): JSX.Element { 48}): JSX.Element {
46 const [width, setWidth] = useState<string | undefined>(); 49 const [width, setWidth] = useState<string | undefined>();
@@ -65,9 +68,9 @@ export default function AnimatedButton({
65 <AnimatedButtonBase 68 <AnimatedButtonBase
66 {...(ariaLabel === undefined ? {} : { 'aria-label': ariaLabel })} 69 {...(ariaLabel === undefined ? {} : { 'aria-label': ariaLabel })}
67 {...(onClick === undefined ? {} : { onClick })} 70 {...(onClick === undefined ? {} : { onClick })}
71 {...(sx === undefined ? {} : { sx })}
68 color={color} 72 color={color}
69 variant="outlined" 73 className="rounded shaded"
70 className="rounded"
71 disabled={disabled ?? false} 74 disabled={disabled ?? false}
72 startIcon={startIcon} 75 startIcon={startIcon}
73 width={width === undefined ? 'auto' : `calc(${width} + 50px)`} 76 width={width === undefined ? 'auto' : `calc(${width} + 50px)`}
@@ -91,5 +94,6 @@ AnimatedButton.defaultProps = {
91 'aria-label': undefined, 94 'aria-label': undefined,
92 onClick: undefined, 95 onClick: undefined,
93 disabled: false, 96 disabled: false,
97 sx: undefined,
94 children: undefined, 98 children: undefined,
95}; 99};
diff --git a/subprojects/frontend/src/editor/EditorPane.tsx b/subprojects/frontend/src/editor/EditorPane.tsx
index 1d51b3f5..f7f8241a 100644
--- a/subprojects/frontend/src/editor/EditorPane.tsx
+++ b/subprojects/frontend/src/editor/EditorPane.tsx
@@ -2,8 +2,6 @@ import Box from '@mui/material/Box';
2import Skeleton from '@mui/material/Skeleton'; 2import Skeleton from '@mui/material/Skeleton';
3import Stack from '@mui/material/Stack'; 3import Stack from '@mui/material/Stack';
4import Toolbar from '@mui/material/Toolbar'; 4import Toolbar from '@mui/material/Toolbar';
5import { useTheme } from '@mui/material/styles';
6import useMediaQuery from '@mui/material/useMediaQuery';
7import { observer } from 'mobx-react-lite'; 5import { observer } from 'mobx-react-lite';
8import { useState } from 'react'; 6import { useState } from 'react';
9 7
@@ -12,7 +10,6 @@ import { useRootStore } from '../RootStoreProvider';
12import ConnectionStatusNotification from './ConnectionStatusNotification'; 10import ConnectionStatusNotification from './ConnectionStatusNotification';
13import EditorArea from './EditorArea'; 11import EditorArea from './EditorArea';
14import EditorButtons from './EditorButtons'; 12import EditorButtons from './EditorButtons';
15import GenerateButton from './GenerateButton';
16import SearchPanelPortal from './SearchPanelPortal'; 13import SearchPanelPortal from './SearchPanelPortal';
17 14
18function EditorLoading(): JSX.Element { 15function EditorLoading(): JSX.Element {
@@ -34,14 +31,11 @@ function EditorLoading(): JSX.Element {
34 31
35export default observer(function EditorPane(): JSX.Element { 32export default observer(function EditorPane(): JSX.Element {
36 const { editorStore } = useRootStore(); 33 const { editorStore } = useRootStore();
37 const { breakpoints } = useTheme();
38 const showGenerateButton = useMediaQuery(breakpoints.up('sm'));
39 34
40 return ( 35 return (
41 <Stack direction="column" flexGrow={1} flexShrink={1} overflow="auto"> 36 <Stack direction="column" flexGrow={1} flexShrink={1} overflow="auto">
42 <Toolbar variant="dense"> 37 <Toolbar variant="dense">
43 <EditorButtons editorStore={editorStore} /> 38 <EditorButtons editorStore={editorStore} />
44 {showGenerateButton && <GenerateButton editorStore={editorStore} />}
45 </Toolbar> 39 </Toolbar>
46 <Box display="flex" flexGrow={1} flexShrink={1} overflow="auto"> 40 <Box display="flex" flexGrow={1} flexShrink={1} overflow="auto">
47 {editorStore === undefined ? ( 41 {editorStore === undefined ? (
diff --git a/subprojects/frontend/src/editor/EditorTheme.ts b/subprojects/frontend/src/editor/EditorTheme.ts
index e9907e83..3f2a3bff 100644
--- a/subprojects/frontend/src/editor/EditorTheme.ts
+++ b/subprojects/frontend/src/editor/EditorTheme.ts
@@ -161,7 +161,7 @@ export default styled('div', {
161 background: 'transparent', 161 background: 'transparent',
162 }, 162 },
163 '.cm-cursor, .cm-cursor-primary': { 163 '.cm-cursor, .cm-cursor-primary': {
164 borderLeft: `2px solid ${theme.palette.highlight.cursor}`, 164 borderLeft: `2px solid ${theme.palette.info.main}`,
165 }, 165 },
166 '.cm-selectionBackground': { 166 '.cm-selectionBackground': {
167 background: theme.palette.highlight.selection, 167 background: theme.palette.highlight.selection,
@@ -265,7 +265,7 @@ export default styled('div', {
265 }, 265 },
266 '.cm-indentation-marker': { 266 '.cm-indentation-marker': {
267 display: 'inline-block', 267 display: 'inline-block',
268 boxShadow: `1px 0 0 ${theme.palette.highlight.lineNumber} inset`, 268 boxShadow: `1px 0 0 ${theme.palette.text.disabled} inset`,
269 '&.active': { 269 '&.active': {
270 boxShadow: `1px 0 0 ${theme.palette.text.primary} inset`, 270 boxShadow: `1px 0 0 ${theme.palette.text.primary} inset`,
271 }, 271 },
@@ -273,7 +273,7 @@ export default styled('div', {
273 '.cm-scroller-selection': { 273 '.cm-scroller-selection': {
274 position: 'absolute', 274 position: 'absolute',
275 right: 0, 275 right: 0,
276 boxShadow: `0 2px 0 ${theme.palette.highlight.cursor} inset`, 276 boxShadow: `0 2px 0 ${theme.palette.info.main} inset`,
277 zIndex: 200, 277 zIndex: 200,
278 }, 278 },
279 '.cm-scroller-occurrence': { 279 '.cm-scroller-occurrence': {
@@ -286,7 +286,7 @@ export default styled('div', {
286 const lineNumberStyle: CSSObject = { 286 const lineNumberStyle: CSSObject = {
287 '.cm-lineNumbers': { 287 '.cm-lineNumbers': {
288 ...editorFontStyle, 288 ...editorFontStyle,
289 color: theme.palette.highlight.lineNumber, 289 color: theme.palette.text.disabled,
290 ...(!showLineNumbers && { 290 ...(!showLineNumbers && {
291 display: 'none !important', 291 display: 'none !important',
292 }), 292 }),
@@ -426,7 +426,7 @@ export default styled('div', {
426 '&[aria-selected="true"]': { 426 '&[aria-selected="true"]': {
427 color: theme.palette.text.primary, 427 color: theme.palette.text.primary,
428 background: 'transparent', 428 background: 'transparent',
429 fontWeight: theme.typography.fontWeightMedium, 429 fontWeight: theme.typography.fontWeightBold,
430 }, 430 },
431 ':hover': { 431 ':hover': {
432 background: alpha( 432 background: alpha(
diff --git a/subprojects/frontend/src/editor/GenerateButton.tsx b/subprojects/frontend/src/editor/GenerateButton.tsx
index 1a32f5ce..2036fc28 100644
--- a/subprojects/frontend/src/editor/GenerateButton.tsx
+++ b/subprojects/frontend/src/editor/GenerateButton.tsx
@@ -1,6 +1,7 @@
1import DangerousOutlinedIcon from '@mui/icons-material/DangerousOutlined'; 1import DangerousOutlinedIcon from '@mui/icons-material/DangerousOutlined';
2import PlayArrowIcon from '@mui/icons-material/PlayArrow'; 2import PlayArrowIcon from '@mui/icons-material/PlayArrow';
3import Button from '@mui/material/Button'; 3import Button from '@mui/material/Button';
4import type { SxProps, Theme } from '@mui/material/styles';
4import { observer } from 'mobx-react-lite'; 5import { observer } from 'mobx-react-lite';
5 6
6import AnimatedButton from './AnimatedButton'; 7import AnimatedButton from './AnimatedButton';
@@ -11,13 +12,20 @@ const GENERATE_LABEL = 'Generate';
11const GenerateButton = observer(function GenerateButton({ 12const GenerateButton = observer(function GenerateButton({
12 editorStore, 13 editorStore,
13 hideWarnings, 14 hideWarnings,
15 sx,
14}: { 16}: {
15 editorStore: EditorStore | undefined; 17 editorStore: EditorStore | undefined;
16 hideWarnings?: boolean | undefined; 18 hideWarnings?: boolean | undefined;
19 sx?: SxProps<Theme> | undefined;
17}): JSX.Element { 20}): JSX.Element {
18 if (editorStore === undefined) { 21 if (editorStore === undefined) {
19 return ( 22 return (
20 <Button color="inherit" variant="outlined" className="rounded" disabled> 23 <Button
24 color="inherit"
25 className="rounded shaded"
26 disabled
27 {...(sx === undefined ? {} : { sx })}
28 >
21 Loading&hellip; 29 Loading&hellip;
22 </Button> 30 </Button>
23 ); 31 );
@@ -41,6 +49,7 @@ const GenerateButton = observer(function GenerateButton({
41 onClick={() => editorStore.nextDiagnostic()} 49 onClick={() => editorStore.nextDiagnostic()}
42 color="error" 50 color="error"
43 startIcon={<DangerousOutlinedIcon />} 51 startIcon={<DangerousOutlinedIcon />}
52 {...(sx === undefined ? {} : { sx })}
44 > 53 >
45 {summary} 54 {summary}
46 </AnimatedButton> 55 </AnimatedButton>
@@ -52,6 +61,7 @@ const GenerateButton = observer(function GenerateButton({
52 disabled={!editorStore.opened} 61 disabled={!editorStore.opened}
53 color={warningCount > 0 ? 'warning' : 'primary'} 62 color={warningCount > 0 ? 'warning' : 'primary'}
54 startIcon={<PlayArrowIcon />} 63 startIcon={<PlayArrowIcon />}
64 {...(sx === undefined ? {} : { sx })}
55 > 65 >
56 {summary === '' ? GENERATE_LABEL : `${GENERATE_LABEL} (${summary})`} 66 {summary === '' ? GENERATE_LABEL : `${GENERATE_LABEL} (${summary})`}
57 </AnimatedButton> 67 </AnimatedButton>
@@ -60,6 +70,7 @@ const GenerateButton = observer(function GenerateButton({
60 70
61GenerateButton.defaultProps = { 71GenerateButton.defaultProps = {
62 hideWarnings: false, 72 hideWarnings: false,
73 sx: undefined,
63}; 74};
64 75
65export default GenerateButton; 76export default GenerateButton;
diff --git a/subprojects/frontend/src/theme/ThemeProvider.tsx b/subprojects/frontend/src/theme/ThemeProvider.tsx
index 85844d3c..7bda1ede 100644
--- a/subprojects/frontend/src/theme/ThemeProvider.tsx
+++ b/subprojects/frontend/src/theme/ThemeProvider.tsx
@@ -1,15 +1,13 @@
1import { 1import {
2 alpha, 2 alpha,
3 createTheme, 3 createTheme,
4 type Components,
5 type CSSObject,
6 responsiveFontSizes, 4 responsiveFontSizes,
7 type Theme, 5 type Theme,
8 type ThemeOptions, 6 type ThemeOptions,
9 ThemeProvider as MaterialUiThemeProvider, 7 ThemeProvider as MaterialUiThemeProvider,
10 type TypographyStyle, 8 type TypographyStyle,
11 type TypographyVariantsOptions,
12 useTheme, 9 useTheme,
10 type CSSObject,
13} from '@mui/material/styles'; 11} from '@mui/material/styles';
14import { observer } from 'mobx-react-lite'; 12import { observer } from 'mobx-react-lite';
15import { type ReactNode, createContext, useContext } from 'react'; 13import { type ReactNode, createContext, useContext } from 'react';
@@ -22,13 +20,11 @@ interface OuterPalette {
22} 20}
23 21
24interface HighlightPalette { 22interface HighlightPalette {
25 cursor: string;
26 number: string; 23 number: string;
27 parameter: string; 24 parameter: string;
28 comment: string; 25 comment: string;
29 activeLine: string; 26 activeLine: string;
30 selection: string; 27 selection: string;
31 lineNumber: string;
32 foldPlaceholder: string; 28 foldPlaceholder: string;
33 activeLintRange: string; 29 activeLintRange: string;
34 occurences: { 30 occurences: {
@@ -49,11 +45,10 @@ declare module '@mui/material/styles' {
49 editor: TypographyStyle; 45 editor: TypographyStyle;
50 } 46 }
51 47
52 // eslint-disable-next-line @typescript-eslint/no-shadow -- Augment imported interface.
53 interface TypographyVariantsOptions { 48 interface TypographyVariantsOptions {
54 fontWeightEditorNormal: number; 49 fontWeightEditorNormal?: number;
55 fontWeightEditorBold: number; 50 fontWeightEditorBold?: number;
56 editor: TypographyStyle; 51 editor?: TypographyStyle;
57 } 52 }
58 53
59 interface Palette { 54 interface Palette {
@@ -62,221 +57,269 @@ declare module '@mui/material/styles' {
62 } 57 }
63 58
64 interface PaletteOptions { 59 interface PaletteOptions {
65 outer: OuterPalette; 60 outer?: Partial<OuterPalette>;
66 highlight: HighlightPalette; 61 highlight?: Partial<HighlightPalette>;
67 } 62 }
68} 63}
69 64
70const typography: TypographyVariantsOptions = { 65function createResponsiveTheme(
71 fontFamily: 66 options: ThemeOptions,
72 '"InterVariable", "Inter", "Roboto", "Helvetica", "Arial", sans-serif', 67 overrides: ThemeOptions = {},
73 fontWeightMedium: 600, 68): Theme {
74 fontWeightEditorNormal: 400, 69 const theme = createTheme({
75 fontWeightEditorBold: 700, 70 ...options,
76 button: { 71 typography: {
77 // 24px line height for 14px button text means 36px high buttons. 72 fontFamily:
78 // Making sure the button has whole pixel height reduces redering errors on Android. 73 '"InterVariable", "Inter", "Roboto", "Helvetica", "Arial", sans-serif',
79 lineHeight: 1.7143, 74 fontWeightMedium: 600,
80 }, 75 fontWeightEditorNormal: 400,
81 editor: { 76 fontWeightEditorBold: 700,
82 fontFamily: 77 button: {
83 '"JetBrains MonoVariable", "JetBrains Mono", "Cascadia Code", "Fira Code", monospace', 78 // 24px line height for 14px button text to fix browser rounding errors.
84 fontFeatureSettings: '"liga", "calt"', 79 lineHeight: 1.714286,
85 // `rem` for JetBrains MonoVariable make the text too large in Safari.
86 fontSize: '16px',
87 fontWeight: 400,
88 lineHeight: 1.5,
89 letterSpacing: 0,
90 textRendering: 'optimizeLegibility',
91 },
92};
93
94const components: Components = {
95 MuiButton: {
96 styleOverrides: {
97 root: {
98 '&.rounded': { borderRadius: '50em' },
99 '.MuiButton-startIcon': { marginRight: 6 },
100 '.MuiButton-endIcon': { marginLeft: 6 },
101 }, 80 },
102 sizeSmall: { fontSize: '0.75rem' }, 81 editor: {
103 sizeLarge: { fontSize: '1rem' }, 82 fontFamily:
104 text: { '&.rounded': { padding: '6px 14px' } }, 83 '"JetBrains MonoVariable", "JetBrains Mono", "Cascadia Code", "Fira Code", monospace',
105 textSizeSmall: { '&.rounded': { padding: '4px 8px' } }, 84 fontFeatureSettings: '"liga", "calt"',
106 textSizeLarge: { '&.rounded': { padding: '8px 20px' } }, 85 // `rem` for JetBrains MonoVariable make the text too large in Safari.
107 outlined: { '&.rounded': { padding: '5px 13px' } }, 86 fontSize: '16px',
108 outlinedSizeSmall: { '&.rounded': { padding: '3px 9px' } }, 87 fontWeight: 400,
109 outlinedSizeLarge: { '&.rounded': { padding: '7px 19px' } }, 88 lineHeight: 1.5,
110 }, 89 letterSpacing: 0,
111 }, 90 textRendering: 'optimizeLegibility',
112 MuiToggleButton: { 91 },
113 styleOverrides: { 92 ...(options.typography ?? {}),
114 root: { '&.iconOnly': { borderRadius: '100%' } },
115 }, 93 },
116 }, 94 });
117 MuiToggleButtonGroup: { 95
118 styleOverrides: { 96 function shadedButtonStyle(color: string): CSSObject {
119 root: { 97 const opacity = theme.palette.action.focusOpacity;
120 '&.rounded .MuiToggleButtonGroup-groupedHorizontal': { 98 return {
121 ':first-of-type': { 99 background: alpha(color, opacity),
122 paddingLeft: 15, 100 ':hover': {
123 borderRadius: '50em 0 0 50em', 101 background: alpha(color, opacity + theme.palette.action.hoverOpacity),
124 }, 102 '@media(hover: none)': {
125 ':last-of-type': { 103 background: alpha(color, opacity),
126 paddingRight: 15, 104 },
127 borderRadius: '0 50em 50em 0', 105 },
128 }, 106 '&.Mui-disabled': {
129 '&.MuiToggleButton-sizeSmall': { 107 background: alpha(theme.palette.text.disabled, opacity),
130 ':first-of-type': { paddingLeft: 9 }, 108 },
131 ':last-of-type': { paddingRight: 9 }, 109 };
110 }
111
112 const themeWithComponents = createTheme(theme, {
113 components: {
114 MuiCssBaseline: {
115 styleOverrides: {
116 body: {
117 overscrollBehavior: 'contain',
132 }, 118 },
133 '&.MuiToggleButton-sizeLarge': { 119 },
134 ':first-of-type': { paddingLeft: 21 }, 120 },
135 ':last-of-type': { paddingRight: 21 }, 121 MuiButton: {
122 styleOverrides: {
123 root: {
124 '&.rounded': { borderRadius: '50em' },
125 '.MuiButton-startIcon': { marginRight: 6 },
126 '.MuiButton-endIcon': { marginLeft: 6 },
127 '&.shaded': {
128 ...shadedButtonStyle(theme.palette.text.primary),
129 ...(
130 [
131 'primary',
132 'secondary',
133 'error',
134 'warning',
135 'success',
136 'info',
137 ] as const
138 ).reduce((accumulator: CSSObject, color) => {
139 const colorCapitalized =
140 (color[0] ?? '').toUpperCase() + color.substring(1);
141 return {
142 ...accumulator,
143 [`&.MuiButton-text${colorCapitalized}, &.MuiButton-outlined${colorCapitalized}`]:
144 shadedButtonStyle(theme.palette[color].main),
145 };
146 }, {}),
147 },
136 }, 148 },
149 sizeSmall: { fontSize: '0.75rem' },
150 sizeLarge: { fontSize: '1rem' },
151 text: { '&.rounded': { padding: '6px 14px' } },
152 textSizeSmall: { '&.rounded': { padding: '4px 8px' } },
153 textSizeLarge: { '&.rounded': { padding: '8px 20px' } },
154 outlined: { '&.rounded': { padding: '5px 13px' } },
155 outlinedSizeSmall: { '&.rounded': { padding: '3px 9px' } },
156 outlinedSizeLarge: { '&.rounded': { padding: '7px 19px' } },
137 }, 157 },
138 }, 158 },
139 }, 159 MuiToggleButton: {
140 }, 160 styleOverrides: {
141 MuiTooltip: { 161 root: { '&.iconOnly': { borderRadius: '100%' } },
142 styleOverrides: { 162 },
143 tooltip: {
144 background: alpha('#212121', 0.93),
145 color: '#fff',
146 }, 163 },
147 arrow: { 164 MuiToggleButtonGroup: {
148 color: alpha('#212121', 0.93), 165 styleOverrides: {
166 root: {
167 '&.rounded .MuiToggleButtonGroup-groupedHorizontal': {
168 ':first-of-type': {
169 paddingLeft: 15,
170 borderRadius: '50em 0 0 50em',
171 },
172 ':last-of-type': {
173 paddingRight: 15,
174 borderRadius: '0 50em 50em 0',
175 },
176 '&.MuiToggleButton-sizeSmall': {
177 ':first-of-type': { paddingLeft: 9 },
178 ':last-of-type': { paddingRight: 9 },
179 },
180 '&.MuiToggleButton-sizeLarge': {
181 ':first-of-type': { paddingLeft: 21 },
182 ':last-of-type': { paddingRight: 21 },
183 },
184 },
185 },
186 },
187 },
188 MuiTooltip: {
189 styleOverrides: {
190 tooltip: {
191 background: alpha('#212121', 0.93),
192 color: '#fff',
193 },
194 arrow: {
195 color: alpha('#212121', 0.93),
196 },
197 },
149 }, 198 },
150 }, 199 },
151 }, 200 });
152};
153 201
154function createResponsiveTheme(options: ThemeOptions): Theme { 202 const themeWithOverrides = createTheme(themeWithComponents, overrides);
155 return responsiveFontSizes(createTheme(options)); 203
204 return responsiveFontSizes(themeWithOverrides);
156} 205}
157 206
158const lightTheme = createResponsiveTheme({ 207const lightTheme = (() => {
159 typography, 208 const primaryText = '#19202b';
160 components, 209 const disabledText = '#a0a1a7';
161 palette: { 210 const darkBackground = '#f5f5f5';
162 mode: 'light', 211
163 primary: { main: '#038a99' }, 212 return createResponsiveTheme({
164 secondary: { main: '#e45649' }, 213 palette: {
165 error: { main: '#ca1243' }, 214 mode: 'light',
166 warning: { main: '#c18401' }, 215 primary: { main: '#038a99' },
167 success: { main: '#50a14f' }, 216 secondary: { main: '#e45649' },
168 info: { main: '#4078f2' }, 217 error: { main: '#ca1243' },
169 background: { 218 warning: { main: '#c18401' },
170 default: '#fff', 219 success: { main: '#50a14f' },
171 paper: '#fff', 220 info: { main: '#4078f2' },
172 }, 221 background: {
173 text: { 222 default: '#fff',
174 primary: '#19202b', 223 paper: '#fff',
175 secondary: '#696c77',
176 disabled: '#a0a1a7',
177 },
178 divider: alpha('#19202b', 0.16),
179 outer: {
180 background: '#f5f5f5',
181 border: '#c8c8c8',
182 },
183 highlight: {
184 cursor: '#4078f2',
185 number: '#0084bc',
186 parameter: '#6a3e3e',
187 comment: '#a0a1a7',
188 activeLine: '#f5f5f5',
189 selection: '#c8e4fb',
190 lineNumber: '#a0a1a7',
191 foldPlaceholder: alpha('#19202b', 0.08),
192 activeLintRange: alpha('#f2a60d', 0.28),
193 occurences: {
194 read: alpha('#19202b', 0.16),
195 write: alpha('#19202b', 0.16),
196 }, 224 },
197 search: { 225 text: {
198 match: '#00bcd4', 226 primary: primaryText,
199 selected: '#d500f9', 227 secondary: '#696c77',
200 contrastText: '#ffffff', 228 disabled: disabledText,
201 }, 229 },
202 }, 230 divider: alpha(primaryText, 0.16),
203 }, 231 outer: {
204}); 232 background: darkBackground,
205 233 border: '#c8c8c8',
206const darkTheme = createResponsiveTheme({ 234 },
207 typography: { 235 highlight: {
208 ...typography, 236 number: '#0084bc',
209 fontWeightEditorNormal: 350, 237 parameter: '#6a3e3e',
210 fontWeightEditorBold: 650, 238 comment: disabledText,
211 }, 239 activeLine: darkBackground,
212 components: { 240 selection: '#c8e4fb',
213 ...components, 241 foldPlaceholder: alpha(primaryText, 0.08),
214 MuiSnackbarContent: { 242 activeLintRange: alpha('#f2a60d', 0.28),
215 styleOverrides: { 243 occurences: {
216 root: { 244 read: alpha(primaryText, 0.16),
217 color: '#f00', 245 write: alpha(primaryText, 0.16),
218 backgroundColor: '#000', 246 },
219 border: `10px solid #ff0`, 247 search: {
248 match: '#00bcd4',
249 selected: '#d500f9',
250 contrastText: '#fff',
220 }, 251 },
221 }, 252 },
222 }, 253 },
223 MuiTooltip: { 254 });
224 ...(components.MuiTooltip || {}), 255})();
225 styleOverrides: { 256
226 ...(components.MuiTooltip?.styleOverrides || {}), 257const darkTheme = (() => {
227 tooltip: { 258 const primaryText = '#ebebff';
228 ...((components.MuiTooltip?.styleOverrides?.tooltip as 259 const secondaryText = '#abb2bf';
229 | CSSObject 260 const darkBackground = '#21252b';
230 | undefined) || {}), 261
231 color: '#ebebff', 262 return createResponsiveTheme(
263 {
264 typography: {
265 fontWeightEditorNormal: 350,
266 fontWeightEditorBold: 650,
267 },
268 palette: {
269 mode: 'dark',
270 primary: { main: '#56b6c2' },
271 secondary: { main: '#be5046' },
272 error: { main: '#e06c75' },
273 warning: { main: '#e5c07b' },
274 success: { main: '#98c379' },
275 info: { main: '#61afef' },
276 background: {
277 default: '#282c34',
278 paper: darkBackground,
279 },
280 text: {
281 primary: primaryText,
282 secondary: secondaryText,
283 disabled: '#5c6370',
284 },
285 divider: alpha(secondaryText, 0.24),
286 outer: {
287 background: darkBackground,
288 border: '#181a1f',
289 },
290 highlight: {
291 number: '#6188a6',
292 parameter: '#c8ae9d',
293 comment: '#7f848e',
294 activeLine: '#2c313c',
295 selection: '#404859',
296 foldPlaceholder: alpha(primaryText, 0.12),
297 activeLintRange: alpha('#fbc346', 0.28),
298 occurences: {
299 read: alpha(primaryText, 0.14),
300 write: alpha(primaryText, 0.14),
301 },
302 search: {
303 match: '#33eaff',
304 selected: '#dd33fa',
305 contrastText: darkBackground,
306 },
232 }, 307 },
233 }, 308 },
234 }, 309 },
235 }, 310 {
236 palette: { 311 components: {
237 mode: 'dark', 312 MuiTooltip: {
238 primary: { main: '#56b6c2' }, 313 styleOverrides: {
239 secondary: { main: '#be5046' }, 314 tooltip: {
240 error: { main: '#e06c75' }, 315 color: primaryText,
241 warning: { main: '#e5c07b' }, 316 },
242 success: { main: '#98c379' }, 317 },
243 info: { main: '#61afef' }, 318 },
244 background: {
245 default: '#282c34',
246 paper: '#21252b',
247 },
248 text: {
249 primary: '#ebebff',
250 secondary: '#abb2bf',
251 disabled: '#5c6370',
252 },
253 divider: alpha('#abb2bf', 0.24),
254 outer: {
255 background: '#21252b',
256 border: '#181a1f',
257 },
258 highlight: {
259 cursor: '#61afef',
260 number: '#6188a6',
261 parameter: '#c8ae9d',
262 comment: '#7f848e',
263 activeLine: '#2c313c',
264 selection: '#404859',
265 lineNumber: '#5c6370',
266 foldPlaceholder: alpha('#ebebff', 0.12),
267 activeLintRange: alpha('#fbc346', 0.28),
268 occurences: {
269 read: alpha('#ebebff', 0.14),
270 write: alpha('#ebebff', 0.14),
271 },
272 search: {
273 match: '#33eaff',
274 selected: '#dd33fa',
275 contrastText: '#21252b',
276 }, 319 },
277 }, 320 },
278 }, 321 );
279}); 322})();
280 323
281const ContrastThemeContext = createContext<Theme | undefined>(undefined); 324const ContrastThemeContext = createContext<Theme | undefined>(undefined);
282 325