Skip to content

Commit 7ac4b95

Browse files
authored
feat(repl): getEditorInstance, getMonacoEditor (expose) (#364)
1 parent e517abb commit 7ac4b95

File tree

7 files changed

+66
-8
lines changed

7 files changed

+66
-8
lines changed

src/Repl.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { type Store, useStore } from './store'
55
import { computed, provide, toRefs, useTemplateRef } from 'vue'
66
import {
77
type EditorComponentType,
8+
type EditorMethods,
89
injectKeyPreviewRef,
910
injectKeyProps,
1011
} from './types'
@@ -73,6 +74,7 @@ if (!props.editor) {
7374
}
7475
7576
const outputRef = useTemplateRef('output')
77+
const editorContainerRef = useTemplateRef('editorContainer')
7678
7779
props.store.init()
7880
@@ -95,14 +97,19 @@ function reload() {
9597
outputRef.value?.reload()
9698
}
9799
98-
defineExpose({ reload })
100+
defineExpose({
101+
reload,
102+
getEditorInstance: (() =>
103+
editorContainerRef.value?.getEditorIns()) as EditorMethods['getEditorIns'],
104+
getMonacoEditor: () => editorContainerRef.value?.getMonacoEditor?.(),
105+
})
99106
</script>
100107

101108
<template>
102109
<div class="vue-repl">
103110
<SplitPane :layout="layout">
104111
<template #[editorSlotName]>
105-
<EditorContainer :editor-component="editor" />
112+
<EditorContainer ref="editorContainer" :editor-component="editor" />
106113
</template>
107114
<template #[outputSlotName]>
108115
<Output

src/codemirror/CodeMirror.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ onMounted(() => {
9999
{ immediate: true },
100100
)
101101
})
102+
103+
defineExpose({
104+
getEditorIns: () => editor,
105+
})
102106
</script>
103107

104108
<style>

src/editor/CodeMirrorEditor.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import CodeMirror, { type Props } from '../codemirror/CodeMirror.vue'
3-
import { computed } from 'vue'
4-
import type { EditorEmits, EditorProps } from '../types'
3+
import { computed, useTemplateRef } from 'vue'
4+
import type { EditorEmits, EditorMethods, EditorProps } from '../types'
55
66
defineOptions({
77
editorType: 'codemirror',
@@ -10,6 +10,8 @@ defineOptions({
1010
const props = defineProps<EditorProps>()
1111
const emit = defineEmits<EditorEmits>()
1212
13+
const codeMirrorRef = useTemplateRef('codeMirror')
14+
1315
const onChange = (code: string) => {
1416
emit('change', code)
1517
}
@@ -36,10 +38,16 @@ const activeMode = computed(() => {
3638
const mode = modes[forcedMode || filename.split('.').pop()!]
3739
return filename.lastIndexOf('.') !== -1 && mode ? mode : modes.js
3840
})
41+
42+
defineExpose({
43+
getEditorIns: (() =>
44+
codeMirrorRef.value?.getEditorIns()) as EditorMethods['getEditorIns'],
45+
})
3946
</script>
4047

4148
<template>
4249
<CodeMirror
50+
ref="codeMirror"
4351
:value="value"
4452
:mode="activeMode"
4553
:readonly="readonly"

src/editor/EditorContainer.vue

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
import FileSelector from './FileSelector.vue'
33
import Message from '../Message.vue'
44
import { debounce } from '../utils'
5-
import { inject, ref, watch } from 'vue'
5+
import { inject, ref, useTemplateRef, watch } from 'vue'
66
import ToggleButton from './ToggleButton.vue'
7-
import { type EditorComponentType, injectKeyProps } from '../types'
7+
import {
8+
type EditorComponentType,
9+
type EditorMethods,
10+
injectKeyProps,
11+
} from '../types'
812
913
const SHOW_ERROR_KEY = 'repl_show_error'
1014
@@ -14,6 +18,7 @@ const props = defineProps<{
1418
1519
const { store, autoSave, editorOptions } = inject(injectKeyProps)!
1620
const showMessage = ref(getItem())
21+
const editorRef = useTemplateRef<EditorMethods>('editor')
1722
1823
const onChange = debounce((code: string) => {
1924
store.value.activeFile.code = code
@@ -25,18 +30,25 @@ function setItem() {
2530
2631
function getItem() {
2732
const item = localStorage.getItem(SHOW_ERROR_KEY)
28-
return !(item === 'false')
33+
return item !== 'false'
2934
}
3035
3136
watch(showMessage, () => {
3237
setItem()
3338
})
39+
40+
defineExpose({
41+
getEditorIns: (() =>
42+
editorRef.value?.getEditorIns?.()) as EditorMethods['getEditorIns'],
43+
getMonacoEditor: () => editorRef.value?.getMonacoEditor?.(),
44+
})
3445
</script>
3546

3647
<template>
3748
<FileSelector />
3849
<div class="editor-container">
3950
<props.editorComponent
51+
ref="editor"
4052
:value="store.activeFile.code"
4153
:filename="store.activeFile.filename"
4254
@change="onChange"

src/editor/MonacoEditor.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import Monaco from '../monaco/Monaco.vue'
3-
import type { EditorEmits, EditorProps } from '../types'
3+
import type { EditorEmits, EditorMethods, EditorProps } from '../types'
4+
import { useTemplateRef } from 'vue'
45
56
defineProps<EditorProps>()
67
const emit = defineEmits<EditorEmits>()
@@ -9,13 +10,22 @@ defineOptions({
910
editorType: 'monaco',
1011
})
1112
13+
const monacoRef = useTemplateRef('monaco')
14+
1215
const onChange = (code: string) => {
1316
emit('change', code)
1417
}
18+
19+
defineExpose({
20+
getEditorIns: (() =>
21+
monacoRef.value?.getEditorIns()) as EditorMethods['getEditorIns'],
22+
getMonacoEditor: () => monacoRef.value?.getMonacoEditor(),
23+
})
1524
</script>
1625

1726
<template>
1827
<Monaco
28+
ref="monaco"
1929
:filename="filename"
2030
:value="value"
2131
:readonly="readonly"

src/monaco/Monaco.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ onMounted(() => {
169169
onBeforeUnmount(() => {
170170
editor.value?.dispose()
171171
})
172+
173+
defineExpose({
174+
getEditorIns: () => editor.value,
175+
getMonacoEditor: () => monaco.editor,
176+
})
172177
</script>
173178

174179
<template>

src/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { Component, ComputedRef, InjectionKey, ToRefs } from 'vue'
22
import { Props } from './Repl.vue'
3+
import type * as monaco from 'monaco-editor-core'
4+
import type CodeMirror from 'codemirror'
35

46
export type EditorMode = 'js' | 'css' | 'ssr'
57
export interface EditorProps {
@@ -11,6 +13,16 @@ export interface EditorProps {
1113
export interface EditorEmits {
1214
(e: 'change', code: string): void
1315
}
16+
17+
export interface EditorMethods {
18+
getEditorIns<T extends 'monaco' | 'codemirror' = 'monaco'>():
19+
| (T extends 'codemirror'
20+
? CodeMirror.Editor
21+
: monaco.editor.IStandaloneCodeEditor)
22+
| undefined
23+
getMonacoEditor?(): typeof monaco.editor | undefined
24+
}
25+
1426
export type EditorComponentType = Component<EditorProps>
1527

1628
export type OutputModes = 'preview' | 'ssr output' | EditorMode

0 commit comments

Comments
 (0)