Skip to content

Commit

Permalink
feat(editor): add monaco editor component
Browse files Browse the repository at this point in the history
  • Loading branch information
ysfscream committed Apr 1, 2021
1 parent 872b83b commit 9bf966f
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 3 deletions.
19 changes: 17 additions & 2 deletions example/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,17 @@
<emqx-key-value-editor ref="KeyValueEditorRef" v-model="kvTest"></emqx-key-value-editor>
</div>
<h2>Tags</h2>
<emqx-tags v-model="tagResult" :options="tagOptions"></emqx-tags>
<div class="show-item">
<emqx-tags v-model="tagResult" :options="tagOptions"></emqx-tags>
</div>
<h2>Tags Allow Add</h2>
<emqx-tags v-model="tagResult" allow-add :options="tagOptions" :request-to-add="fakeRequestToAddTag"></emqx-tags>
<div class="show-item">
<emqx-tags v-model="tagResult" allow-add :options="tagOptions" :request-to-add="fakeRequestToAddTag"></emqx-tags>
</div>
<h2>Editor</h2>
<div class="show-item">
<emqx-editor id="test" v-model="jsonValue" :lang="editorLang" :height="editorHeight"></emqx-editor>
</div>
</template>

<script lang="ts">
Expand Down Expand Up @@ -209,12 +217,16 @@ export default defineComponent({
const testTagsVal = ref(['test1'])
const testTagsOptions = ['test1', 'test2', 'test3']
const kvTest = ref({})
const jsonValue = ref(JSON.stringify({ messge: 'hello' }, null, 2))
const editorHeight = ref(200)
const editorLang = ref('json')
const test = () => {
console.log(testInput.value)
console.log(testSelect.value)
console.log(testSwitch.value)
console.log(testTagsVal.value)
console.log(kvTest.value)
console.log(jsonValue.value)
}
const onSubmit = () => {
console.log(testForm.value)
Expand Down Expand Up @@ -266,6 +278,9 @@ export default defineComponent({
tagResult,
tagOptions,
fakeRequestToAddTag,
jsonValue,
editorHeight,
editorLang,
}
},
})
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
},
"dependencies": {
"core-js": "^3.6.5",
"element-plus": "^1.0.2-beta.35"
"element-plus": "^1.0.2-beta.35",
"monaco-editor": "^0.23.0"
},
"peerDependencies": {
"vue": "^3.0.0"
Expand All @@ -47,6 +48,7 @@
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-0",
"lint-staged": "^9.5.0",
"monaco-editor-webpack-plugin": "^3.0.1",
"node-sass": "^4.12.0",
"prettier": "^1.19.1",
"sass-loader": "^8.0.2",
Expand Down
71 changes: 71 additions & 0 deletions packages/Editor/composables/useEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { onMounted, Ref, ToRefs, ref, onBeforeUnmount, watch } from 'vue'
import * as Monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { CustomMonacoOption } from '../types/editor'

const getMonacoOptions = (options: ToRefs<CustomMonacoOption>): Monaco.editor.IStandaloneEditorConstructionOptions => {
const defaultOptions: Monaco.editor.IStandaloneEditorConstructionOptions = {
value: options.value.value,
language: options.lang.value,
readOnly: options.disabled.value,
wordWrap: options.wordWrap.value,
lineHeight: options.lineHeight.value,
fontSize: options.fontSize.value,
scrollBeyondLastLine: false,
lineNumbers: options.lineNumbers.value,
renderLineHighlight: options.renderLineHighlight.value,
matchBrackets: 'near',
folding: false,
lightbulb: {
enabled: false,
},
minimap: {
enabled: false,
},
scrollbar: {
horizontal: options.scrollbarStatus.value,
vertical: options.scrollbarStatus.value,
useShadows: true,
alwaysConsumeMouseWheel: false,
},
smoothScrolling: true,
// theme: editorTheme || getTheme(),
}
return defaultOptions
}

export default function useEditor(id: Ref<string>, refOptions: ToRefs<CustomMonacoOption>) {
const elementId = `monaco-${id.value}`
let editor: Monaco.editor.IStandaloneCodeEditor | null = null
let subscriber: Monaco.IDisposable | null = null
const value: Ref<string | undefined> = ref('')
const initEditor = () => {
const editorElement = document.getElementById(elementId)
if (editorElement) {
const defaultOptions = getMonacoOptions(refOptions)
editor = Monaco.editor.create(editorElement, defaultOptions)
subscriber = editor.onDidChangeModelContent(() => {
value.value = editor?.getValue()
})
}
}
const resetEditor = () => {
subscriber?.dispose()
editor?.getModel()?.dispose()
editor?.dispose()
editor = null
}
window.onresize = () => {
editor?.layout()
}
watch(refOptions.lang, () => {
resetEditor()
initEditor()
})
onMounted(initEditor)
onBeforeUnmount(() => {
resetEditor()
})
return {
value,
}
}
8 changes: 8 additions & 0 deletions packages/Editor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { App } from 'vue'
import Editor from './src/editor.vue'

Editor.install = (Vue: App): void => {
Vue.component(Editor.name, Editor)
}

export default Editor
86 changes: 86 additions & 0 deletions packages/Editor/src/editor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<div class="emqx-editor" :style="{ height: editorHeight }">
<div :id="`monaco-${id}`" class="emqx-editor-view"></div>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, ToRefs, toRefs, watch } from 'vue'
import useEditor from '../composables/useEditor'
import { Lang, Switch, renderLineHighlight, ScrollBarStatus, CustomMonacoOption } from '../types/editor'
export default defineComponent({
name: 'EmqxEditor',
props: {
id: {
required: true,
type: String,
},
height: {
type: Number,
default: 300,
},
modelValue: {
required: true,
type: String,
},
lang: {
required: true,
type: String as PropType<Lang>,
},
fontSize: {
type: Number,
default: 14,
},
lineNumbers: {
type: String as PropType<Switch>,
default: 'on',
},
renderLineHighlight: {
type: String as PropType<renderLineHighlight>,
default: 'line',
},
scrollbarStatus: {
type: String as PropType<ScrollBarStatus>,
default: 'visible',
},
disabled: {
type: Boolean,
default: false,
},
wordWrap: {
type: String as PropType<Switch>,
default: 'off',
},
lineHeight: {
type: Number,
default: undefined,
},
},
setup(props, ctx) {
const { id, height, modelValue, ...others } = toRefs(props)
const option: ToRefs<CustomMonacoOption> = { value: modelValue, ...others }
const editorHeight = computed(() => {
return `${height.value}px`
})
const { value } = useEditor(id, option)
watch(value, val => {
ctx.emit('update:modelValue', val)
})
return {
editorHeight,
}
},
})
</script>

