Web component based on Monaco Editor. Support Vue and React.
[npm|yarn|pnpm] install monaco-editor-component
OR
bun install monaco-editor-component
You can see the demo details.
// App.tsx
import { useState } from 'react'
import { MonacoDiffEditor, MonacoEditor } from 'monaco-editor-component/react'
import { createRoot } from 'react-dom/client'
// main.tsx
/**
*
*/
function App() {
const [code, setCode] = useState('console.log("Hello World")')
return (
<div>
<MonacoEditor language="javascript" value={code} width="300" height="500" onChange={value => setCode(value)} />
<MonacoDiffEditor language="javascript" originalValue="const a = 123;" value={code} onChange={value => setCode(value)} />
</div>
)
}
const app = document.getElementById('root')
createRoot(app).render(<App />)
You can see the demo details.
// App.vue
<script setup lang="ts">
import { ref } from 'vue'
import { MonacoEditor, MonacoDiffEditor } from 'monaco-editor-component/vue'
const input = ref('const a = 12356;')
</script>
<template>
<div>
<MonacoEditor v-model:value="input" language='javascript' width='300' height='500' />
<MonacoDiffEditor language='javascript' originalValue='const a = 123;' v-model:value='input' />
</div>
</template>
// main.ts
import App from './App.vue'
const app = document.getElementById('root')
createApp(app).render(<App />)
Name | Type | Default | Description |
---|---|---|---|
language | string | javascript | The language of the editor. |
value | string | null | The value of the auto created model in the editor. |
defaultValue | string | "" | The default value of the auto created model in the editor. |
theme | string | vs-dark | The theme of the editor. |
options | MonacoEditorOptions | {} | The options of the editor. |
onChange | (value: string, e: monaco.editor.IModelContentChangedEvent) => void | noop | An event emitted when the content of the current model has changed. |
width | string | number | 100% | The width of the editor. |
height | string | number | 100% | The height of the editor. |
className | string | "" | The class name of the editor. |
style | React.CSSProperties | {} | The style of the editor. |
onEditorDidMount | (editor: MonacoCodeEditor, monaco: Monaco) => void | noop | An event emitted when the editor has been mounted (similar to componentDidMount of React). |
onEditorWillMount | (monaco: Monaco) => void | noop | An event emitted before the editor mounted (similar to componentWillMount of React). |
onEditorWillUnmount | (editor: MonacoCodeEditor, monaco: Monaco) => void | noop | An event emitted when the editor will unmount (similar to componentWillUnmount of React). |
modelUri | (monaco: Monaco) => monaco.Uri | undefined | The uri of the model. |
For more options see monaco-editor
MonacoDiffEditor is a diff editor.
MonacoDiffEditor extends MonacoEditor, so it has all the props of MonacoEditor but excludes the modelUri
prop.
Name | Type | Default | Description |
---|---|---|---|
originalValue | string | "" | The original value of the auto created model in the editor, is a base value. |
originalUri | (monaco: Monaco) => monaco.Uri | undefined | The uri of the original model. |
modifiedUri | (monaco: Monaco) => monaco.Uri | undefined | The uri of the modified model. |
value | string | null | The modified value of the auto created model in the editor, is a modified value. |
// react
import { useRef } from 'react'
import type { MonacoEditorRef } from 'monaco-editor-component'
const editorRef = useRef<MonacoEditorRef>(null)
// vue
import { ref } from 'vue'
const monacoEditor = ref<MonacoCodeEditor | null>(null)
const updateMonacoEditor = (editor: MonacoCodeEditor, monaco: Monaco) => {
monacoEditor.value = editor
}
<template>
<MonacoEditor v-model:value="input" :onEditorDidMount="updateMonacoEditor" />
</template>
// usage
const model = editorRef.current.editor.current.getModel()
OR
const model = monacoEditor.value.getModel()
For Vite, you only need to implement the getWorker
function (NOT the getWorkerUrl
) to use Vite's output.
Others like Webpack see monaco-editor worker
// Vite
// worker.ts file
import * as monaco from 'monaco-editor'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
// App.tsx
import { MonacoEditor } from 'monaco-editor-component/react'
import './worker'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
self.MonacoEnvironment = {
getWorker(_: unknown, label: string) {
if (label === 'json')
return new jsonWorker()
if (label === 'css' || label === 'scss' || label === 'less')
return new cssWorker()
if (label === 'html' || label === 'handlebars' || label === 'razor')
return new htmlWorker()
if (label === 'typescript' || label === 'javascript')
return new tsWorker()
return new editorWorker()
},
}
// usage of MonacoEditor...
Vue usage is similar to React (when you use Vite).
MIT License
Copyright (c) 2023 Yugang Cao, see the LICENSE details.