61 lines
2.7 KiB
Vue
61 lines
2.7 KiB
Vue
<template>
|
|
<div class="flex flex-col h-full bg-white relative">
|
|
<div v-if="editor" class="border-b border-gray-100 px-8 py-2 flex gap-1 items-center sticky top-0 bg-white z-10 shadow-sm">
|
|
<button @click="editor.chain().focus().toggleBold().run()" :class="{ 'bg-gray-100 text-black': editor.isActive('bold') }" class="p-1.5 rounded hover:bg-gray-50 text-gray-600 font-bold transition-colors">B</button>
|
|
<button @click="editor.chain().focus().toggleItalic().run()" :class="{ 'bg-gray-100 text-black': editor.isActive('italic') }" class="p-1.5 rounded hover:bg-gray-50 text-gray-600 italic transition-colors">I</button>
|
|
|
|
<div class="w-px h-4 bg-gray-200 mx-2"></div>
|
|
|
|
<button @click="editor.chain().focus().toggleHeading({ level: 1 }).run()" :class="{ 'bg-gray-100 text-black': editor.isActive('heading', { level: 1 }) }" class="p-1.5 rounded hover:bg-gray-50 text-gray-600 font-bold text-sm">H1</button>
|
|
<button @click="editor.chain().focus().toggleHeading({ level: 2 }).run()" :class="{ 'bg-gray-100 text-black': editor.isActive('heading', { level: 2 }) }" class="p-1.5 rounded hover:bg-gray-50 text-gray-600 font-bold text-xs">H2</button>
|
|
|
|
<div class="w-px h-4 bg-gray-200 mx-2"></div>
|
|
|
|
<button @click="editor.chain().focus().toggleBulletList().run()" :class="{ 'bg-gray-100 text-black': editor.isActive('bulletList') }" class="p-1.5 rounded hover:bg-gray-50 text-gray-600 text-sm">Liste</button>
|
|
</div>
|
|
|
|
<editor-content :editor="editor" class="flex-1 overflow-y-auto px-8 py-6 prose prose-slate max-w-none focus:outline-none custom-editor-area" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useEditor, EditorContent } from '@tiptap/vue-3'
|
|
import StarterKit from '@tiptap/starter-kit'
|
|
import Placeholder from '@tiptap/extension-placeholder'
|
|
|
|
const props = defineProps<{ modelValue: any }>()
|
|
const emit = defineEmits(['update:modelValue'])
|
|
|
|
const editor = useEditor({
|
|
content: props.modelValue,
|
|
extensions: [
|
|
StarterKit,
|
|
Placeholder.configure({ placeholder: 'Schreibe etwas...' }),
|
|
],
|
|
editorProps: {
|
|
// Tailwind Klassen für den inneren Bereich (damit man überall hinklicken kann)
|
|
attributes: { class: 'focus:outline-none min-h-[500px] pb-20' },
|
|
},
|
|
onUpdate: ({ editor }) => {
|
|
emit('update:modelValue', editor.getJSON())
|
|
},
|
|
})
|
|
|
|
// Reactivity: Wenn Parent Daten ändert (z.B. Seitenwechsel), Editor updaten
|
|
watch(() => props.modelValue, (val) => {
|
|
if (editor.value && JSON.stringify(val) !== JSON.stringify(editor.value.getJSON())) {
|
|
editor.value.commands.setContent(val, false)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
/* Placeholder Grau */
|
|
.ProseMirror p.is-editor-empty:first-child::before {
|
|
color: #9ca3af;
|
|
content: attr(data-placeholder);
|
|
float: left;
|
|
height: 0;
|
|
pointer-events: none;
|
|
}
|
|
</style> |