diff options
author | 2023-03-26 19:04:42 +0200 | |
---|---|---|
committer | 2023-03-26 20:21:00 +0200 | |
commit | f3b1863f093124309963c3ad7c275142cd370b0f (patch) | |
tree | c8dd861e9d5d253bcb655c2c055965fae7f952c5 /src/tools/html-wysiwyg-editor/editor/editor.vue | |
parent | b1d6bfd2dcb718b486dcd708adcdea65341b3d16 (diff) | |
download | it-tools-f3b1863f093124309963c3ad7c275142cd370b0f.tar.gz it-tools-f3b1863f093124309963c3ad7c275142cd370b0f.tar.zst it-tools-f3b1863f093124309963c3ad7c275142cd370b0f.zip |
feat(new-tool): html wysiwyg editor
Diffstat (limited to 'src/tools/html-wysiwyg-editor/editor/editor.vue')
-rw-r--r-- | src/tools/html-wysiwyg-editor/editor/editor.vue | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/tools/html-wysiwyg-editor/editor/editor.vue b/src/tools/html-wysiwyg-editor/editor/editor.vue new file mode 100644 index 0000000..346cb10 --- /dev/null +++ b/src/tools/html-wysiwyg-editor/editor/editor.vue @@ -0,0 +1,135 @@ +<template> + <n-card v-if="editor" class="editor"> + <template #header> + <menu-bar class="editor-header" :editor="editor" /> + <n-divider style="margin-top: 0" /> + </template> + + <editor-content class="editor-content" :editor="editor" /> + </n-card> +</template> + +<script setup lang="ts"> +import { tryOnBeforeUnmount, useVModel } from '@vueuse/core'; +import { Editor, EditorContent } from '@tiptap/vue-3'; +import StarterKit from '@tiptap/starter-kit'; +import { useThemeVars } from 'naive-ui'; +import MenuBar from './menu-bar.vue'; + +const themeVars = useThemeVars(); +const props = defineProps<{ html: string }>(); +const emit = defineEmits(['update:html']); +const html = useVModel(props, 'html', emit); + +const editor = new Editor({ + content: html.value, + extensions: [StarterKit], +}); + +editor.on('update', ({ editor }) => emit('update:html', editor.getHTML())); + +tryOnBeforeUnmount(() => { + editor.destroy(); +}); +</script> + +<style scoped lang="less"> +::v-deep(.n-card-header) { + padding: 0; +} + +::v-deep(.ProseMirror-focused) { + outline: none; +} +</style> + +<style scoped lang="less"> +::v-deep(.ProseMirror) { + > * + * { + margin-top: 0.75em; + } + + p { + margin: 0; + } + + ul, + ol { + padding: 0 1rem; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + line-height: 1.1; + } + + code { + background-color: v-bind('themeVars.codeColor'); + padding: 2px 4px; + border-radius: 5px; + font-size: 85%; + } + + pre { + background: v-bind('themeVars.codeColor'); + font-family: monospace; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + + code { + color: inherit; + padding: 0; + background: none; + font-size: 0.8rem; + } + } + + mark { + background-color: #faf594; + } + + img { + max-width: 100%; + height: auto; + } + + hr { + margin: 1rem 0; + } + + blockquote { + padding-left: 1rem; + border-left: 2px solid rgba(#0d0d0d, 0.1); + } + + hr { + border: none; + border-top: 2px solid rgba(#0d0d0d, 0.1); + margin: 2rem 0; + } + + ul[data-type='taskList'] { + list-style: none; + padding: 0; + + li { + display: flex; + align-items: center; + + > label { + flex: 0 0 auto; + margin-right: 0.5rem; + user-select: none; + } + + > div { + flex: 1 1 auto; + } + } + } +} +</style> |