@bendyline/squisq-editor-react 1.0.0 → 1.0.1
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/dist/EditorContext.d.ts +75 -0
- package/dist/EditorContext.d.ts.map +1 -0
- package/dist/EditorContext.js +158 -0
- package/dist/EditorContext.js.map +1 -0
- package/dist/EditorShell.d.ts +34 -0
- package/dist/EditorShell.d.ts.map +1 -0
- package/dist/EditorShell.js +59 -0
- package/dist/EditorShell.js.map +1 -0
- package/dist/PreviewPanel.d.ts +33 -0
- package/dist/PreviewPanel.d.ts.map +1 -0
- package/dist/PreviewPanel.js +385 -0
- package/dist/PreviewPanel.js.map +1 -0
- package/dist/RawEditor.d.ts +25 -0
- package/dist/RawEditor.d.ts.map +1 -0
- package/dist/RawEditor.js +100 -0
- package/dist/RawEditor.js.map +1 -0
- package/dist/StatusBar.d.ts +15 -0
- package/dist/StatusBar.d.ts.map +1 -0
- package/dist/StatusBar.js +24 -0
- package/dist/StatusBar.js.map +1 -0
- package/dist/TemplateAnnotation.d.ts +20 -0
- package/dist/TemplateAnnotation.d.ts.map +1 -0
- package/dist/TemplateAnnotation.js +69 -0
- package/dist/TemplateAnnotation.js.map +1 -0
- package/dist/Toolbar.d.ts +19 -0
- package/dist/Toolbar.d.ts.map +1 -0
- package/dist/Toolbar.js +350 -0
- package/dist/Toolbar.js.map +1 -0
- package/dist/ViewSwitcher.d.ts +14 -0
- package/dist/ViewSwitcher.d.ts.map +1 -0
- package/dist/ViewSwitcher.js +20 -0
- package/dist/ViewSwitcher.js.map +1 -0
- package/dist/WysiwygEditor.d.ts +28 -0
- package/dist/WysiwygEditor.d.ts.map +1 -0
- package/dist/WysiwygEditor.js +111 -0
- package/dist/WysiwygEditor.js.map +1 -0
- package/dist/index.d.ts +36 -268
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -3832
- package/dist/index.js.map +1 -1
- package/dist/tiptapBridge.d.ts +24 -0
- package/dist/tiptapBridge.d.ts.map +1 -0
- package/dist/tiptapBridge.js +358 -0
- package/dist/tiptapBridge.js.map +1 -0
- package/package.json +4 -5
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* WysiwygEditor
|
|
4
|
+
*
|
|
5
|
+
* Tiptap-based rich text editor that provides a WYSIWYG editing experience
|
|
6
|
+
* for markdown content. Uses squisq's parseMarkdown/stringifyMarkdown for
|
|
7
|
+
* conversion rather than Tiptap's built-in HTML serialization, ensuring
|
|
8
|
+
* perfect fidelity with the markdown format.
|
|
9
|
+
*
|
|
10
|
+
* Includes extensions for GFM features: tables, task lists, strikethrough,
|
|
11
|
+
* and code blocks.
|
|
12
|
+
*/
|
|
13
|
+
import { useEffect, useRef } from 'react';
|
|
14
|
+
import { useEditor, EditorContent } from '@tiptap/react';
|
|
15
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
16
|
+
import Table from '@tiptap/extension-table';
|
|
17
|
+
import TableRow from '@tiptap/extension-table-row';
|
|
18
|
+
import TableCell from '@tiptap/extension-table-cell';
|
|
19
|
+
import TableHeader from '@tiptap/extension-table-header';
|
|
20
|
+
import TaskList from '@tiptap/extension-task-list';
|
|
21
|
+
import TaskItem from '@tiptap/extension-task-item';
|
|
22
|
+
import Placeholder from '@tiptap/extension-placeholder';
|
|
23
|
+
import { HeadingWithTemplate } from './TemplateAnnotation';
|
|
24
|
+
import { useEditorContext } from './EditorContext';
|
|
25
|
+
import { markdownToTiptap, tiptapToMarkdown } from './tiptapBridge';
|
|
26
|
+
// ── Frontmatter helpers ────────────────────────────────────────────
|
|
27
|
+
/** Regex matching a YAML frontmatter block at the start of the document. */
|
|
28
|
+
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
29
|
+
/** Strip YAML frontmatter from markdown, returning both parts. */
|
|
30
|
+
function stripFrontmatter(md) {
|
|
31
|
+
const m = md.match(FRONTMATTER_RE);
|
|
32
|
+
if (!m)
|
|
33
|
+
return { body: md, frontmatter: '' };
|
|
34
|
+
return { body: md.slice(m[0].length), frontmatter: m[0] };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Rich WYSIWYG markdown editor built on Tiptap (ProseMirror).
|
|
38
|
+
* Binds to the shared EditorContext for source synchronization.
|
|
39
|
+
*/
|
|
40
|
+
export function WysiwygEditor({ placeholder = 'Start typing your markdown…', className, }) {
|
|
41
|
+
const { markdownSource, setMarkdownSource, setTiptapEditor } = useEditorContext();
|
|
42
|
+
const isExternalUpdate = useRef(false);
|
|
43
|
+
const lastSourceRef = useRef(markdownSource);
|
|
44
|
+
// Preserve frontmatter across edits — hidden from WYSIWYG but prepended on save
|
|
45
|
+
const frontmatterRef = useRef(stripFrontmatter(markdownSource).frontmatter);
|
|
46
|
+
const editor = useEditor({
|
|
47
|
+
extensions: [
|
|
48
|
+
StarterKit.configure({
|
|
49
|
+
// Disable built-in heading; we use HeadingWithTemplate instead
|
|
50
|
+
heading: false,
|
|
51
|
+
codeBlock: {
|
|
52
|
+
HTMLAttributes: { class: 'squisq-code-block' },
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
HeadingWithTemplate.configure({ levels: [1, 2, 3, 4, 5, 6] }),
|
|
56
|
+
Table.configure({ resizable: true }),
|
|
57
|
+
TableRow,
|
|
58
|
+
TableCell,
|
|
59
|
+
TableHeader,
|
|
60
|
+
TaskList,
|
|
61
|
+
TaskItem.configure({ nested: true }),
|
|
62
|
+
Placeholder.configure({ placeholder }),
|
|
63
|
+
],
|
|
64
|
+
content: markdownToTiptap(stripFrontmatter(markdownSource).body),
|
|
65
|
+
onUpdate: ({ editor: ed }) => {
|
|
66
|
+
if (isExternalUpdate.current)
|
|
67
|
+
return;
|
|
68
|
+
const html = ed.getHTML();
|
|
69
|
+
const bodyMd = tiptapToMarkdown(html);
|
|
70
|
+
const newSource = frontmatterRef.current + bodyMd;
|
|
71
|
+
lastSourceRef.current = newSource;
|
|
72
|
+
setMarkdownSource(newSource);
|
|
73
|
+
},
|
|
74
|
+
editorProps: {
|
|
75
|
+
attributes: {
|
|
76
|
+
class: 'squisq-wysiwyg-editor',
|
|
77
|
+
'data-testid': 'wysiwyg-editor',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
// Register / unregister the Tiptap editor instance with the shared context
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (editor) {
|
|
84
|
+
setTiptapEditor(editor);
|
|
85
|
+
}
|
|
86
|
+
return () => setTiptapEditor(null);
|
|
87
|
+
}, [editor, setTiptapEditor]);
|
|
88
|
+
// Sync external changes into Tiptap
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (!editor)
|
|
91
|
+
return;
|
|
92
|
+
// Only update if the source changed externally (not from our own onUpdate)
|
|
93
|
+
if (markdownSource !== lastSourceRef.current) {
|
|
94
|
+
isExternalUpdate.current = true;
|
|
95
|
+
const { body, frontmatter } = stripFrontmatter(markdownSource);
|
|
96
|
+
frontmatterRef.current = frontmatter;
|
|
97
|
+
const content = markdownToTiptap(body);
|
|
98
|
+
editor.commands.setContent(content);
|
|
99
|
+
lastSourceRef.current = markdownSource;
|
|
100
|
+
isExternalUpdate.current = false;
|
|
101
|
+
}
|
|
102
|
+
}, [markdownSource, editor]);
|
|
103
|
+
return (_jsx("div", { className: className, style: { width: '100%', height: '100%', overflow: 'auto' }, "data-testid": "wysiwyg-container", children: _jsx(EditorContent, { editor: editor, style: { height: '100%' } }) }));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Hook to access the Tiptap editor instance for toolbar commands.
|
|
107
|
+
* The WysiwygEditor must be mounted as a sibling or descendant.
|
|
108
|
+
*/
|
|
109
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
110
|
+
export { useEditor as useTiptapEditor } from '@tiptap/react';
|
|
111
|
+
//# sourceMappingURL=WysiwygEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WysiwygEditor.js","sourceRoot":"","sources":["../src/WysiwygEditor.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,269 +1,37 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
3
|
-
import { Doc } from '@bendyline/squisq/schemas';
|
|
4
|
-
import { MarkdownDocument } from '@bendyline/squisq/markdown';
|
|
5
|
-
import * as _tiptap_core from '@tiptap/core';
|
|
6
|
-
import { Editor } from '@tiptap/core';
|
|
7
|
-
import { editor } from 'monaco-editor';
|
|
8
|
-
import * as _tiptap_extension_heading from '@tiptap/extension-heading';
|
|
9
|
-
|
|
10
|
-
/** Monaco standalone code editor instance type */
|
|
11
|
-
type MonacoEditor = editor.IStandaloneCodeEditor;
|
|
12
|
-
type EditorView = 'raw' | 'wysiwyg' | 'preview';
|
|
13
|
-
type EditorTheme = 'light' | 'dark';
|
|
14
|
-
interface EditorState {
|
|
15
|
-
/** Raw markdown source string */
|
|
16
|
-
markdownSource: string;
|
|
17
|
-
/** Parsed markdown document (JSON DOM) */
|
|
18
|
-
markdownDoc: MarkdownDocument | null;
|
|
19
|
-
/** Generated Doc (block hierarchy) */
|
|
20
|
-
doc: Doc | null;
|
|
21
|
-
/** Currently active editor view */
|
|
22
|
-
activeView: EditorView;
|
|
23
|
-
/** Parse error, if any */
|
|
24
|
-
parseError: string | null;
|
|
25
|
-
/** Whether a parse is pending */
|
|
26
|
-
isParsing: boolean;
|
|
27
|
-
/** Current color theme */
|
|
28
|
-
theme: EditorTheme;
|
|
29
|
-
}
|
|
30
|
-
interface EditorActions {
|
|
31
|
-
/** Set markdown source and trigger re-parse */
|
|
32
|
-
setMarkdownSource: (source: string) => void;
|
|
33
|
-
/** Set markdown from a MarkdownDocument (e.g. from WYSIWYG) */
|
|
34
|
-
setMarkdownDoc: (doc: MarkdownDocument) => void;
|
|
35
|
-
/** Switch the active view */
|
|
36
|
-
setActiveView: (view: EditorView) => void;
|
|
37
|
-
/** Register / unregister the Tiptap editor instance (called by WysiwygEditor) */
|
|
38
|
-
setTiptapEditor: (editor: Editor | null) => void;
|
|
39
|
-
/** Register / unregister the Monaco editor instance (called by RawEditor) */
|
|
40
|
-
setMonacoEditor: (editor: MonacoEditor | null) => void;
|
|
41
|
-
/** Set the color theme */
|
|
42
|
-
setTheme: (theme: EditorTheme) => void;
|
|
43
|
-
}
|
|
44
|
-
interface EditorContextValue extends EditorState, EditorActions {
|
|
45
|
-
/** The live Tiptap editor instance (null when WYSIWYG is not mounted) */
|
|
46
|
-
tiptapEditor: Editor | null;
|
|
47
|
-
/** The live Monaco editor instance (null when Raw is not mounted) */
|
|
48
|
-
monacoEditor: MonacoEditor | null;
|
|
49
|
-
}
|
|
50
1
|
/**
|
|
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
|
-
/** CSS height for the shell container (default: '100vh') */
|
|
88
|
-
height?: string;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Complete markdown editor shell with toolbar, view switcher, and three
|
|
92
|
-
* editing modes: Raw (Monaco), WYSIWYG (Tiptap), and Preview.
|
|
93
|
-
*/
|
|
94
|
-
declare function EditorShell({ initialMarkdown, initialView, articleId, basePath, onChange, theme, className, height, }: EditorShellProps): react_jsx_runtime.JSX.Element;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* RawEditor
|
|
98
|
-
*
|
|
99
|
-
* Monaco-based raw markdown editor. Provides full VS Code-like editing
|
|
100
|
-
* experience with syntax highlighting, minimap, and bracket matching.
|
|
101
|
-
* Syncs changes back to EditorContext on every keystroke (debounced).
|
|
102
|
-
*/
|
|
103
|
-
interface RawEditorProps {
|
|
104
|
-
/** Monaco editor theme (default: 'vs-dark') */
|
|
105
|
-
theme?: string;
|
|
106
|
-
/** Show minimap (default: false) */
|
|
107
|
-
minimap?: boolean;
|
|
108
|
-
/** Font size in pixels (default: 14) */
|
|
109
|
-
fontSize?: number;
|
|
110
|
-
/** Word wrap setting (default: 'on') */
|
|
111
|
-
wordWrap?: 'on' | 'off' | 'wordWrapColumn' | 'bounded';
|
|
112
|
-
/** Additional class name for the container */
|
|
113
|
-
className?: string;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Raw markdown editor using Monaco Editor.
|
|
117
|
-
* Binds to the shared EditorContext for source synchronization.
|
|
118
|
-
*/
|
|
119
|
-
declare function RawEditor({ theme, minimap, fontSize, wordWrap, className, }: RawEditorProps): react_jsx_runtime.JSX.Element;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* WysiwygEditor
|
|
123
|
-
*
|
|
124
|
-
* Tiptap-based rich text editor that provides a WYSIWYG editing experience
|
|
125
|
-
* for markdown content. Uses squisq's parseMarkdown/stringifyMarkdown for
|
|
126
|
-
* conversion rather than Tiptap's built-in HTML serialization, ensuring
|
|
127
|
-
* perfect fidelity with the markdown format.
|
|
128
|
-
*
|
|
129
|
-
* Includes extensions for GFM features: tables, task lists, strikethrough,
|
|
130
|
-
* and code blocks.
|
|
131
|
-
*/
|
|
132
|
-
interface WysiwygEditorProps {
|
|
133
|
-
/** Placeholder text when editor is empty */
|
|
134
|
-
placeholder?: string;
|
|
135
|
-
/** Additional class name for the container */
|
|
136
|
-
className?: string;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Rich WYSIWYG markdown editor built on Tiptap (ProseMirror).
|
|
140
|
-
* Binds to the shared EditorContext for source synchronization.
|
|
141
|
-
*/
|
|
142
|
-
declare function WysiwygEditor({ placeholder, className, }: WysiwygEditorProps): react_jsx_runtime.JSX.Element;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* PreviewPanel
|
|
146
|
-
*
|
|
147
|
-
* Renders a live preview of the current markdown document as a slideshow
|
|
148
|
-
* using the DocPlayer component from @bendyline/squisq-react.
|
|
149
|
-
*
|
|
150
|
-
* The markdown-derived Doc (from markdownToDoc) contains hierarchical blocks
|
|
151
|
-
* with template names, heading text, and body content — but no audio or
|
|
152
|
-
* visual layers. This component bridges the gap by:
|
|
153
|
-
*
|
|
154
|
-
* 1. Flattening the block tree into a linear slide sequence
|
|
155
|
-
* 2. Converting each block into a TemplateBlock-compatible object
|
|
156
|
-
* (mapping heading text → title, templateOverrides → template fields)
|
|
157
|
-
* 3. Synthesizing a dummy audio segment so DocPlayer's timing works
|
|
158
|
-
* (the player enters fallback-timer mode when audio can't load)
|
|
159
|
-
* 4. Passing the prepared Doc to DocPlayer for SVG-based rendering
|
|
160
|
-
*/
|
|
161
|
-
interface PreviewPanelProps {
|
|
162
|
-
/** Base path for resolving media URLs in DocPlayer */
|
|
163
|
-
basePath?: string;
|
|
164
|
-
/** Additional class name for the container */
|
|
165
|
-
className?: string;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Live preview panel that renders the current document as a slideshow.
|
|
169
|
-
* Uses DocPlayer from @bendyline/squisq-react for SVG block rendering
|
|
170
|
-
* with template expansion, transitions, and playback controls.
|
|
171
|
-
*
|
|
172
|
-
* Includes a viewport format dropdown above the player. The default
|
|
173
|
-
* format can be hinted via YAML frontmatter `document-render-as:`.
|
|
174
|
-
*/
|
|
175
|
-
declare function PreviewPanel({ basePath, className }: PreviewPanelProps): react_jsx_runtime.JSX.Element;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* ViewSwitcher
|
|
179
|
-
*
|
|
180
|
-
* Tab bar for switching between Raw, WYSIWYG, and Preview editor views.
|
|
181
|
-
*/
|
|
182
|
-
interface ViewSwitcherProps {
|
|
183
|
-
/** Additional class name */
|
|
184
|
-
className?: string;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Tab-style view switcher for the three editor modes.
|
|
188
|
-
*/
|
|
189
|
-
declare function ViewSwitcher({ className }: ViewSwitcherProps): react_jsx_runtime.JSX.Element;
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Toolbar
|
|
193
|
-
*
|
|
194
|
-
* Formatting toolbar that provides common markdown editing actions.
|
|
195
|
-
* In WYSIWYG mode, uses Tiptap's chain commands to toggle marks / set nodes.
|
|
196
|
-
* In Raw mode, appends markdown syntax at the cursor (or end of source).
|
|
197
|
-
* Hidden in Preview mode.
|
|
198
|
-
*/
|
|
199
|
-
interface ToolbarProps {
|
|
200
|
-
/** Additional class name */
|
|
201
|
-
className?: string;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Formatting toolbar.
|
|
205
|
-
* - WYSIWYG: calls Tiptap chain commands (toggleBold, etc.)
|
|
206
|
-
* - Raw: appends markdown syntax to the source
|
|
207
|
-
*/
|
|
208
|
-
declare function Toolbar({ className }: ToolbarProps): react_jsx_runtime.JSX.Element;
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* StatusBar
|
|
212
|
-
*
|
|
213
|
-
* Bottom status bar showing document statistics and parse status.
|
|
214
|
-
*/
|
|
215
|
-
interface StatusBarProps {
|
|
216
|
-
/** Additional class name */
|
|
217
|
-
className?: string;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Status bar displaying document statistics: character count, word count,
|
|
221
|
-
* block count, and parse/error status.
|
|
222
|
-
*/
|
|
223
|
-
declare function StatusBar({ className }: StatusBarProps): react_jsx_runtime.JSX.Element;
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Tiptap Bridge
|
|
227
|
-
*
|
|
228
|
-
* Conversion utilities between raw markdown source and Tiptap's JSON/HTML
|
|
229
|
-
* content format. Uses a lightweight HTML-based approach: we convert markdown
|
|
230
|
-
* to a simple HTML representation that Tiptap can consume, and parse
|
|
231
|
-
* Tiptap's HTML output back to markdown.
|
|
232
|
-
*
|
|
233
|
-
* This bridge preserves markdown semantics much better than going through
|
|
234
|
-
* Tiptap's native markdown extension, since we control the conversion
|
|
235
|
-
* using squisq's own parser.
|
|
236
|
-
*/
|
|
237
|
-
/**
|
|
238
|
-
* Convert raw markdown source to Tiptap-consumable HTML content.
|
|
239
|
-
* Uses a simple markdown-to-HTML conversion that maps cleanly to
|
|
240
|
-
* Tiptap's ProseMirror schema.
|
|
241
|
-
*/
|
|
242
|
-
declare function markdownToTiptap(markdown: string): string;
|
|
243
|
-
/**
|
|
244
|
-
* Convert Tiptap HTML output back to markdown source.
|
|
245
|
-
* Extracts semantic structure from HTML and produces clean markdown.
|
|
246
|
-
*/
|
|
247
|
-
declare function tiptapToMarkdown(html: string): string;
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* TemplateAnnotation — Tiptap Heading Extension
|
|
251
|
-
*
|
|
252
|
-
* Extends Tiptap's built-in Heading node to support `data-template` and
|
|
253
|
-
* `data-template-params` HTML attributes. These attributes store which block
|
|
254
|
-
* template should be used for a heading section.
|
|
255
|
-
*
|
|
256
|
-
* When present, the heading renders a visible badge (styled CSS chip)
|
|
257
|
-
* showing the template name, e.g. `[chart]`.
|
|
258
|
-
*
|
|
259
|
-
* The tiptapBridge converts `### Title {[chart]}` markdown into
|
|
260
|
-
* `<h3 data-template="chart">Title</h3>` and back, so this extension
|
|
261
|
-
* ensures Tiptap's schema preserves those attributes through edits.
|
|
262
|
-
*/
|
|
263
|
-
/**
|
|
264
|
-
* HeadingWithTemplate — drop-in replacement for Tiptap's Heading that
|
|
265
|
-
* persists template annotation attributes.
|
|
266
|
-
*/
|
|
267
|
-
declare const HeadingWithTemplate: _tiptap_core.Node<_tiptap_extension_heading.HeadingOptions, any>;
|
|
268
|
-
|
|
269
|
-
export { type EditorActions, type EditorContextValue, EditorProvider, type EditorProviderProps, EditorShell, type EditorShellProps, type EditorState, type EditorTheme, type EditorView, HeadingWithTemplate, PreviewPanel, type PreviewPanelProps, RawEditor, type RawEditorProps, StatusBar, type StatusBarProps, Toolbar, type ToolbarProps, ViewSwitcher, type ViewSwitcherProps, WysiwygEditor, type WysiwygEditorProps, markdownToTiptap, tiptapToMarkdown, useEditorContext };
|
|
2
|
+
* @bendyline/squisq-editor-react
|
|
3
|
+
*
|
|
4
|
+
* React component library for editing markdown content with three views:
|
|
5
|
+
* - Raw (Monaco) — Full markdown source editing
|
|
6
|
+
* - WYSIWYG (Tiptap) — Rich text editing
|
|
7
|
+
* - Preview — Rendered block preview
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { EditorShell } from '@bendyline/squisq-editor-react';
|
|
12
|
+
* import '@bendyline/squisq-editor-react/styles';
|
|
13
|
+
*
|
|
14
|
+
* function App() {
|
|
15
|
+
* return <EditorShell initialMarkdown="# Hello World" />;
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export { EditorShell } from './EditorShell.js';
|
|
20
|
+
export type { EditorShellProps, EditorTheme } from './EditorShell.js';
|
|
21
|
+
export { EditorProvider, useEditorContext } from './EditorContext.js';
|
|
22
|
+
export type { EditorView, EditorState, EditorActions, EditorContextValue, EditorProviderProps, } from './EditorContext.js';
|
|
23
|
+
export { RawEditor } from './RawEditor.js';
|
|
24
|
+
export type { RawEditorProps } from './RawEditor.js';
|
|
25
|
+
export { WysiwygEditor } from './WysiwygEditor.js';
|
|
26
|
+
export type { WysiwygEditorProps } from './WysiwygEditor.js';
|
|
27
|
+
export { PreviewPanel } from './PreviewPanel.js';
|
|
28
|
+
export type { PreviewPanelProps } from './PreviewPanel.js';
|
|
29
|
+
export { ViewSwitcher } from './ViewSwitcher.js';
|
|
30
|
+
export type { ViewSwitcherProps } from './ViewSwitcher.js';
|
|
31
|
+
export { Toolbar } from './Toolbar.js';
|
|
32
|
+
export type { ToolbarProps } from './Toolbar.js';
|
|
33
|
+
export { StatusBar } from './StatusBar.js';
|
|
34
|
+
export type { StatusBarProps } from './StatusBar.js';
|
|
35
|
+
export { markdownToTiptap, tiptapToMarkdown } from './tiptapBridge.js';
|
|
36
|
+
export { HeadingWithTemplate } from './TemplateAnnotation.js';
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGtE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
|