<style lang="scss">
.emqx-editor {
border: 1px solid #d7dae1;
}
.emqx-editor-view {
height: 100%;
width: 100%;
position: relative;
}
</style>
21 changes: 21 additions & 0 deletions packages/Editor/types/editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export type Lang = 'json' | 'sql'

export type Switch = 'on' | 'off'

export type renderLineHighlight = 'none' | 'line' | 'gutter' | 'all' | undefined

export type ScrollBarStatus = 'auto' | 'visible' | 'hidden' | undefined

export interface CustomMonacoOption {
value: string
lang: Lang
fontSize: number
lineNumbers: Switch
renderLineHighlight: renderLineHighlight
scrollbarStatus: ScrollBarStatus
disabled: boolean
wordWrap: Switch
lineHeight: number
}

export default {}
3 changes: 3 additions & 0 deletions packages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import BreadcrumbItem from './BreadcrumbItem'
import Upload from './Upload'
import Tags from './Tags'
import KeyValueEditor from './KeyValueEditor'
import Editor from './Editor'
import Loading from './Loading'
import './style/global.scss'

Expand Down Expand Up @@ -68,6 +69,7 @@ const components = [
Upload,
Tags,
KeyValueEditor,
Editor,
]

const plugins = [Loading]
Expand Down Expand Up @@ -114,6 +116,7 @@ const packages = {
Upload,
Tags,
KeyValueEditor,
Editor,
}

export default packages
14 changes: 14 additions & 0 deletions vue.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')

module.exports = {
lintOnSave: false,
devServer: {
port: 6800,
},
pages: {
index: {
entry: 'example/main.ts',
Expand All @@ -18,4 +24,12 @@ module.exports = {
return options
})
},
configureWebpack: {
plugins: [
new MonacoWebpackPlugin({
output: 'static/',
languages: ['json', 'sql'],
}),
],
},
}
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6375,6 +6375,18 @@ mixin-deep@^1.2.0:
dependencies:
minimist "^1.2.5"

monaco-editor-webpack-plugin@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-3.0.1.tgz#b9bf93314eb2708907c232cfbf359622e7a6d98a"
integrity sha512-Hym4HqWgIpyoi9G0spln/b/7rkDKfYwIOrNzo1fHHMc+MLYSwD1JXHwKSDS77X27ZHfVJsEXbMZYdGhSYuVF0w==
dependencies:
loader-utils "^2.0.0"

monaco-editor@^0.23.0:
version "0.23.0"
resolved "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.23.0.tgz#24844ba5640c7adb3a2a3ff3b520cf2d7170a6f0"
integrity sha512-q+CP5zMR/aFiMTE9QlIavGyGicKnG2v/H8qVvybLzeFsARM8f6G9fL0sMST2tyVYCwDKkGamZUI6647A0jR/Lg==

move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
Expand Down

0 comments on commit 9bf966f

Please sign in to comment.