diff options
Diffstat (limited to 'language-web/src/main/js/editor/EditorParent.ts')
-rw-r--r-- | language-web/src/main/js/editor/EditorParent.ts | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/language-web/src/main/js/editor/EditorParent.ts b/language-web/src/main/js/editor/EditorParent.ts new file mode 100644 index 00000000..ee1323f6 --- /dev/null +++ b/language-web/src/main/js/editor/EditorParent.ts | |||
@@ -0,0 +1,200 @@ | |||
1 | import { styled } from '@mui/material/styles'; | ||
2 | |||
3 | /** | ||
4 | * Returns a squiggly underline background image encoded as a CSS `url()` data URI with Base64. | ||
5 | * | ||
6 | * Based on | ||
7 | * https://github.com/codemirror/lint/blob/f524b4a53b0183bb343ac1e32b228d28030d17af/src/lint.ts#L501 | ||
8 | * | ||
9 | * @param color the color of the underline | ||
10 | * @returns the CSS `url()` | ||
11 | */ | ||
12 | function underline(color: string) { | ||
13 | const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="6" height="3"> | ||
14 | <path d="m0 3 l2 -2 l1 0 l2 2 l1 0" stroke="${color}" fill="none" stroke-width=".7"/> | ||
15 | </svg>`; | ||
16 | const svgBase64 = window.btoa(svg); | ||
17 | return `url('data:image/svg+xml;base64,${svgBase64}')`; | ||
18 | } | ||
19 | |||
20 | export const EditorParent = styled('div')(({ theme }) => { | ||
21 | const codeMirrorLintStyle: Record<string, unknown> = {}; | ||
22 | (['error', 'warning', 'info'] as const).forEach((severity) => { | ||
23 | const color = theme.palette[severity].main; | ||
24 | codeMirrorLintStyle[`.cm-diagnostic-${severity}`] = { | ||
25 | borderLeftColor: color, | ||
26 | }; | ||
27 | codeMirrorLintStyle[`.cm-lintRange-${severity}`] = { | ||
28 | backgroundImage: underline(color), | ||
29 | }; | ||
30 | }); | ||
31 | |||
32 | return { | ||
33 | background: theme.palette.background.default, | ||
34 | '&, .cm-editor': { | ||
35 | height: '100%', | ||
36 | }, | ||
37 | '.cm-scroller, .cm-tooltip-autocomplete, .cm-completionLabel, .cm-completionDetail': { | ||
38 | fontSize: 16, | ||
39 | fontFamily: '"JetBrains MonoVariable", "JetBrains Mono", monospace', | ||
40 | fontFeatureSettings: '"liga", "calt"', | ||
41 | fontWeight: 400, | ||
42 | letterSpacing: 0, | ||
43 | textRendering: 'optimizeLegibility', | ||
44 | }, | ||
45 | '.cm-scroller': { | ||
46 | color: theme.palette.text.secondary, | ||
47 | }, | ||
48 | '.cm-gutters': { | ||
49 | background: theme.palette.background.default, | ||
50 | color: theme.palette.text.disabled, | ||
51 | border: 'none', | ||
52 | }, | ||
53 | '.cm-specialChar': { | ||
54 | color: theme.palette.secondary.main, | ||
55 | }, | ||
56 | '.cm-activeLine': { | ||
57 | background: 'rgba(0, 0, 0, 0.3)', | ||
58 | }, | ||
59 | '.cm-activeLineGutter': { | ||
60 | background: 'rgba(0, 0, 0, 0.3)', | ||
61 | color: theme.palette.text.primary, | ||
62 | }, | ||
63 | '.cm-cursor, .cm-cursor-primary': { | ||
64 | borderColor: theme.palette.primary.main, | ||
65 | background: theme.palette.common.black, | ||
66 | }, | ||
67 | '.cm-selectionBackground': { | ||
68 | background: '#3e4453', | ||
69 | }, | ||
70 | '.cm-focused': { | ||
71 | outline: 'none', | ||
72 | '.cm-selectionBackground': { | ||
73 | background: '#3e4453', | ||
74 | }, | ||
75 | }, | ||
76 | '.cm-panels-top': { | ||
77 | color: theme.palette.text.secondary, | ||
78 | }, | ||
79 | '.cm-panel': { | ||
80 | '&, & button, & input': { | ||
81 | fontFamily: '"Roboto","Helvetica","Arial",sans-serif', | ||
82 | }, | ||
83 | background: theme.palette.background.paper, | ||
84 | borderTop: `1px solid ${theme.palette.divider}`, | ||
85 | 'button[name="close"]': { | ||
86 | background: 'transparent', | ||
87 | color: theme.palette.text.secondary, | ||
88 | cursor: 'pointer', | ||
89 | }, | ||
90 | }, | ||
91 | '.cm-panel.cm-panel-lint': { | ||
92 | 'button[name="close"]': { | ||
93 | // Close button interferes with scrollbar, so we better hide it. | ||
94 | // The panel can still be closed from the toolbar. | ||
95 | display: 'none', | ||
96 | }, | ||
97 | ul: { | ||
98 | li: { | ||
99 | borderBottom: `1px solid ${theme.palette.divider}`, | ||
100 | cursor: 'pointer', | ||
101 | }, | ||
102 | '[aria-selected]': { | ||
103 | background: '#3e4453', | ||
104 | color: theme.palette.text.primary, | ||
105 | }, | ||
106 | '&:focus [aria-selected]': { | ||
107 | background: theme.palette.primary.main, | ||
108 | color: theme.palette.primary.contrastText, | ||
109 | }, | ||
110 | }, | ||
111 | }, | ||
112 | '.cm-foldPlaceholder': { | ||
113 | background: theme.palette.background.paper, | ||
114 | borderColor: theme.palette.text.disabled, | ||
115 | color: theme.palette.text.secondary, | ||
116 | }, | ||
117 | '.cmt-comment': { | ||
118 | fontStyle: 'italic', | ||
119 | color: theme.palette.text.disabled, | ||
120 | }, | ||
121 | '.cmt-number': { | ||
122 | color: '#6188a6', | ||
123 | }, | ||
124 | '.cmt-string': { | ||
125 | color: theme.palette.secondary.dark, | ||
126 | }, | ||
127 | '.cmt-keyword': { | ||
128 | color: theme.palette.primary.main, | ||
129 | }, | ||
130 | '.cmt-typeName, .cmt-macroName, .cmt-atom': { | ||
131 | color: theme.palette.text.primary, | ||
132 | }, | ||
133 | '.cmt-variableName': { | ||
134 | color: '#c8ae9d', | ||
135 | }, | ||
136 | '.cmt-problem-node': { | ||
137 | '&, & .cmt-variableName': { | ||
138 | color: theme.palette.text.secondary, | ||
139 | }, | ||
140 | }, | ||
141 | '.cmt-problem-unique': { | ||
142 | '&, & .cmt-variableName': { | ||
143 | color: theme.palette.text.primary, | ||
144 | }, | ||
145 | }, | ||
146 | '.cmt-problem-abstract, .cmt-problem-new': { | ||
147 | fontStyle: 'italic', | ||
148 | }, | ||
149 | '.cmt-problem-containment': { | ||
150 | fontWeight: 700, | ||
151 | }, | ||
152 | '.cmt-problem-error': { | ||
153 | '&, & .cmt-typeName': { | ||
154 | color: theme.palette.error.main, | ||
155 | }, | ||
156 | }, | ||
157 | '.cmt-problem-builtin': { | ||
158 | '&, & .cmt-typeName, & .cmt-atom, & .cmt-variableName': { | ||
159 | color: theme.palette.primary.main, | ||
160 | fontWeight: 400, | ||
161 | fontStyle: 'normal', | ||
162 | }, | ||
163 | }, | ||
164 | '.cm-tooltip-autocomplete': { | ||
165 | background: theme.palette.background.paper, | ||
166 | boxShadow: `0px 2px 4px -1px rgb(0 0 0 / 20%), | ||
167 | 0px 4px 5px 0px rgb(0 0 0 / 14%), | ||
168 | 0px 1px 10px 0px rgb(0 0 0 / 12%)`, | ||
169 | '.cm-completionIcon': { | ||
170 | color: theme.palette.text.secondary, | ||
171 | }, | ||
172 | '.cm-completionLabel': { | ||
173 | color: theme.palette.text.primary, | ||
174 | }, | ||
175 | '.cm-completionDetail': { | ||
176 | color: theme.palette.text.secondary, | ||
177 | fontStyle: 'normal', | ||
178 | }, | ||
179 | '[aria-selected]': { | ||
180 | background: `${theme.palette.primary.main} !important`, | ||
181 | '.cm-completionIcon, .cm-completionLabel, .cm-completionDetail': { | ||
182 | color: theme.palette.primary.contrastText, | ||
183 | }, | ||
184 | }, | ||
185 | }, | ||
186 | '.cm-completionIcon': { | ||
187 | width: 16, | ||
188 | padding: 0, | ||
189 | marginRight: '0.5em', | ||
190 | textAlign: 'center', | ||
191 | }, | ||
192 | ...codeMirrorLintStyle, | ||
193 | '.cm-problem-write': { | ||
194 | background: 'rgba(255, 255, 128, 0.3)', | ||
195 | }, | ||
196 | '.cm-problem-read': { | ||
197 | background: 'rgba(255, 255, 255, 0.15)', | ||
198 | }, | ||
199 | }; | ||
200 | }); | ||