diff options
author | 2022-08-16 21:14:50 +0200 | |
---|---|---|
committer | 2022-08-16 21:14:50 +0200 | |
commit | 19cd11118cde7160cd447c81bc965007c0437479 (patch) | |
tree | 5fea613e7a46d69380995368a68cc72f186078a4 /subprojects/frontend/src/editor/EditorTheme.ts | |
parent | chore(deps): bump frontend dependencies (diff) | |
download | refinery-19cd11118cde7160cd447c81bc965007c0437479.tar.gz refinery-19cd11118cde7160cd447c81bc965007c0437479.tar.zst refinery-19cd11118cde7160cd447c81bc965007c0437479.zip |
refactor(frondend): improve editor store and theme
Also bumps frontend dependencies.
Diffstat (limited to 'subprojects/frontend/src/editor/EditorTheme.ts')
-rw-r--r-- | subprojects/frontend/src/editor/EditorTheme.ts | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/subprojects/frontend/src/editor/EditorTheme.ts b/subprojects/frontend/src/editor/EditorTheme.ts new file mode 100644 index 00000000..8d98e832 --- /dev/null +++ b/subprojects/frontend/src/editor/EditorTheme.ts | |||
@@ -0,0 +1,342 @@ | |||
1 | import errorSVG from '@material-icons/svg/svg/error/baseline.svg?raw'; | ||
2 | import expandMoreSVG from '@material-icons/svg/svg/expand_more/baseline.svg?raw'; | ||
3 | import infoSVG from '@material-icons/svg/svg/info/baseline.svg?raw'; | ||
4 | import warningSVG from '@material-icons/svg/svg/warning/baseline.svg?raw'; | ||
5 | import { alpha, styled } from '@mui/material/styles'; | ||
6 | |||
7 | import editorClassNames from './editorClassNames'; | ||
8 | |||
9 | function svgURL(svg: string): string { | ||
10 | return `url('data:image/svg+xml;utf8,${svg}')`; | ||
11 | } | ||
12 | |||
13 | export default styled('div', { | ||
14 | name: 'EditorTheme', | ||
15 | shouldForwardProp: (propName) => propName !== 'showLineNumbers', | ||
16 | })<{ showLineNumbers: boolean }>(({ theme, showLineNumbers }) => { | ||
17 | let codeMirrorLintStyle: Record<string, unknown> = {}; | ||
18 | ( | ||
19 | [ | ||
20 | { | ||
21 | severity: 'error', | ||
22 | icon: errorSVG, | ||
23 | }, | ||
24 | { | ||
25 | severity: 'warning', | ||
26 | icon: warningSVG, | ||
27 | }, | ||
28 | { | ||
29 | severity: 'info', | ||
30 | icon: infoSVG, | ||
31 | }, | ||
32 | ] as const | ||
33 | ).forEach(({ severity, icon }) => { | ||
34 | const palette = theme.palette[severity]; | ||
35 | const color = palette.main; | ||
36 | const iconStyle = { | ||
37 | background: color, | ||
38 | maskImage: svgURL(icon), | ||
39 | maskSize: '16px 16px', | ||
40 | height: 16, | ||
41 | width: 16, | ||
42 | }; | ||
43 | const tooltipColor = | ||
44 | theme.palette.mode === 'dark' ? palette.main : palette.light; | ||
45 | codeMirrorLintStyle = { | ||
46 | ...codeMirrorLintStyle, | ||
47 | [`.cm-lintRange-${severity}`]: { | ||
48 | backgroundImage: 'none', | ||
49 | textDecoration: `underline wavy ${color}`, | ||
50 | textDecorationSkipInk: 'none', | ||
51 | }, | ||
52 | [`.cm-diagnostic-${severity}`]: { | ||
53 | marginLeft: 0, | ||
54 | padding: '4px 8px 4px 32px', | ||
55 | borderLeft: 'none', | ||
56 | position: 'relative', | ||
57 | '::before': { | ||
58 | ...iconStyle, | ||
59 | content: '" "', | ||
60 | position: 'absolute', | ||
61 | top: 6, | ||
62 | left: 8, | ||
63 | }, | ||
64 | }, | ||
65 | [`.cm-tooltip .cm-diagnostic-${severity}::before`]: { | ||
66 | background: tooltipColor, | ||
67 | }, | ||
68 | [`.cm-lint-marker-${severity}`]: { | ||
69 | ...iconStyle, | ||
70 | display: 'block', | ||
71 | margin: '4px 0', | ||
72 | // Remove original CodeMirror icon. | ||
73 | content: '""', | ||
74 | '::before': { | ||
75 | // Remove original CodeMirror icon. | ||
76 | content: '""', | ||
77 | display: 'none', | ||
78 | }, | ||
79 | }, | ||
80 | }; | ||
81 | }); | ||
82 | |||
83 | return { | ||
84 | background: theme.palette.background.default, | ||
85 | '&, .cm-editor': { | ||
86 | height: '100%', | ||
87 | }, | ||
88 | '.cm-content': { | ||
89 | padding: 0, | ||
90 | }, | ||
91 | '.cm-scroller': { | ||
92 | color: theme.palette.text.secondary, | ||
93 | }, | ||
94 | '.cm-scroller, .cm-tooltip-autocomplete, .cm-completionLabel, .cm-completionDetail': | ||
95 | { | ||
96 | ...theme.typography.body1, | ||
97 | fontFamily: '"JetBrains MonoVariable", "JetBrains Mono", monospace', | ||
98 | fontFeatureSettings: '"liga", "calt"', | ||
99 | letterSpacing: 0, | ||
100 | textRendering: 'optimizeLegibility', | ||
101 | }, | ||
102 | '.cm-gutters': { | ||
103 | background: 'transparent', | ||
104 | color: theme.palette.text.disabled, | ||
105 | border: 'none', | ||
106 | }, | ||
107 | '.cm-specialChar': { | ||
108 | color: theme.palette.secondary.main, | ||
109 | }, | ||
110 | '.cm-activeLine': { | ||
111 | background: theme.palette.highlight.activeLine, | ||
112 | }, | ||
113 | '.cm-gutter-lint': { | ||
114 | width: 16, | ||
115 | '.cm-gutterElement': { | ||
116 | padding: 0, | ||
117 | }, | ||
118 | }, | ||
119 | '.cm-foldGutter': { | ||
120 | opacity: 0, | ||
121 | width: 16, | ||
122 | transition: theme.transitions.create('opacity', { | ||
123 | duration: theme.transitions.duration.short, | ||
124 | }), | ||
125 | '@media (hover: none)': { | ||
126 | opacity: 1, | ||
127 | }, | ||
128 | }, | ||
129 | '.cm-gutters:hover .cm-foldGutter': { | ||
130 | opacity: 1, | ||
131 | }, | ||
132 | [`.${editorClassNames.foldMarker}`]: { | ||
133 | display: 'block', | ||
134 | margin: '4px 0', | ||
135 | padding: 0, | ||
136 | maskImage: svgURL(expandMoreSVG), | ||
137 | maskSize: '16px 16px', | ||
138 | height: 16, | ||
139 | width: 16, | ||
140 | background: theme.palette.text.primary, | ||
141 | border: 'none', | ||
142 | cursor: 'pointer', | ||
143 | }, | ||
144 | [`.${editorClassNames.foldMarkerClosed}`]: { | ||
145 | transform: 'rotate(-90deg)', | ||
146 | }, | ||
147 | '.cm-activeLineGutter': { | ||
148 | background: 'transparent', | ||
149 | }, | ||
150 | '.cm-lineNumbers': { | ||
151 | ...(!showLineNumbers && { | ||
152 | display: 'none !important', | ||
153 | }), | ||
154 | '.cm-activeLineGutter': { | ||
155 | color: theme.palette.text.primary, | ||
156 | }, | ||
157 | }, | ||
158 | '.cm-cursor, .cm-cursor-primary': { | ||
159 | borderLeft: `2px solid ${theme.palette.primary.main}`, | ||
160 | }, | ||
161 | '.cm-selectionBackground': { | ||
162 | background: theme.palette.highlight.selection, | ||
163 | }, | ||
164 | '.cm-focused': { | ||
165 | outline: 'none', | ||
166 | '.cm-selectionBackground': { | ||
167 | background: theme.palette.highlight.selection, | ||
168 | }, | ||
169 | }, | ||
170 | '.cm-panels-top': { | ||
171 | color: theme.palette.text.secondary, | ||
172 | borderBottom: `1px solid ${theme.palette.outer.border}`, | ||
173 | marginBottom: theme.spacing(1), | ||
174 | }, | ||
175 | '.cm-panel': { | ||
176 | position: 'relative', | ||
177 | overflow: 'hidden', | ||
178 | background: theme.palette.outer.background, | ||
179 | borderTop: `1px solid ${theme.palette.outer.border}`, | ||
180 | '&, & button, & input': { | ||
181 | fontFamily: theme.typography.fontFamily, | ||
182 | }, | ||
183 | 'button[name="close"]': { | ||
184 | background: 'transparent', | ||
185 | color: theme.palette.text.secondary, | ||
186 | cursor: 'pointer', | ||
187 | }, | ||
188 | }, | ||
189 | '.cm-panel.cm-panel-lint': { | ||
190 | borderTop: `1px solid ${theme.palette.outer.border}`, | ||
191 | borderBottom: 'none', | ||
192 | 'button[name="close"]': { | ||
193 | // Close button interferes with scrollbar, so we better hide it. | ||
194 | // The panel can still be closed from the toolbar. | ||
195 | display: 'none', | ||
196 | }, | ||
197 | ul: { | ||
198 | maxHeight: 'max(112px, 20vh)', | ||
199 | li: { | ||
200 | cursor: 'pointer', | ||
201 | color: theme.palette.text.primary, | ||
202 | }, | ||
203 | '.cm-diagnostic': { | ||
204 | ...theme.typography.body2, | ||
205 | '&[aria-selected="true"]': { | ||
206 | color: theme.palette.text.primary, | ||
207 | background: 'transparent', | ||
208 | fontWeight: 700, | ||
209 | }, | ||
210 | ':hover': { | ||
211 | background: alpha( | ||
212 | theme.palette.text.primary, | ||
213 | theme.palette.action.hoverOpacity, | ||
214 | ), | ||
215 | }, | ||
216 | }, | ||
217 | }, | ||
218 | }, | ||
219 | [`.${editorClassNames.foldPlaceholder}`]: { | ||
220 | ...theme.typography.body1, | ||
221 | padding: 0, | ||
222 | fontFamily: 'inherit', | ||
223 | fontFeatureSettings: '"liga", "calt"', | ||
224 | color: theme.palette.text.secondary, | ||
225 | backgroundColor: alpha( | ||
226 | theme.palette.text.secondary, | ||
227 | theme.palette.action.focusOpacity, | ||
228 | ), | ||
229 | border: 'none', | ||
230 | cursor: 'pointer', | ||
231 | transition: theme.transitions.create(['background-color', 'color'], { | ||
232 | duration: theme.transitions.duration.short, | ||
233 | }), | ||
234 | '&:hover': { | ||
235 | color: theme.palette.text.primary, | ||
236 | backgroundColor: alpha( | ||
237 | theme.palette.text.secondary, | ||
238 | theme.palette.action.focusOpacity + theme.palette.action.hoverOpacity, | ||
239 | ), | ||
240 | }, | ||
241 | }, | ||
242 | '.tok-comment': { | ||
243 | fontStyle: 'italic', | ||
244 | color: theme.palette.highlight.comment, | ||
245 | }, | ||
246 | '.tok-number': { | ||
247 | color: theme.palette.highlight.number, | ||
248 | }, | ||
249 | '.tok-string': { | ||
250 | color: theme.palette.secondary, | ||
251 | }, | ||
252 | '.tok-keyword': { | ||
253 | color: theme.palette.primary.main, | ||
254 | }, | ||
255 | '.tok-typeName, .tok-atom': { | ||
256 | color: theme.palette.text.primary, | ||
257 | }, | ||
258 | '.tok-variableName': { | ||
259 | color: theme.palette.highlight.parameter, | ||
260 | }, | ||
261 | '.tok-problem-node': { | ||
262 | '&, & .tok-variableName': { | ||
263 | color: theme.palette.text.secondary, | ||
264 | }, | ||
265 | }, | ||
266 | '.tok-problem-individual': { | ||
267 | '&, & .tok-variableName': { | ||
268 | color: theme.palette.text.primary, | ||
269 | }, | ||
270 | }, | ||
271 | '.tok-problem-abstract, .tok-problem-new': { | ||
272 | fontStyle: 'italic', | ||
273 | }, | ||
274 | '.tok-problem-containment': { | ||
275 | fontWeight: 700, | ||
276 | }, | ||
277 | '.tok-problem-error': { | ||
278 | '&, & .tok-typeName': { | ||
279 | color: theme.palette.error.main, | ||
280 | }, | ||
281 | }, | ||
282 | '.tok-problem-builtin': { | ||
283 | '&, & .tok-typeName, & .tok-atom, & .tok-variableName': { | ||
284 | color: theme.palette.primary.main, | ||
285 | fontWeight: 400, | ||
286 | fontStyle: 'normal', | ||
287 | }, | ||
288 | }, | ||
289 | '.cm-tooltip.cm-tooltip-autocomplete': { | ||
290 | background: theme.palette.background.paper, | ||
291 | borderRadius: theme.shape.borderRadius, | ||
292 | overflow: 'hidden', | ||
293 | ...(theme.palette.mode === 'dark' && { | ||
294 | // https://github.com/mui/material-ui/blob/10c72729c7d03bab8cdce6eb422642684c56dca2/packages/mui-material/src/Paper/Paper.js#L18 | ||
295 | backgroundImage: | ||
296 | 'linear-gradient(rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.07))', | ||
297 | }), | ||
298 | boxShadow: theme.shadows[2], | ||
299 | '.cm-completionIcon': { | ||
300 | color: theme.palette.text.secondary, | ||
301 | }, | ||
302 | '.cm-completionLabel': { | ||
303 | color: theme.palette.text.primary, | ||
304 | }, | ||
305 | '.cm-completionDetail': { | ||
306 | color: theme.palette.text.secondary, | ||
307 | fontStyle: 'normal', | ||
308 | }, | ||
309 | 'li[aria-selected="true"]': { | ||
310 | background: alpha( | ||
311 | theme.palette.text.primary, | ||
312 | theme.palette.action.focusOpacity, | ||
313 | ), | ||
314 | '.cm-completionIcon, .cm-completionLabel, .cm-completionDetail': { | ||
315 | color: theme.palette.text.primary, | ||
316 | }, | ||
317 | }, | ||
318 | }, | ||
319 | '.cm-tooltip.cm-tooltip-hover, .cm-tooltip.cm-tooltip-lint': { | ||
320 | ...theme.typography.body2, | ||
321 | // https://github.com/mui/material-ui/blob/dee9529f7a298c54ae760761112c3ae9ba082137/packages/mui-material/src/Tooltip/Tooltip.js#L121-L125 | ||
322 | background: alpha(theme.palette.grey[700], 0.92), | ||
323 | borderRadius: theme.shape.borderRadius, | ||
324 | color: theme.palette.common.white, | ||
325 | overflow: 'hidden', | ||
326 | maxWidth: 400, | ||
327 | }, | ||
328 | '.cm-completionIcon': { | ||
329 | width: 16, | ||
330 | padding: 0, | ||
331 | marginRight: '0.5em', | ||
332 | textAlign: 'center', | ||
333 | }, | ||
334 | ...codeMirrorLintStyle, | ||
335 | '.cm-problem-read': { | ||
336 | background: theme.palette.highlight.occurences.read, | ||
337 | }, | ||
338 | '.cm-problem-write': { | ||
339 | background: theme.palette.highlight.occurences.write, | ||
340 | }, | ||
341 | }; | ||
342 | }); | ||