-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy path+page.svelte
114 lines (100 loc) · 2.92 KB
/
+page.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<script lang="ts">
import { onMount } from 'svelte';
import type { Readable } from 'svelte/store';
import StarterKit from '@tiptap/starter-kit';
import cx from 'clsx';
import { Editor, EditorContent, createEditor } from '$lib';
import Placeholder from '@tiptap/extension-placeholder';
import { SvelteCounterExtension, SvelteEditableExtension } from './_components/SvelteExtension';
const extensions = [
StarterKit,
SvelteCounterExtension,
SvelteEditableExtension,
Placeholder.configure({ placeholder: 'Writwe something...' }),
];
let editor = $state() as Readable<Editor>;
onMount(() => {
editor = createEditor({
extensions,
content: `
<p>This is still the text editor you're used to, but enriched with node views.</p>
<svelte-counter-component count="0"></svelte-counter-component>
<p>This is an editable component</p>
<svelte-editable-component>This is editable</svelte-editable-component>
<p>Did you see that? That's a Svelte component. We are really living in the future.</p>
`,
editorProps: {
attributes: {
class: 'border-2 border-black rounded-b-md p-3 outline-none',
},
},
});
});
const toggleHeading = (level: 1 | 2) => {
return () => {
$editor.chain().focus().toggleHeading({ level }).run();
};
};
const toggleBold = () => {
$editor.chain().focus().toggleBold().run();
};
const toggleItalic = () => {
$editor.chain().focus().toggleItalic().run();
};
const setParagraph = () => {
$editor.chain().focus().setParagraph().run();
};
const isActive = (name: string, attrs = {}) => $editor.isActive(name, attrs);
const menuItems = $derived([
{
name: 'heading-1',
command: toggleHeading(1),
content: 'H1',
active: () => isActive('heading', { level: 1 }),
},
{
name: 'heading-2',
command: toggleHeading(2),
content: 'H2',
active: () => isActive('heading', { level: 2 }),
},
{
name: 'bold',
command: toggleBold,
content: 'B',
active: () => isActive('bold'),
},
{
name: 'italic',
command: toggleItalic,
content: 'I',
active: () => isActive('italic'),
},
{
name: 'paragraph',
command: setParagraph,
content: 'P',
active: () => isActive('paragraph'),
},
]);
</script>
<svelte:head>
<title>Tiptap Svelte</title>
</svelte:head>
<h1 class="mb-2 font-bold">Editor with Nodeview Renderer</h1>
{#if editor}
<div class="border-black border-2 border-b-0 rounded-t-md p-2 flex gap-1">
{#each menuItems as item (item.name)}
<button
type="button"
class={cx('hover:bg-black hover:text-white w-7 h-7 rounded', {
'bg-black text-white': item.active(),
})}
onclick={item.command}
>
{item.content}
</button>
{/each}
</div>
{/if}
<EditorContent editor={$editor} />