2024-08-18 17:23:18 +03:00
|
|
|
<script>
|
|
|
|
|
import {onDestroy, onMount} from 'svelte';
|
|
|
|
|
import {Editor} from '@tiptap/core'
|
|
|
|
|
import Document from '@tiptap/extension-document'
|
|
|
|
|
import Paragraph from '@tiptap/extension-paragraph'
|
2024-08-25 14:23:20 +03:00
|
|
|
import Dropcursor from '@tiptap/extension-dropcursor'
|
2024-08-18 17:23:18 +03:00
|
|
|
import Text from '@tiptap/extension-text'
|
|
|
|
|
import Heading from '@tiptap/extension-heading'
|
2024-08-25 14:23:20 +03:00
|
|
|
import HardBreak from '@tiptap/extension-hard-break'
|
2024-08-18 17:23:18 +03:00
|
|
|
import Blockquote from '@tiptap/extension-blockquote';
|
2024-08-25 14:23:20 +03:00
|
|
|
import CodeBlock from '@tiptap/extension-code-block';
|
2024-08-18 17:23:18 +03:00
|
|
|
import Bold from '@tiptap/extension-bold';
|
|
|
|
|
import BulletList from '@tiptap/extension-bullet-list';
|
|
|
|
|
import Code from '@tiptap/extension-code';
|
|
|
|
|
import History from '@tiptap/extension-history';
|
|
|
|
|
import Italic from '@tiptap/extension-italic';
|
|
|
|
|
import ListItem from '@tiptap/extension-list-item';
|
|
|
|
|
import OrderedList from '@tiptap/extension-ordered-list';
|
|
|
|
|
import Strike from '@tiptap/extension-strike';
|
|
|
|
|
import Table from '@tiptap/extension-table';
|
|
|
|
|
import TableRow from '@tiptap/extension-table-row';
|
|
|
|
|
import TableCell from '@tiptap/extension-table-cell';
|
|
|
|
|
import TableHeader from '@tiptap/extension-table-header';
|
|
|
|
|
import Underline from '@tiptap/extension-underline';
|
2024-08-25 14:23:20 +03:00
|
|
|
import Image from '@tiptap/extension-image';
|
|
|
|
|
import Icon from "../common/Icon.svelte";
|
2024-08-18 17:23:18 +03:00
|
|
|
|
|
|
|
|
let element;
|
|
|
|
|
let editor;
|
|
|
|
|
export let value = "";
|
|
|
|
|
|
|
|
|
|
onMount(() => {
|
|
|
|
|
editor = new Editor({
|
|
|
|
|
element: element,
|
|
|
|
|
extensions: [
|
|
|
|
|
Document,
|
|
|
|
|
Paragraph,
|
|
|
|
|
Text,
|
|
|
|
|
Bold,
|
2024-08-25 14:23:20 +03:00
|
|
|
ListItem,
|
2024-08-18 17:23:18 +03:00
|
|
|
BulletList,
|
|
|
|
|
Code,
|
2024-08-25 14:23:20 +03:00
|
|
|
CodeBlock,
|
2024-08-18 17:23:18 +03:00
|
|
|
History,
|
|
|
|
|
Italic,
|
2024-08-25 14:23:20 +03:00
|
|
|
HardBreak,
|
2024-08-18 17:23:18 +03:00
|
|
|
OrderedList,
|
|
|
|
|
Strike,
|
|
|
|
|
Table,
|
|
|
|
|
TableRow,
|
|
|
|
|
TableCell,
|
|
|
|
|
TableHeader,
|
|
|
|
|
Underline,
|
2024-08-25 14:23:20 +03:00
|
|
|
Dropcursor,
|
|
|
|
|
Image,
|
2024-08-18 17:23:18 +03:00
|
|
|
Heading.configure({
|
|
|
|
|
levels: [1, 2, 3],
|
|
|
|
|
}),
|
|
|
|
|
Blockquote
|
|
|
|
|
],
|
|
|
|
|
content: value,
|
|
|
|
|
editable: true,
|
|
|
|
|
onTransaction: () => {
|
|
|
|
|
// force re-render so `editor.isActive` works as expected
|
|
|
|
|
editor = editor;
|
|
|
|
|
},
|
2024-08-25 14:23:20 +03:00
|
|
|
onUpdate: ({editor}) => {
|
|
|
|
|
value = editor.getHTML()
|
|
|
|
|
},
|
2024-08-18 17:23:18 +03:00
|
|
|
});
|
2024-08-25 14:23:20 +03:00
|
|
|
|
2024-08-18 17:23:18 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onDestroy(() => {
|
|
|
|
|
if (editor) {
|
|
|
|
|
editor.destroy();
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-08-25 14:23:20 +03:00
|
|
|
|
|
|
|
|
export function insertMedia(info){
|
|
|
|
|
editor.chain().focus().setImage({ src: info.url }).run()
|
|
|
|
|
}
|
2024-08-18 17:23:18 +03:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
{#if editor}
|
2024-08-25 14:23:20 +03:00
|
|
|
<div class="editor-toolbar">
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
|
|
|
|
class:active={editor.isActive('heading', { level: 1 })}
|
|
|
|
|
>
|
|
|
|
|
H1
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
|
|
|
|
class:active={editor.isActive('heading', { level: 2 })}
|
|
|
|
|
>
|
|
|
|
|
H2
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleBold().run()}
|
|
|
|
|
class:active={editor.isActive('bold')}
|
|
|
|
|
>
|
|
|
|
|
B
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleItalic().run()}
|
|
|
|
|
class:active={editor.isActive('italic')}
|
|
|
|
|
>
|
|
|
|
|
<em>IT</em>
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleUnderline().run()}
|
|
|
|
|
class:active={editor.isActive('underline')}
|
|
|
|
|
>
|
|
|
|
|
<u>U</u>
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleStrike().run()}
|
|
|
|
|
class:active={editor.isActive('strike')}
|
|
|
|
|
>
|
|
|
|
|
<s>S</s>
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.commands.unsetAllMarks()}
|
|
|
|
|
>
|
|
|
|
|
Clear
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleCode().run()}
|
|
|
|
|
class:active={editor.isActive('code')}
|
|
|
|
|
>
|
|
|
|
|
Code
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleBulletList().run()}
|
|
|
|
|
class:active={editor.isActive('bulletList')}
|
|
|
|
|
>
|
|
|
|
|
<Icon icon="list"></Icon>
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleOrderedList().run()}
|
|
|
|
|
class:active={editor.isActive('orderedList')}
|
|
|
|
|
>
|
|
|
|
|
<Icon icon="ordered-list"></Icon>
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleBlockquote().run()}
|
|
|
|
|
class:active={editor.isActive('blockquote')}
|
|
|
|
|
>
|
|
|
|
|
""
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="button"
|
|
|
|
|
on:click={() => editor.chain().focus().toggleCodeBlock().run()}
|
|
|
|
|
class:active={editor.isActive('codeBlock')}
|
|
|
|
|
>
|
|
|
|
|
cb
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
2024-08-18 17:23:18 +03:00
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
<div bind:this={element} class="content"/>
|