@overlap/rte 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,243 +0,0 @@
1
- import { IconWrapper } from "../components/IconWrapper";
2
- import { ButtonProps, EditorAPI, Plugin } from "../types";
3
-
4
- /**
5
- * Link-Plugin mit verbesserter Funktionalität
6
- */
7
- export function createLinkPlugin(): Plugin {
8
- return {
9
- name: "link",
10
- type: "inline",
11
- command: "createLink",
12
- renderButton: (props: ButtonProps) => (
13
- <button
14
- type="button"
15
- onClick={props.onClick}
16
- disabled={props.disabled}
17
- className={`rte-toolbar-button ${
18
- props.isActive ? "rte-toolbar-button-active" : ""
19
- }`}
20
- title="Link einfügen"
21
- aria-label="Link einfügen"
22
- >
23
- <IconWrapper icon="mdi:link" width={18} height={18} />
24
- </button>
25
- ),
26
- execute: (editor: EditorAPI) => {
27
- const selection = editor.getSelection();
28
- if (!selection || selection.rangeCount === 0) return;
29
-
30
- const range = selection.getRangeAt(0);
31
- const container = range.commonAncestorContainer;
32
- const element =
33
- container.nodeType === Node.TEXT_NODE
34
- ? container.parentElement
35
- : (container as HTMLElement);
36
-
37
- // Prüfe ob bereits ein Link vorhanden ist
38
- const existingLink = element?.closest("a") as HTMLAnchorElement;
39
-
40
- if (existingLink) {
41
- // Link entfernen
42
- const parent = existingLink.parentNode;
43
- if (parent) {
44
- while (existingLink.firstChild) {
45
- parent.insertBefore(
46
- existingLink.firstChild,
47
- existingLink
48
- );
49
- }
50
- parent.removeChild(existingLink);
51
- // Content aktualisieren
52
- const editorEl = editor.getSelection()?.anchorNode;
53
- if (editorEl) {
54
- const content = editor.getContent();
55
- editor.setContent(content);
56
- }
57
- }
58
- } else {
59
- // Neuen Link einfügen
60
- const url = prompt("URL eingeben:");
61
- if (url) {
62
- editor.executeCommand("createLink", url);
63
- }
64
- }
65
- },
66
- isActive: (editor: EditorAPI) => {
67
- const selection = editor.getSelection();
68
- if (!selection || selection.rangeCount === 0) return false;
69
-
70
- const range = selection.getRangeAt(0);
71
- const container = range.commonAncestorContainer;
72
- const element =
73
- container.nodeType === Node.TEXT_NODE
74
- ? container.parentElement
75
- : (container as HTMLElement);
76
-
77
- if (!element) return false;
78
-
79
- return element.closest("a") !== null;
80
- },
81
- getCurrentValue: (editor: EditorAPI) => {
82
- const selection = editor.getSelection();
83
- if (!selection || selection.rangeCount === 0) return undefined;
84
-
85
- const range = selection.getRangeAt(0);
86
- const container = range.commonAncestorContainer;
87
- const element =
88
- container.nodeType === Node.TEXT_NODE
89
- ? container.parentElement
90
- : (container as HTMLElement);
91
-
92
- if (!element) return undefined;
93
-
94
- const link = element.closest("a") as HTMLAnchorElement;
95
- return link ? link.href : undefined;
96
- },
97
- canExecute: (editor: EditorAPI) => {
98
- const selection = editor.getSelection();
99
- return selection !== null && selection.rangeCount > 0;
100
- },
101
- };
102
- }
103
-
104
- export const linkPlugin = createLinkPlugin();
105
-
106
- /**
107
- * Blockquote-Plugin
108
- */
109
- export const blockquotePlugin: Plugin = {
110
- name: "blockquote",
111
- type: "block",
112
- command: "formatBlock",
113
- renderButton: (props: ButtonProps) => (
114
- <button
115
- type="button"
116
- onClick={props.onClick}
117
- disabled={props.disabled}
118
- className={`rte-toolbar-button ${
119
- props.isActive ? "rte-toolbar-button-active" : ""
120
- }`}
121
- title="Zitat"
122
- aria-label="Zitat"
123
- >
124
- <IconWrapper icon="mdi:format-quote-close" width={18} height={18} />
125
- </button>
126
- ),
127
- execute: (editor: EditorAPI) => {
128
- const selection = editor.getSelection();
129
- if (!selection || selection.rangeCount === 0) return;
130
-
131
- const range = selection.getRangeAt(0);
132
- const container = range.commonAncestorContainer;
133
- const element =
134
- container.nodeType === Node.TEXT_NODE
135
- ? container.parentElement
136
- : (container as HTMLElement);
137
-
138
- if (!element) return;
139
-
140
- const isBlockquote = element.closest("blockquote") !== null;
141
-
142
- if (isBlockquote) {
143
- editor.executeCommand("formatBlock", "<p>");
144
- } else {
145
- editor.executeCommand("formatBlock", "<blockquote>");
146
- }
147
- },
148
- isActive: (editor: EditorAPI) => {
149
- const selection = editor.getSelection();
150
- if (!selection || selection.rangeCount === 0) return false;
151
-
152
- const range = selection.getRangeAt(0);
153
- const container = range.commonAncestorContainer;
154
- const element =
155
- container.nodeType === Node.TEXT_NODE
156
- ? container.parentElement
157
- : (container as HTMLElement);
158
-
159
- if (!element) return false;
160
-
161
- return element.closest("blockquote") !== null;
162
- },
163
- canExecute: (editor: EditorAPI) => {
164
- const selection = editor.getSelection();
165
- return selection !== null && selection.rangeCount > 0;
166
- },
167
- };
168
-
169
- /**
170
- * Unordered List Plugin
171
- */
172
- export const unorderedListPlugin: Plugin = {
173
- name: "unorderedList",
174
- type: "block",
175
- command: "insertUnorderedList",
176
- renderButton: (props: ButtonProps) => (
177
- <button
178
- type="button"
179
- onClick={props.onClick}
180
- disabled={props.disabled}
181
- className={`rte-toolbar-button ${
182
- props.isActive ? "rte-toolbar-button-active" : ""
183
- }`}
184
- title="Aufzählungsliste"
185
- aria-label="Aufzählungsliste"
186
- >
187
- <IconWrapper
188
- icon="mdi:format-list-bulleted"
189
- width={18}
190
- height={18}
191
- />
192
- </button>
193
- ),
194
- execute: (editor: EditorAPI) => {
195
- editor.executeCommand("insertUnorderedList");
196
- },
197
- isActive: (editor: EditorAPI) => {
198
- if (typeof document === "undefined") return false;
199
- return document.queryCommandState("insertUnorderedList");
200
- },
201
- canExecute: (editor: EditorAPI) => {
202
- const selection = editor.getSelection();
203
- return selection !== null && selection.rangeCount > 0;
204
- },
205
- };
206
-
207
- /**
208
- * Ordered List Plugin
209
- */
210
- export const orderedListPlugin: Plugin = {
211
- name: "orderedList",
212
- type: "block",
213
- command: "insertOrderedList",
214
- renderButton: (props: ButtonProps) => (
215
- <button
216
- type="button"
217
- onClick={props.onClick}
218
- disabled={props.disabled}
219
- className={`rte-toolbar-button ${
220
- props.isActive ? "rte-toolbar-button-active" : ""
221
- }`}
222
- title="Nummerierte Liste"
223
- aria-label="Nummerierte Liste"
224
- >
225
- <IconWrapper
226
- icon="mdi:format-list-numbered"
227
- width={18}
228
- height={18}
229
- />
230
- </button>
231
- ),
232
- execute: (editor: EditorAPI) => {
233
- editor.executeCommand("insertOrderedList");
234
- },
235
- isActive: (editor: EditorAPI) => {
236
- if (typeof document === "undefined") return false;
237
- return document.queryCommandState("insertOrderedList");
238
- },
239
- canExecute: (editor: EditorAPI) => {
240
- const selection = editor.getSelection();
241
- return selection !== null && selection.rangeCount > 0;
242
- },
243
- };