dashboard/shell/components/CodeMirror.vue

125 lines
2.4 KiB
Vue

<script>
import { KEYMAP } from '@shell/store/prefs';
export default {
name: 'CodeMirror',
props: {
value: {
type: String,
required: true,
},
options: {
type: Object,
default: () => {}
}
},
data() {
return { loaded: false };
},
computed: {
combinedOptions() {
const theme = this.$store.getters['prefs/theme'];
const keymap = this.$store.getters['prefs/get'](KEYMAP);
const out = {
// codemirror default options
tabSize: 2,
indentWithTabs: false,
mode: 'yaml',
keyMap: keymap,
theme: `base16-${ theme }`,
lineNumbers: true,
line: true,
styleActiveLine: true,
lineWrapping: true,
foldGutter: true,
styleSelectedText: true,
showCursorWhenSelecting: true,
};
Object.assign(out, this.options);
return out;
},
},
created() {
if (window.__codeMirrorLoader) {
window.__codeMirrorLoader().then(() => {
this.loaded = true;
});
} else {
console.error('Code mirror loader not available'); // eslint-disable-line no-console
}
},
methods: {
focus() {
if ( this.$refs.cm ) {
this.$refs.cm.codemirror.focus();
}
},
refresh() {
if ( this.$refs.cm ) {
this.$refs.cm.refresh();
}
},
onReady(cm) {
this.$nextTick(() => {
cm.refresh();
});
this.$emit('onReady', cm);
},
onInput(newCode) {
this.$emit('onInput', newCode);
},
onChanges(cm, changes) {
this.$emit('onChanges', cm, changes);
},
updateValue(value) {
if ( this.$refs.cm ) {
this.$refs.cm.codemirror.doc.setValue(value);
}
}
}
};
</script>
<template>
<client-only placeholder=" Loading...">
<div class="code-mirror">
<codemirror
v-if="loaded"
ref="cm"
:value="value"
:options="combinedOptions"
@ready="onReady"
@input="onInput"
@changes="onChanges"
/>
<div v-else>
Loading...
</div>
</div>
</client-only>
</template>
<style lang="scss">
.code-mirror {
z-index: 0;
.vue-codemirror .CodeMirror {
height: initial;
background: none
}
}
</style>