Feat(CodeEditor): Support jsx highlight
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { editor, IPosition, Selection } from 'monaco-editor'
|
||||
import ScrollType = editor.ScrollType
|
||||
import { Monaco } from '@monaco-editor/react'
|
||||
import { getWorker, MonacoJsxSyntaxHighlight } from 'monaco-jsx-syntax-highlight'
|
||||
import { createATA, TypeHelper } from '@/components/Playground/CodeEditor/Editor/ata'
|
||||
|
||||
export const useEditor = () => {
|
||||
@@ -28,18 +27,6 @@ export const useEditor = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const loadJsxSyntaxHighlight = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => {
|
||||
const monacoJsxSyntaxHighlight = new MonacoJsxSyntaxHighlight(getWorker(), monaco)
|
||||
const { highlighter, dispose } = monacoJsxSyntaxHighlight.highlighterBuilder({ editor })
|
||||
|
||||
editor.onDidChangeModelContent(() => {
|
||||
highlighter()
|
||||
})
|
||||
highlighter()
|
||||
|
||||
return { highlighter, dispose }
|
||||
}
|
||||
|
||||
const autoLoadExtraLib = async (
|
||||
editor: editor.IStandaloneCodeEditor,
|
||||
monaco: Monaco,
|
||||
@@ -68,7 +55,6 @@ export const useEditor = () => {
|
||||
|
||||
return {
|
||||
doOpenEditor,
|
||||
loadJsxSyntaxHighlight,
|
||||
autoLoadExtraLib
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,27 +13,7 @@ const rotate = keyframes`
|
||||
export default createStyles(() => ({
|
||||
root: {
|
||||
position: 'relative',
|
||||
height: 0,
|
||||
|
||||
'.monaco-editor-light': {
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: 'var(--border)',
|
||||
'.jsx-tag-angle-bracket': { color: '#800000' },
|
||||
'.jsx-text': { color: '#000' },
|
||||
'.jsx-tag-name': { color: '#800000' },
|
||||
'.jsx-tag-attribute-key': { color: '#f00' }
|
||||
},
|
||||
|
||||
'.monaco-editor-dark': {
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: 'var(--border)',
|
||||
'.jsx-tag-angle-bracket': { color: '#808080' },
|
||||
'.jsx-text': { color: '#d4d4d4' },
|
||||
'.jsx-tag-name': { color: '#569cd6' },
|
||||
'.jsx-tag-attribute-key': { color: '#9cdcfe' }
|
||||
}
|
||||
height: 0
|
||||
},
|
||||
|
||||
loading: {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { editor, Selection } from 'monaco-editor'
|
||||
import MonacoEditor, { Monaco } from '@monaco-editor/react'
|
||||
import { shikiToMonaco } from '@shikijs/monaco'
|
||||
import { createHighlighter } from 'shiki'
|
||||
import useStyles from '@/components/Playground/CodeEditor/Editor/index.style'
|
||||
import '@/components/Playground/CodeEditor/Editor/loader'
|
||||
import { IEditorOptions, IFiles, ITsconfig } from '@/components/Playground/shared'
|
||||
@@ -38,18 +40,19 @@ const Editor = ({
|
||||
const { styles } = useStyles()
|
||||
const editorRef = useRef<editor.IStandaloneCodeEditor>()
|
||||
const monacoRef = useRef<Monaco>()
|
||||
const { doOpenEditor, loadJsxSyntaxHighlight, autoLoadExtraLib } = useEditor()
|
||||
const jsxSyntaxHighlightRef = useRef<{
|
||||
highlighter: (code?: string | undefined) => void
|
||||
dispose: () => void
|
||||
}>({
|
||||
highlighter: () => undefined,
|
||||
dispose: () => undefined
|
||||
})
|
||||
const { doOpenEditor, autoLoadExtraLib } = useEditor()
|
||||
const { total, finished, onWatch } = useTypesProgress()
|
||||
const file = files[selectedFileName] || { name: 'Untitled' }
|
||||
|
||||
const handleOnEditorWillMount = (monaco: Monaco) => {
|
||||
createHighlighter({
|
||||
themes: ['vitesse-light', 'vitesse-dark'],
|
||||
langs: ['javascript', 'jsx', 'typescript', 'tsx', 'css', 'json', 'xml']
|
||||
}).then((highlighter) => {
|
||||
shikiToMonaco(highlighter, monaco)
|
||||
monaco.editor.setTheme(isDarkMode ? 'vitesse-dark' : 'vitesse-light')
|
||||
})
|
||||
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions(tsconfigJsonDiagnosticsOptions)
|
||||
tsconfig &&
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(
|
||||
@@ -78,8 +81,6 @@ const Editor = ({
|
||||
|
||||
monacoRef.current = monaco
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
editor['_codeEditorService'].doOpenEditor = function (
|
||||
editor: editor.IStandaloneCodeEditor,
|
||||
input: { options: { selection: Selection }; resource: { path: string } }
|
||||
@@ -91,7 +92,6 @@ const Editor = ({
|
||||
}
|
||||
}
|
||||
|
||||
jsxSyntaxHighlightRef.current = loadJsxSyntaxHighlight(editor, monaco)
|
||||
extraLibs.forEach((item) =>
|
||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(item.content, item.path)
|
||||
)
|
||||
@@ -99,9 +99,12 @@ const Editor = ({
|
||||
void autoLoadExtraLib(editor, monaco, file.value, onWatch)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
monacoRef.current?.editor.setTheme(isDarkMode ? 'vitesse-dark' : 'vitesse-light')
|
||||
}, [isDarkMode])
|
||||
|
||||
useEffect(() => {
|
||||
editorRef.current?.focus()
|
||||
jsxSyntaxHighlightRef?.current?.highlighter?.()
|
||||
}, [file.name])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -115,9 +118,8 @@ const Editor = ({
|
||||
<>
|
||||
<div className={styles.root}>
|
||||
<MonacoEditor
|
||||
theme={isDarkMode ? 'vs-dark' : 'light'}
|
||||
theme={isDarkMode ? 'vitesse-dark' : 'vitesse-light'}
|
||||
path={file.name}
|
||||
className={`monaco-editor-${isDarkMode ? 'dark' : 'light'}`}
|
||||
language={file.language}
|
||||
value={file.value}
|
||||
onChange={onChange}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import MonacoEditor from '@monaco-editor/react'
|
||||
import { Loader } from 'esbuild-wasm'
|
||||
import useStyles from '@/components/Playground/Output/Transform/index.style'
|
||||
import { IFile, ITheme } from '@/components/Playground/shared'
|
||||
import { IFile } from '@/components/Playground/shared'
|
||||
import { cssToJsFromFile, jsonToJsFromFile } from '@/components/Playground/files'
|
||||
import Compiler from '@/components/Playground/compiler'
|
||||
import { MonacoEditorConfig } from '@/components/Playground/CodeEditor/Editor/monacoConfig'
|
||||
|
||||
interface OutputProps {
|
||||
isDarkMode?: boolean
|
||||
file: IFile
|
||||
theme?: ITheme
|
||||
}
|
||||
|
||||
const Transform = ({ file, theme }: OutputProps) => {
|
||||
const Transform = ({ isDarkMode, file }: OutputProps) => {
|
||||
const { styles } = useStyles()
|
||||
const [compiledCode, setCompiledCode] = useState('')
|
||||
const [errorMsg, setErrorMsg] = useState('')
|
||||
@@ -60,7 +60,7 @@ const Transform = ({ file, theme }: OutputProps) => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<MonacoEditor
|
||||
theme={theme}
|
||||
theme={isDarkMode ? 'vitesse-dark' : 'vitesse-light'}
|
||||
language={'javascript'}
|
||||
value={compiledCode}
|
||||
options={{ ...MonacoEditorConfig, readOnly: true }}
|
||||
|
||||
@@ -5,6 +5,7 @@ import Transform from '@/components/Playground/Output/Transform'
|
||||
import Preview from '@/components/Playground/Output/Preview'
|
||||
|
||||
interface OutputProps {
|
||||
isDarkMode?: boolean
|
||||
files: IFiles
|
||||
selectedFileName: string
|
||||
importMap: IImportMap
|
||||
@@ -15,6 +16,7 @@ interface OutputProps {
|
||||
}
|
||||
|
||||
const Output = ({
|
||||
isDarkMode,
|
||||
files,
|
||||
selectedFileName,
|
||||
importMap,
|
||||
@@ -47,7 +49,9 @@ const Output = ({
|
||||
mobileMode={mobileMode}
|
||||
/>
|
||||
)}
|
||||
{selectedTab === 'Transform' && <Transform file={files[selectedFileName]} />}
|
||||
{selectedTab === 'Transform' && (
|
||||
<Transform isDarkMode={isDarkMode} file={files[selectedFileName]} />
|
||||
)}
|
||||
</FlexBox>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ const Playground = ({
|
||||
onSelectedFileChange={setSelectedFileName}
|
||||
/>
|
||||
<Output
|
||||
isDarkMode={isDarkMode}
|
||||
files={files}
|
||||
selectedFileName={selectedFileName}
|
||||
importMap={importMap!}
|
||||
|
||||
@@ -20,6 +20,4 @@ export interface ITsconfig {
|
||||
compilerOptions: CompilerOptions
|
||||
}
|
||||
|
||||
export type ITheme = 'light' | 'vs-dark'
|
||||
|
||||
export type IEditorOptions = editor.IStandaloneEditorConstructionOptions
|
||||
|
||||
@@ -459,6 +459,7 @@ const Edit = () => {
|
||||
extraLibs={editorExtraLibs}
|
||||
/>
|
||||
<Playground.Output
|
||||
isDarkMode={isDarkMode}
|
||||
files={files}
|
||||
selectedFileName={selectedFileName}
|
||||
importMap={importMap!}
|
||||
|
||||
Reference in New Issue
Block a user