@svadmin/editor 0.1.0 → 0.2.2
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.
- package/{src → dist}/components/BubbleMenu.svelte +11 -20
- package/dist/components/BubbleMenu.svelte.d.ts +7 -0
- package/{src → dist}/components/ColorPicker.svelte +1 -1
- package/dist/components/ColorPicker.svelte.d.ts +7 -0
- package/{src → dist}/components/Editor.svelte +4 -4
- package/dist/components/Editor.svelte.d.ts +42 -0
- package/{src → dist}/components/FloatingMenu.svelte +14 -16
- package/dist/components/FloatingMenu.svelte.d.ts +7 -0
- package/{src → dist}/components/ImageUpload.svelte +12 -2
- package/dist/components/ImageUpload.svelte.d.ts +9 -0
- package/{src → dist}/components/LinkPopover.svelte +1 -1
- package/dist/components/LinkPopover.svelte.d.ts +8 -0
- package/{src → dist}/components/TableMenu.svelte +1 -1
- package/dist/components/TableMenu.svelte.d.ts +8 -0
- package/{src → dist}/components/Toolbar.svelte +3 -5
- package/dist/components/Toolbar.svelte.d.ts +9 -0
- package/dist/components/ToolbarButton.svelte.d.ts +11 -0
- package/dist/components/ToolbarGroup.svelte.d.ts +7 -0
- package/{src → dist}/components/ToolbarSelect.svelte +1 -1
- package/dist/components/ToolbarSelect.svelte.d.ts +12 -0
- package/dist/editor.svelte.d.ts +36 -0
- package/dist/editor.svelte.js +54 -0
- package/dist/extensions/index.d.ts +53 -0
- package/dist/extensions/index.js +156 -0
- package/dist/extensions/slash-command.d.ts +35 -0
- package/dist/extensions/slash-command.js +127 -0
- package/dist/index.d.ts +29 -0
- package/{src/index.ts → dist/index.js} +2 -34
- package/package.json +67 -37
- package/src/editor.svelte.ts +0 -99
- package/src/extensions/index.ts +0 -211
- package/src/extensions/slash-command.ts +0 -150
- /package/{src → dist}/components/ToolbarButton.svelte +0 -0
- /package/{src → dist}/components/ToolbarGroup.svelte +0 -0
- /package/{src → dist}/styles/editor.css +0 -0
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Editor } from '@tiptap/core';
|
|
3
|
-
import {
|
|
3
|
+
import { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu';
|
|
4
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
4
5
|
import ToolbarButton from './ToolbarButton.svelte';
|
|
5
6
|
import {
|
|
6
7
|
Bold, Italic, Underline as UnderlineIcon, Strikethrough,
|
|
7
8
|
Code, Link as LinkIcon, Highlighter,
|
|
8
|
-
} from 'lucide
|
|
9
|
+
} from '@lucide/svelte';
|
|
9
10
|
import { t } from '@svadmin/core';
|
|
10
11
|
|
|
12
|
+
const bubbleMenuKey = new PluginKey('svadminBubbleMenu');
|
|
13
|
+
|
|
11
14
|
let { editor } = $props<{
|
|
12
15
|
editor: Editor;
|
|
13
16
|
}>();
|
|
@@ -28,37 +31,25 @@
|
|
|
28
31
|
const isCode = $derived((void txn, editor.isActive('code')));
|
|
29
32
|
const isLink = $derived((void txn, editor.isActive('link')));
|
|
30
33
|
|
|
31
|
-
// Register the bubble menu
|
|
34
|
+
// Register the bubble menu plugin (Tiptap v3)
|
|
32
35
|
$effect(() => {
|
|
33
36
|
if (!menuElement) return;
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
);
|
|
39
|
-
if (existing) return;
|
|
40
|
-
|
|
41
|
-
// We need to register the extension dynamically
|
|
42
|
-
// Tiptap handles this through the plugin system
|
|
43
|
-
const plugin = TiptapBubbleMenu.configure({
|
|
38
|
+
const plugin = BubbleMenuPlugin({
|
|
39
|
+
pluginKey: bubbleMenuKey,
|
|
40
|
+
editor,
|
|
44
41
|
element: menuElement,
|
|
45
|
-
tippyOptions: {
|
|
46
|
-
duration: 150,
|
|
47
|
-
placement: 'top',
|
|
48
|
-
animation: 'shift-away',
|
|
49
|
-
},
|
|
50
42
|
shouldShow: ({ editor: e, state }) => {
|
|
51
43
|
const { selection } = state;
|
|
52
44
|
const { empty } = selection;
|
|
53
|
-
// Don't show in code blocks or empty selections
|
|
54
45
|
if (empty || e.isActive('codeBlock')) return false;
|
|
55
46
|
return true;
|
|
56
47
|
},
|
|
57
48
|
});
|
|
58
49
|
|
|
59
|
-
editor.registerPlugin(plugin
|
|
50
|
+
editor.registerPlugin(plugin);
|
|
60
51
|
return () => {
|
|
61
|
-
|
|
52
|
+
editor.unregisterPlugin(bubbleMenuKey);
|
|
62
53
|
};
|
|
63
54
|
});
|
|
64
55
|
</script>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
3
|
import { Editor } from '@tiptap/core';
|
|
3
|
-
import { onDestroy } from 'svelte';
|
|
4
4
|
import { fullPreset, minimalPreset, prosePreset, type EditorPresetOptions } from '../extensions/index.js';
|
|
5
5
|
import type { AnyExtension } from '@tiptap/core';
|
|
6
6
|
import Toolbar from './Toolbar.svelte';
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
const currentHtml = editor.getHTML();
|
|
179
179
|
if (value !== currentHtml) {
|
|
180
180
|
isUpdatingFromExternal = true;
|
|
181
|
-
editor.commands.setContent(value || '', false);
|
|
181
|
+
editor.commands.setContent(value || '', { emitUpdate: false });
|
|
182
182
|
isUpdatingFromExternal = false;
|
|
183
183
|
}
|
|
184
184
|
});
|
|
@@ -191,8 +191,8 @@
|
|
|
191
191
|
});
|
|
192
192
|
|
|
193
193
|
// Character count
|
|
194
|
-
const charCount = $derived(editor?.storage
|
|
195
|
-
const wordCount = $derived(editor?.storage
|
|
194
|
+
const charCount = $derived(((editor as any)?.storage as Record<string, any>)?.characterCount?.characters() ?? 0);
|
|
195
|
+
const wordCount = $derived(((editor as any)?.storage as Record<string, any>)?.characterCount?.words() ?? 0);
|
|
196
196
|
</script>
|
|
197
197
|
|
|
198
198
|
<div class="svadmin-editor {className}">
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Editor } from '@tiptap/core';
|
|
2
|
+
import type { AnyExtension } from '@tiptap/core';
|
|
3
|
+
import '../styles/editor.css';
|
|
4
|
+
interface Props {
|
|
5
|
+
/** HTML string content (bindable) */
|
|
6
|
+
value?: string;
|
|
7
|
+
/** Placeholder text */
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
/** Whether the editor is editable */
|
|
10
|
+
editable?: boolean;
|
|
11
|
+
/** Autofocus on mount */
|
|
12
|
+
autofocus?: boolean | 'start' | 'end';
|
|
13
|
+
/** Max character count */
|
|
14
|
+
maxLength?: number;
|
|
15
|
+
/** Show toolbar */
|
|
16
|
+
showToolbar?: boolean;
|
|
17
|
+
/** Show bubble menu on text selection */
|
|
18
|
+
showBubbleMenu?: boolean;
|
|
19
|
+
/** Show floating menu on empty lines */
|
|
20
|
+
showFloatingMenu?: boolean;
|
|
21
|
+
/** Show character count in footer */
|
|
22
|
+
showCharCount?: boolean;
|
|
23
|
+
/** Extension preset */
|
|
24
|
+
preset?: 'full' | 'minimal' | 'prose';
|
|
25
|
+
/** Custom extensions (overrides preset) */
|
|
26
|
+
extensions?: AnyExtension[];
|
|
27
|
+
/** Image upload handler */
|
|
28
|
+
onUpload?: (file: File) => Promise<string>;
|
|
29
|
+
/** Called on every content change */
|
|
30
|
+
onchange?: (html: string) => void;
|
|
31
|
+
/** Additional CSS class for the wrapper */
|
|
32
|
+
class?: string;
|
|
33
|
+
/** Min height for the editor content area */
|
|
34
|
+
minHeight?: string;
|
|
35
|
+
/** Max height for the editor content area */
|
|
36
|
+
maxHeight?: string;
|
|
37
|
+
/** lowlight instance for syntax-highlighted code blocks */
|
|
38
|
+
lowlight?: unknown;
|
|
39
|
+
}
|
|
40
|
+
declare const Editor: import("svelte").Component<Props, {}, "value">;
|
|
41
|
+
type Editor = ReturnType<typeof Editor>;
|
|
42
|
+
export default Editor;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Editor } from '@tiptap/core';
|
|
3
|
-
import {
|
|
3
|
+
import { FloatingMenuPlugin } from '@tiptap/extension-floating-menu';
|
|
4
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
4
5
|
import ToolbarButton from './ToolbarButton.svelte';
|
|
5
6
|
import {
|
|
6
7
|
Heading1, Heading2, Heading3,
|
|
7
8
|
List, ListOrdered, ListChecks,
|
|
8
|
-
Quote, Code2, Minus,
|
|
9
|
-
} from 'lucide
|
|
9
|
+
Quote, Code2, Minus,
|
|
10
|
+
} from '@lucide/svelte';
|
|
10
11
|
import { t } from '@svadmin/core';
|
|
11
12
|
|
|
13
|
+
const floatingMenuKey = new PluginKey('svadminFloatingMenu');
|
|
14
|
+
|
|
12
15
|
let { editor } = $props<{
|
|
13
16
|
editor: Editor;
|
|
14
17
|
}>();
|
|
@@ -18,21 +21,13 @@
|
|
|
18
21
|
$effect(() => {
|
|
19
22
|
if (!menuElement) return;
|
|
20
23
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (existing) return;
|
|
25
|
-
|
|
26
|
-
const plugin = TiptapFloatingMenu.configure({
|
|
24
|
+
const plugin = FloatingMenuPlugin({
|
|
25
|
+
pluginKey: floatingMenuKey,
|
|
26
|
+
editor,
|
|
27
27
|
element: menuElement,
|
|
28
|
-
|
|
29
|
-
duration: 150,
|
|
30
|
-
placement: 'left-start',
|
|
31
|
-
},
|
|
32
|
-
shouldShow: ({ editor: e, state }) => {
|
|
28
|
+
shouldShow: ({ editor: _e, state }) => {
|
|
33
29
|
const { selection } = state;
|
|
34
30
|
const { $anchor: anchor, empty } = selection;
|
|
35
|
-
// Show only on empty paragraphs
|
|
36
31
|
if (!empty) return false;
|
|
37
32
|
const isRootDepth = anchor.depth === 1;
|
|
38
33
|
const isEmptyTextBlock = anchor.parent.isTextblock
|
|
@@ -42,7 +37,10 @@
|
|
|
42
37
|
},
|
|
43
38
|
});
|
|
44
39
|
|
|
45
|
-
editor.registerPlugin(plugin
|
|
40
|
+
editor.registerPlugin(plugin);
|
|
41
|
+
return () => {
|
|
42
|
+
editor.unregisterPlugin(floatingMenuKey);
|
|
43
|
+
};
|
|
46
44
|
});
|
|
47
45
|
</script>
|
|
48
46
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Editor } from '@tiptap/core';
|
|
3
|
-
import { ImageIcon, Upload, Link as LinkIcon
|
|
3
|
+
import { ImageIcon, Upload, Link as LinkIcon } from '@lucide/svelte';
|
|
4
4
|
import { t } from '@svadmin/core';
|
|
5
5
|
|
|
6
6
|
let { editor, onUpload, onclose } = $props<{
|
|
@@ -56,6 +56,13 @@
|
|
|
56
56
|
dragover = false;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function handleDropZoneKeydown(e: KeyboardEvent) {
|
|
60
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
fileInput?.click();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
function handleKeydown(e: KeyboardEvent) {
|
|
60
67
|
if (e.key === 'Enter') {
|
|
61
68
|
e.preventDefault();
|
|
@@ -122,8 +129,10 @@
|
|
|
122
129
|
</button>
|
|
123
130
|
</div>
|
|
124
131
|
{:else}
|
|
125
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
126
132
|
<div
|
|
133
|
+
role="button"
|
|
134
|
+
tabindex="0"
|
|
135
|
+
aria-label={t('editor.image.upload')}
|
|
127
136
|
style="
|
|
128
137
|
border: 2px dashed {dragover ? 'var(--editor-primary)' : 'var(--editor-border)'};
|
|
129
138
|
border-radius: 8px;
|
|
@@ -136,6 +145,7 @@
|
|
|
136
145
|
ondrop={handleDrop}
|
|
137
146
|
ondragover={handleDragOver}
|
|
138
147
|
ondragleave={handleDragLeave}
|
|
148
|
+
onkeydown={handleDropZoneKeydown}
|
|
139
149
|
onclick={() => fileInput?.click()}
|
|
140
150
|
>
|
|
141
151
|
{#if uploading}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Editor } from '@tiptap/core';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
editor: Editor;
|
|
4
|
+
onUpload?: (file: File) => Promise<string>;
|
|
5
|
+
onclose?: () => void;
|
|
6
|
+
};
|
|
7
|
+
declare const ImageUpload: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type ImageUpload = ReturnType<typeof ImageUpload>;
|
|
9
|
+
export default ImageUpload;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Editor } from '@tiptap/core';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
editor: Editor;
|
|
4
|
+
onclose?: () => void;
|
|
5
|
+
};
|
|
6
|
+
declare const LinkPopover: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type LinkPopover = ReturnType<typeof LinkPopover>;
|
|
8
|
+
export default LinkPopover;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Editor } from '@tiptap/core';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
editor: Editor;
|
|
4
|
+
onclose?: () => void;
|
|
5
|
+
};
|
|
6
|
+
declare const TableMenu: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type TableMenu = ReturnType<typeof TableMenu>;
|
|
8
|
+
export default TableMenu;
|
|
@@ -9,16 +9,14 @@
|
|
|
9
9
|
import ImageUpload from './ImageUpload.svelte';
|
|
10
10
|
import {
|
|
11
11
|
Bold, Italic, Underline as UnderlineIcon, Strikethrough,
|
|
12
|
-
Heading1, Heading2, Heading3,
|
|
13
12
|
List, ListOrdered, ListChecks,
|
|
14
13
|
AlignLeft, AlignCenter, AlignRight, AlignJustify,
|
|
15
14
|
Quote, Minus, Code, Code2,
|
|
16
15
|
Undo2, Redo2,
|
|
17
16
|
Link as LinkIcon, ImageIcon, TableIcon,
|
|
18
|
-
Palette, Highlighter,
|
|
17
|
+
Palette, Highlighter,
|
|
19
18
|
Subscript, Superscript,
|
|
20
|
-
|
|
21
|
-
} from 'lucide-svelte';
|
|
19
|
+
} from '@lucide/svelte';
|
|
22
20
|
import { t } from '@svadmin/core';
|
|
23
21
|
|
|
24
22
|
let { editor, onUpload, preset = 'full' } = $props<{
|
|
@@ -120,7 +118,7 @@
|
|
|
120
118
|
}
|
|
121
119
|
}
|
|
122
120
|
|
|
123
|
-
const isFullOrProse = preset === 'full' || preset === 'prose';
|
|
121
|
+
const isFullOrProse = $derived(preset === 'full' || preset === 'prose');
|
|
124
122
|
</script>
|
|
125
123
|
|
|
126
124
|
<div class="svadmin-editor-toolbar">
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Editor } from '@tiptap/core';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
editor: Editor;
|
|
4
|
+
onUpload?: (file: File) => Promise<string>;
|
|
5
|
+
preset?: 'full' | 'minimal' | 'prose';
|
|
6
|
+
};
|
|
7
|
+
declare const Toolbar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type Toolbar = ReturnType<typeof Toolbar>;
|
|
9
|
+
export default Toolbar;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
active?: boolean;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
title?: string;
|
|
6
|
+
onclick?: () => void;
|
|
7
|
+
children: Snippet;
|
|
8
|
+
};
|
|
9
|
+
declare const ToolbarButton: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type ToolbarButton = ReturnType<typeof ToolbarButton>;
|
|
11
|
+
export default ToolbarButton;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
value?: string;
|
|
3
|
+
options: Array<{
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
}>;
|
|
7
|
+
title?: string;
|
|
8
|
+
onchange?: (value: string) => void;
|
|
9
|
+
};
|
|
10
|
+
declare const ToolbarSelect: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type ToolbarSelect = ReturnType<typeof ToolbarSelect>;
|
|
12
|
+
export default ToolbarSelect;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @svadmin/editor — Editor factory
|
|
3
|
+
*
|
|
4
|
+
* Creates and manages a Tiptap editor instance with Svelte 5 reactivity.
|
|
5
|
+
*/
|
|
6
|
+
import { Editor, type EditorOptions } from '@tiptap/core';
|
|
7
|
+
import { type EditorPresetOptions } from './extensions/index.js';
|
|
8
|
+
import type { AnyExtension } from '@tiptap/core';
|
|
9
|
+
export interface SvadminEditorOptions {
|
|
10
|
+
/** Initial HTML content */
|
|
11
|
+
content?: string;
|
|
12
|
+
/** Placeholder text shown when editor is empty */
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
/** Whether the editor is editable */
|
|
15
|
+
editable?: boolean;
|
|
16
|
+
/** Autofocus on mount */
|
|
17
|
+
autofocus?: boolean | 'start' | 'end';
|
|
18
|
+
/** Maximum character count (0 = unlimited) */
|
|
19
|
+
maxLength?: number;
|
|
20
|
+
/** Extension preset: 'full' | 'minimal' | 'prose' */
|
|
21
|
+
preset?: 'full' | 'minimal' | 'prose';
|
|
22
|
+
/** Custom extensions (overrides preset) */
|
|
23
|
+
extensions?: AnyExtension[];
|
|
24
|
+
/** Preset options */
|
|
25
|
+
presetOptions?: EditorPresetOptions;
|
|
26
|
+
/** Image upload handler */
|
|
27
|
+
onUpload?: (file: File) => Promise<string>;
|
|
28
|
+
/** Called on every content update */
|
|
29
|
+
onUpdate?: (html: string) => void;
|
|
30
|
+
/** Additional Tiptap EditorOptions overrides */
|
|
31
|
+
editorProps?: Partial<EditorOptions>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create a Tiptap editor instance with svadmin defaults.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createSvadminEditor(element: HTMLElement, options?: SvadminEditorOptions): Editor;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @svadmin/editor — Editor factory
|
|
3
|
+
*
|
|
4
|
+
* Creates and manages a Tiptap editor instance with Svelte 5 reactivity.
|
|
5
|
+
*/
|
|
6
|
+
import { Editor } from '@tiptap/core';
|
|
7
|
+
import { fullPreset, minimalPreset, prosePreset } from './extensions/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a Tiptap editor instance with svadmin defaults.
|
|
10
|
+
*/
|
|
11
|
+
export function createSvadminEditor(element, options = {}) {
|
|
12
|
+
const { content = '', placeholder = '', editable = true, autofocus = false, maxLength = 0, preset = 'full', extensions: customExtensions, presetOptions, onUpdate, editorProps, } = options;
|
|
13
|
+
// Resolve extensions
|
|
14
|
+
let extensions;
|
|
15
|
+
if (customExtensions) {
|
|
16
|
+
extensions = customExtensions;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const opts = {
|
|
20
|
+
placeholder,
|
|
21
|
+
maxLength,
|
|
22
|
+
...presetOptions,
|
|
23
|
+
};
|
|
24
|
+
switch (preset) {
|
|
25
|
+
case 'minimal':
|
|
26
|
+
extensions = minimalPreset(opts);
|
|
27
|
+
break;
|
|
28
|
+
case 'prose':
|
|
29
|
+
extensions = prosePreset(opts);
|
|
30
|
+
break;
|
|
31
|
+
case 'full':
|
|
32
|
+
default:
|
|
33
|
+
extensions = fullPreset(opts);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const editor = new Editor({
|
|
37
|
+
element,
|
|
38
|
+
extensions,
|
|
39
|
+
content,
|
|
40
|
+
editable,
|
|
41
|
+
autofocus,
|
|
42
|
+
editorProps: {
|
|
43
|
+
attributes: {
|
|
44
|
+
class: 'tiptap',
|
|
45
|
+
},
|
|
46
|
+
...editorProps?.editorProps,
|
|
47
|
+
},
|
|
48
|
+
onUpdate({ editor: e }) {
|
|
49
|
+
onUpdate?.(e.getHTML());
|
|
50
|
+
},
|
|
51
|
+
...editorProps,
|
|
52
|
+
});
|
|
53
|
+
return editor;
|
|
54
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @svadmin/editor — Extension presets
|
|
3
|
+
*
|
|
4
|
+
* Pre-configured extension bundles for different use cases.
|
|
5
|
+
* Users can pick a preset or compose their own extension array.
|
|
6
|
+
*/
|
|
7
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
8
|
+
import Underline from '@tiptap/extension-underline';
|
|
9
|
+
import TextAlign from '@tiptap/extension-text-align';
|
|
10
|
+
import { TextStyle } from '@tiptap/extension-text-style';
|
|
11
|
+
import Color from '@tiptap/extension-color';
|
|
12
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
13
|
+
import Link from '@tiptap/extension-link';
|
|
14
|
+
import Image from '@tiptap/extension-image';
|
|
15
|
+
import Placeholder from '@tiptap/extension-placeholder';
|
|
16
|
+
import CharacterCount from '@tiptap/extension-character-count';
|
|
17
|
+
import Typography from '@tiptap/extension-typography';
|
|
18
|
+
import Subscript from '@tiptap/extension-subscript';
|
|
19
|
+
import Superscript from '@tiptap/extension-superscript';
|
|
20
|
+
import TaskList from '@tiptap/extension-task-list';
|
|
21
|
+
import TaskItem from '@tiptap/extension-task-item';
|
|
22
|
+
import { Table } from '@tiptap/extension-table';
|
|
23
|
+
import TableRow from '@tiptap/extension-table-row';
|
|
24
|
+
import TableHeader from '@tiptap/extension-table-header';
|
|
25
|
+
import TableCell from '@tiptap/extension-table-cell';
|
|
26
|
+
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
|
|
27
|
+
import type { AnyExtension } from '@tiptap/core';
|
|
28
|
+
export interface EditorPresetOptions {
|
|
29
|
+
/** Placeholder text */
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
/** Max character count (0 = unlimited) */
|
|
32
|
+
maxLength?: number;
|
|
33
|
+
/** Enable code block syntax highlighting */
|
|
34
|
+
codeHighlight?: boolean;
|
|
35
|
+
/** lowlight instance (required if codeHighlight is true) */
|
|
36
|
+
lowlight?: unknown;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Full preset: all extensions enabled.
|
|
40
|
+
* Suitable for content management, article editing, knowledge bases.
|
|
41
|
+
*/
|
|
42
|
+
export declare function fullPreset(options?: EditorPresetOptions): AnyExtension[];
|
|
43
|
+
/**
|
|
44
|
+
* Minimal preset: basic text formatting only.
|
|
45
|
+
* Suitable for comments, short descriptions, inline editing.
|
|
46
|
+
*/
|
|
47
|
+
export declare function minimalPreset(options?: EditorPresetOptions): AnyExtension[];
|
|
48
|
+
/**
|
|
49
|
+
* Prose preset: optimized for long-form writing.
|
|
50
|
+
* Includes typography, highlights, but no tables.
|
|
51
|
+
*/
|
|
52
|
+
export declare function prosePreset(options?: EditorPresetOptions): AnyExtension[];
|
|
53
|
+
export { StarterKit, Underline, TextAlign, TextStyle, Color, Highlight, Link, Image, Placeholder, CharacterCount, Typography, Subscript, Superscript, TaskList, TaskItem, Table, TableRow, TableHeader, TableCell, CodeBlockLowlight, };
|