aboutsummaryrefslogtreecommitdiff
path: root/src/tools/html-wysiwyg-editor/editor/editor.vue
diff options
context:
space:
mode:
authorGravatar Corentin Thomasset <corentin.thomasset74@gmail.com> 2023-03-26 19:04:42 +0200
committerGravatar Corentin THOMASSET <corentin.thomasset74@gmail.com> 2023-03-26 20:21:00 +0200
commitf3b1863f093124309963c3ad7c275142cd370b0f (patch)
treec8dd861e9d5d253bcb655c2c055965fae7f952c5 /src/tools/html-wysiwyg-editor/editor/editor.vue
parentb1d6bfd2dcb718b486dcd708adcdea65341b3d16 (diff)
downloadit-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.vue135
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>