antares/src/renderer/components/BaseTextEditor.vue

148 lines
3.3 KiB
Vue
Raw Normal View History

<template>
<div class="editor-wrapper">
<div
:id="`editor-${id}`"
class="editor"
:class="editorClass"
:style="{
height: `${height}px`,
width: width ? `${width}px` : null,
resize: resizable ? 'both' : 'none'
}"
/>
</div>
</template>
<script setup lang="ts">
/* eslint-disable simple-import-sort/imports */
import * as ace from 'ace-builds';
2022-04-30 11:45:49 +02:00
import 'ace-builds/webpack-resolver';
/* eslint-enable simple-import-sort/imports */
import { uidGen } from 'common/libs/uidGen';
import { storeToRefs } from 'pinia';
import { PropType, onMounted, watch } from 'vue';
2022-04-30 00:47:37 +02:00
import { useSettingsStore } from '@/stores/settings';
const props = defineProps({
modelValue: String,
mode: { type: String, default: 'text' },
editorClass: { type: String, default: '' },
resizable: { type: Boolean, default: false },
autoFocus: { type: Boolean, default: false },
readOnly: { type: Boolean, default: false },
showLineNumbers: { type: Boolean, default: true },
height: { type: Number, default: 200 },
width: { type: [Number, Boolean] as PropType<number|false>, default: false }
});
const emit = defineEmits(['update:modelValue']);
const settingsStore = useSettingsStore();
const {
editorTheme,
editorFontSize,
autoComplete,
lineWrap
} = storeToRefs(settingsStore);
let editor: ace.Ace.Editor;
const id = uidGen();
watch(() => props.mode, () => {
if (editor)
editor.session.setMode(`ace/mode/${props.mode}`);
});
watch(() => props.modelValue, () => {
if (editor && props.readOnly)
editor.session.setValue(props.modelValue);
});
watch(editorTheme, () => {
if (editor)
editor.setTheme(`ace/theme/${editorTheme.value}`);
});
watch(editorFontSize, () => {
const sizes = {
xsmall: '10px',
small: '12px',
medium: '14px',
large: '16px',
xlarge: '18px',
xxlarge: '20px'
};
if (editor) {
editor.setOptions({
fontSize: sizes[editorFontSize.value]
});
}
});
watch(autoComplete, () => {
if (editor) {
editor.setOptions({
enableLiveAutocompletion: autoComplete.value
});
}
});
watch(lineWrap, () => {
if (editor) {
editor.setOptions({
wrap: lineWrap.value
});
}
});
onMounted(() => {
editor = ace.edit(`editor-${id}`, {
mode: `ace/mode/${props.mode}`,
theme: `ace/theme/${editorTheme.value}`,
value: props.modelValue || '',
fontSize: 14,
printMargin: false,
readOnly: props.readOnly,
showLineNumbers: props.showLineNumbers,
showGutter: props.showLineNumbers
});
editor.setOptions({
enableBasicAutocompletion: false,
wrap: lineWrap,
enableSnippets: false,
enableLiveAutocompletion: false
});
(editor.session as unknown as ace.Ace.Editor).on('change', () => {
const content = editor.getValue();
emit('update:modelValue', content);
});
if (props.autoFocus) {
setTimeout(() => {
editor.focus();
editor.resize();
}, 20);
}
editor.commands.removeCommand('showSettingsMenu');
setTimeout(() => {
editor.resize();
}, 20);
});
</script>
<style lang="scss" scoped>
.editor-wrapper {
.editor {
width: 100%;
height: 100%;
max-width: 90vw;
}
}
</style>