Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fc414bc

Browse files
committed
Show diff files with monaco
1 parent 7bf286f commit fc414bc

File tree

8 files changed

+385
-104
lines changed

8 files changed

+385
-104
lines changed

site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@material-ui/core": "4.12.1",
3333
"@material-ui/icons": "4.5.1",
3434
"@material-ui/lab": "4.0.0-alpha.42",
35+
"@monaco-editor/react": "^4.4.6",
3536
"@testing-library/react-hooks": "8.0.1",
3637
"@vitejs/plugin-react": "2.1.0",
3738
"@xstate/inspect": "0.6.5",
Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,36 @@
1-
import { makeStyles } from "@material-ui/core/styles"
2-
import { ComponentProps, FC } from "react"
3-
import { Prism } from "react-syntax-highlighter"
4-
import { colors } from "theme/colors"
5-
import darcula from "react-syntax-highlighter/dist/cjs/styles/prism/darcula"
6-
import { combineClasses } from "util/combineClasses"
7-
8-
export const SyntaxHighlighter: FC<ComponentProps<typeof Prism>> = ({
9-
className,
10-
...props
11-
}) => {
12-
const styles = useStyles()
13-
14-
return (
15-
<Prism
16-
style={darcula}
17-
useInlineStyles={false}
18-
// Use inline styles does not work correctly
19-
// https://github.com/react-syntax-highlighter/react-syntax-highlighter/issues/329
20-
codeTagProps={{ style: {} }}
21-
className={combineClasses([styles.prism, className])}
22-
{...props}
23-
/>
24-
)
25-
}
26-
27-
const useStyles = makeStyles((theme) => ({
28-
prism: {
29-
margin: 0,
30-
background: theme.palette.background.paperLight,
31-
borderRadius: theme.shape.borderRadius,
32-
padding: theme.spacing(2, 3),
33-
// Line breaks are broken when used with line numbers on react-syntax-highlighter
34-
// https://github.com/react-syntax-highlighter/react-syntax-highlighter/pull/483
35-
overflowX: "auto",
36-
37-
"& code": {
38-
color: theme.palette.text.secondary,
1+
import { FC } from "react"
2+
import Editor, { DiffEditor } from "@monaco-editor/react"
3+
import { useCoderTheme } from "./coderTheme"
4+
5+
export const SyntaxHighlighter: FC<{
6+
value: string
7+
language: string
8+
compareWith?: string
9+
}> = ({ value, compareWith, language }) => {
10+
const hasDiff = compareWith && value !== compareWith
11+
const coderTheme = useCoderTheme()
12+
const commonProps = {
13+
language,
14+
theme: coderTheme.name,
15+
height: 560,
16+
options: {
17+
minimap: {
18+
enabled: false,
19+
},
20+
renderSideBySide: false,
21+
readOnly: true,
3922
},
23+
}
4024

41-
"& .key, & .property, & .code-snippet, & .keyword": {
42-
color: colors.turquoise[7],
43-
},
25+
if (coderTheme.isLoading) {
26+
return null
27+
}
4428

45-
"& .url": {
46-
color: colors.blue[6],
47-
},
48-
49-
"& .comment": {
50-
color: theme.palette.text.disabled,
51-
},
29+
if (hasDiff) {
30+
return (
31+
<DiffEditor original={value} modified={compareWith} {...commonProps} />
32+
)
33+
}
5234

53-
"& .title": {
54-
color: theme.palette.text.primary,
55-
fontWeight: 600,
56-
},
57-
},
58-
}))
35+
return <Editor value={value} {...commonProps} />
36+
}
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
import { Theme, useTheme } from "@material-ui/core/styles"
2+
import { useMonaco } from "@monaco-editor/react"
3+
import { useEffect, useState } from "react"
4+
import { hslToHex } from "util/colors"
5+
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- The theme is not typed
7+
export const coderTheme = (theme: Theme): Record<string, any> => ({
8+
base: "vs-dark",
9+
inherit: true,
10+
rules: [
11+
{
12+
background: "282a36",
13+
token: "",
14+
},
15+
{
16+
foreground: "6272a4",
17+
token: "comment",
18+
},
19+
{
20+
foreground: "f1fa8c",
21+
token: "string",
22+
},
23+
{
24+
foreground: "bd93f9",
25+
token: "constant.numeric",
26+
},
27+
{
28+
foreground: "bd93f9",
29+
token: "constant.language",
30+
},
31+
{
32+
foreground: "bd93f9",
33+
token: "constant.character",
34+
},
35+
{
36+
foreground: "bd93f9",
37+
token: "constant.other",
38+
},
39+
{
40+
foreground: "ffb86c",
41+
token: "variable.other.readwrite.instance",
42+
},
43+
{
44+
foreground: "ff79c6",
45+
token: "constant.character.escaped",
46+
},
47+
{
48+
foreground: "ff79c6",
49+
token: "constant.character.escape",
50+
},
51+
{
52+
foreground: "ff79c6",
53+
token: "string source",
54+
},
55+
{
56+
foreground: "ff79c6",
57+
token: "string source.ruby",
58+
},
59+
{
60+
foreground: "ff79c6",
61+
token: "keyword",
62+
},
63+
{
64+
foreground: "ff79c6",
65+
token: "storage",
66+
},
67+
{
68+
foreground: "8be9fd",
69+
fontStyle: "italic",
70+
token: "storage.type",
71+
},
72+
{
73+
foreground: "50fa7b",
74+
fontStyle: "underline",
75+
token: "entity.name.class",
76+
},
77+
{
78+
foreground: "50fa7b",
79+
fontStyle: "italic underline",
80+
token: "entity.other.inherited-class",
81+
},
82+
{
83+
foreground: "50fa7b",
84+
token: "entity.name.function",
85+
},
86+
{
87+
foreground: "ffb86c",
88+
fontStyle: "italic",
89+
token: "variable.parameter",
90+
},
91+
{
92+
foreground: "ff79c6",
93+
token: "entity.name.tag",
94+
},
95+
{
96+
foreground: "50fa7b",
97+
token: "entity.other.attribute-name",
98+
},
99+
{
100+
foreground: "8be9fd",
101+
token: "support.function",
102+
},
103+
{
104+
foreground: "6be5fd",
105+
token: "support.constant",
106+
},
107+
{
108+
foreground: "66d9ef",
109+
fontStyle: " italic",
110+
token: "support.type",
111+
},
112+
{
113+
foreground: "66d9ef",
114+
fontStyle: " italic",
115+
token: "support.class",
116+
},
117+
{
118+
foreground: "f8f8f0",
119+
background: "ff79c6",
120+
token: "invalid",
121+
},
122+
{
123+
foreground: "f8f8f0",
124+
background: "bd93f9",
125+
token: "invalid.deprecated",
126+
},
127+
{
128+
foreground: "cfcfc2",
129+
token: "meta.structure.dictionary.json string.quoted.double.json",
130+
},
131+
{
132+
foreground: "6272a4",
133+
token: "meta.diff",
134+
},
135+
{
136+
foreground: "6272a4",
137+
token: "meta.diff.header",
138+
},
139+
{
140+
foreground: "ff79c6",
141+
token: "markup.deleted",
142+
},
143+
{
144+
foreground: "50fa7b",
145+
token: "markup.inserted",
146+
},
147+
{
148+
foreground: "e6db74",
149+
token: "markup.changed",
150+
},
151+
{
152+
foreground: "bd93f9",
153+
token: "constant.numeric.line-number.find-in-files - match",
154+
},
155+
{
156+
foreground: "e6db74",
157+
token: "entity.name.filename",
158+
},
159+
{
160+
foreground: "f83333",
161+
token: "message.error",
162+
},
163+
{
164+
foreground: "eeeeee",
165+
token:
166+
"punctuation.definition.string.begin.json - meta.structure.dictionary.value.json",
167+
},
168+
{
169+
foreground: "eeeeee",
170+
token:
171+
"punctuation.definition.string.end.json - meta.structure.dictionary.value.json",
172+
},
173+
{
174+
foreground: "8be9fd",
175+
token: "meta.structure.dictionary.json string.quoted.double.json",
176+
},
177+
{
178+
foreground: "f1fa8c",
179+
token: "meta.structure.dictionary.value.json string.quoted.double.json",
180+
},
181+
{
182+
foreground: "50fa7b",
183+
token:
184+
"meta meta meta meta meta meta meta.structure.dictionary.value string",
185+
},
186+
{
187+
foreground: "ffb86c",
188+
token: "meta meta meta meta meta meta.structure.dictionary.value string",
189+
},
190+
{
191+
foreground: "ff79c6",
192+
token: "meta meta meta meta meta.structure.dictionary.value string",
193+
},
194+
{
195+
foreground: "bd93f9",
196+
token: "meta meta meta meta.structure.dictionary.value string",
197+
},
198+
{
199+
foreground: "50fa7b",
200+
token: "meta meta meta.structure.dictionary.value string",
201+
},
202+
{
203+
foreground: "ffb86c",
204+
token: "meta meta.structure.dictionary.value string",
205+
},
206+
],
207+
colors: {
208+
"editor.foreground": hslToHex(theme.palette.text.secondary),
209+
"editor.background": hslToHex(theme.palette.background.paper),
210+
"editor.selectionBackground": hslToHex(theme.palette.action.hover),
211+
"editor.lineHighlightBackground": hslToHex(
212+
theme.palette.background.paperLight,
213+
),
214+
"editorCursor.foreground": "#f8f8f0",
215+
"editorWhitespace.foreground": "#3B3A32",
216+
"editorIndentGuide.activeBackground": "#9D550FB0",
217+
"editor.selectionHighlightBorder": "#222218",
218+
},
219+
})
220+
221+
export const useCoderTheme = (): { isLoading: boolean; name: string } => {
222+
const [isLoading, setIsLoading] = useState(true)
223+
const monaco = useMonaco()
224+
const theme = useTheme<Theme>()
225+
const name = "coder"
226+
227+
useEffect(() => {
228+
if (monaco) {
229+
monaco.editor.defineTheme(name, coderTheme(theme))
230+
setIsLoading(false)
231+
}
232+
}, [monaco, theme])
233+
234+
return {
235+
isLoading,
236+
name,
237+
}
238+
}

0 commit comments

Comments
 (0)