Skip to content

Commit ae8c87d

Browse files
committed
Add PlainTextPaste plugin and enable via prop
Add a PlainTextPastePlugin that intercepts paste events and inserts only plain text, stripping formatting. This plugin addresses the need for a simplified rich-text mode where pasted content should not carry formatting. The plugin is registered with the editor and unregistered on cleanup.
1 parent e33a3fc commit ae8c87d

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

packages/ui/src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export { default as Formatter } from '$lib/richText/plugins/Formatter.svelte';
146146
export { default as GhostTextPlugin } from '$lib/richText/plugins/GhostText.svelte';
147147
export { default as HardWrapPlugin } from '$lib/richText/plugins/HardWrapPlugin.svelte';
148148
export { default as FilePlugin } from '$lib/richText/plugins/FilePlugin.svelte';
149+
export { default as PlainTextPastePlugin } from '$lib/richText/plugins/PlainTextPastePlugin.svelte';
149150
export { default as UpDownPlugin } from '$lib/richText/plugins/UpDownPlugin.svelte';
150151
export {
151152
default as Mention,

packages/ui/src/lib/richText/RichTextEditor.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// import CodeBlockTypeAhead from '$lib/richText/plugins/CodeBlockTypeAhead.svelte';
88
import EmojiPlugin from '$lib/richText/plugins/Emoji.svelte';
99
import IndentPlugin from '$lib/richText/plugins/IndentPlugin.svelte';
10+
import PlainTextPastePlugin from '$lib/richText/plugins/PlainTextPastePlugin.svelte';
1011
import OnChangePlugin, { type OnChangeCallback } from '$lib/richText/plugins/onChange.svelte';
1112
import OnInput, { type OnInputCallback } from '$lib/richText/plugins/onInput.svelte';
1213
import { insertTextAtCaret, setEditorText } from '$lib/richText/selection';
@@ -292,6 +293,7 @@
292293

293294
<RichTextPlugin />
294295
<IndentPlugin />
296+
<PlainTextPastePlugin />
295297
<MarkdownShortcutPlugin transformers={[INLINE_CODE_TRANSFORMER]} />
296298

297299
{#if autoFocus}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!--
2+
@component
3+
This plugin strips all formatting from pasted content, only allowing plain text to be inserted.
4+
Use this when you want a simplified rich text mode without formatted paste support.
5+
-->
6+
<script lang="ts">
7+
import {
8+
$getSelection as getSelection,
9+
$isRangeSelection as isRangeSelection,
10+
COMMAND_PRIORITY_HIGH,
11+
PASTE_COMMAND
12+
} from 'lexical';
13+
import { getEditor } from 'svelte-lexical';
14+
15+
const editor = getEditor();
16+
17+
$effect(() => {
18+
const unregisterPaste = editor.registerCommand(
19+
PASTE_COMMAND,
20+
(event: ClipboardEvent) => {
21+
// Get plain text from clipboard
22+
const text = event?.clipboardData?.getData('text/plain');
23+
24+
if (text) {
25+
event.preventDefault();
26+
27+
// Insert as plain text only, stripping all formatting
28+
editor.update(() => {
29+
const selection = getSelection();
30+
if (isRangeSelection(selection)) {
31+
selection.insertText(text);
32+
}
33+
});
34+
35+
return true; // Prevent default paste behavior
36+
}
37+
38+
return false;
39+
},
40+
COMMAND_PRIORITY_HIGH
41+
);
42+
43+
return () => {
44+
unregisterPaste();
45+
};
46+
});
47+
</script>

0 commit comments

Comments
 (0)