@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,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TemplateAnnotation — Tiptap Heading Extension
|
|
3
|
+
*
|
|
4
|
+
* Extends Tiptap's built-in Heading node to support `data-template` and
|
|
5
|
+
* `data-template-params` HTML attributes. These attributes store which block
|
|
6
|
+
* template should be used for a heading section.
|
|
7
|
+
*
|
|
8
|
+
* When present, the heading renders a visible badge (styled CSS chip)
|
|
9
|
+
* showing the template name, e.g. `[chart]`.
|
|
10
|
+
*
|
|
11
|
+
* The tiptapBridge converts `### Title {[chart]}` markdown into
|
|
12
|
+
* `<h3 data-template="chart">Title</h3>` and back, so this extension
|
|
13
|
+
* ensures Tiptap's schema preserves those attributes through edits.
|
|
14
|
+
*/
|
|
15
|
+
import Heading from '@tiptap/extension-heading';
|
|
16
|
+
/**
|
|
17
|
+
* HeadingWithTemplate — drop-in replacement for Tiptap's Heading that
|
|
18
|
+
* persists template annotation attributes.
|
|
19
|
+
*/
|
|
20
|
+
export const HeadingWithTemplate = Heading.extend({
|
|
21
|
+
addAttributes() {
|
|
22
|
+
return {
|
|
23
|
+
...this.parent?.(),
|
|
24
|
+
dataTemplate: {
|
|
25
|
+
default: null,
|
|
26
|
+
parseHTML: (element) => element.getAttribute('data-template') || null,
|
|
27
|
+
renderHTML: (attributes) => {
|
|
28
|
+
if (!attributes.dataTemplate)
|
|
29
|
+
return {};
|
|
30
|
+
return { 'data-template': attributes.dataTemplate };
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
dataTemplateParams: {
|
|
34
|
+
default: null,
|
|
35
|
+
parseHTML: (element) => element.getAttribute('data-template-params') || null,
|
|
36
|
+
renderHTML: (attributes) => {
|
|
37
|
+
if (!attributes.dataTemplateParams)
|
|
38
|
+
return {};
|
|
39
|
+
return { 'data-template-params': attributes.dataTemplateParams };
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
45
|
+
const level = node.attrs.level;
|
|
46
|
+
const tag = `h${level}`;
|
|
47
|
+
const templateName = HTMLAttributes['data-template'];
|
|
48
|
+
if (templateName) {
|
|
49
|
+
// Render heading with a trailing badge span
|
|
50
|
+
return [
|
|
51
|
+
tag,
|
|
52
|
+
HTMLAttributes,
|
|
53
|
+
['span', { class: 'squisq-heading-content' }, 0],
|
|
54
|
+
[
|
|
55
|
+
'span',
|
|
56
|
+
{
|
|
57
|
+
class: 'squisq-template-badge',
|
|
58
|
+
contenteditable: 'false',
|
|
59
|
+
'data-template': templateName,
|
|
60
|
+
},
|
|
61
|
+
templateName,
|
|
62
|
+
],
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
// No template — render as normal heading
|
|
66
|
+
return [tag, HTMLAttributes, 0];
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=TemplateAnnotation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateAnnotation.js","sourceRoot":"","sources":["../src/TemplateAnnotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,OAAO,MAAM,2BAA2B,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAChD,aAAa;QACX,OAAO;YACL,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE;YAClB,YAAY,EAAE;gBACZ,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,CAAC,OAAoB,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,IAAI;gBAClF,UAAU,EAAE,CAAC,UAAmC,EAAE,EAAE;oBAClD,IAAI,CAAC,UAAU,CAAC,YAAY;wBAAE,OAAO,EAAE,CAAC;oBACxC,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,YAAY,EAAE,CAAC;gBACtD,CAAC;aACF;YACD,kBAAkB,EAAE;gBAClB,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,CAAC,OAAoB,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,IAAI,IAAI;gBACzF,UAAU,EAAE,CAAC,UAAmC,EAAE,EAAE;oBAClD,IAAI,CAAC,UAAU,CAAC,kBAAkB;wBAAE,OAAO,EAAE,CAAC;oBAC9C,OAAO,EAAE,sBAAsB,EAAE,UAAU,CAAC,kBAAkB,EAAE,CAAC;gBACnE,CAAC;aACF;SACF,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,YAAY,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;QAErD,IAAI,YAAY,EAAE,CAAC;YACjB,4CAA4C;YAC5C,OAAO;gBACL,GAAG;gBACH,cAAc;gBACd,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC;gBAChD;oBACE,MAAM;oBACN;wBACE,KAAK,EAAE,uBAAuB;wBAC9B,eAAe,EAAE,OAAO;wBACxB,eAAe,EAAE,YAAY;qBAC9B;oBACD,YAAY;iBACb;aACF,CAAC;QACJ,CAAC;QAED,yCAAyC;QACzC,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toolbar
|
|
3
|
+
*
|
|
4
|
+
* Formatting toolbar that provides common markdown editing actions.
|
|
5
|
+
* In WYSIWYG mode, uses Tiptap's chain commands to toggle marks / set nodes.
|
|
6
|
+
* In Raw mode, appends markdown syntax at the cursor (or end of source).
|
|
7
|
+
* Hidden in Preview mode.
|
|
8
|
+
*/
|
|
9
|
+
export interface ToolbarProps {
|
|
10
|
+
/** Additional class name */
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Formatting toolbar.
|
|
15
|
+
* - WYSIWYG: calls Tiptap chain commands (toggleBold, etc.)
|
|
16
|
+
* - Raw: appends markdown syntax to the source
|
|
17
|
+
*/
|
|
18
|
+
export declare function Toolbar({ className }: ToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=Toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../src/Toolbar.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuFD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,YAAY,2CAkWlD"}
|
package/dist/Toolbar.js
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Toolbar
|
|
4
|
+
*
|
|
5
|
+
* Formatting toolbar that provides common markdown editing actions.
|
|
6
|
+
* In WYSIWYG mode, uses Tiptap's chain commands to toggle marks / set nodes.
|
|
7
|
+
* In Raw mode, appends markdown syntax at the cursor (or end of source).
|
|
8
|
+
* Hidden in Preview mode.
|
|
9
|
+
*/
|
|
10
|
+
import { useCallback, useEffect, useReducer } from 'react';
|
|
11
|
+
import { useEditorContext } from './EditorContext';
|
|
12
|
+
import { getAvailableTemplates } from '@bendyline/squisq/doc';
|
|
13
|
+
const VIEWS = [
|
|
14
|
+
{ id: 'wysiwyg', label: 'Editor', shortcut: '⌘1' },
|
|
15
|
+
{ id: 'raw', label: 'Raw', shortcut: '⌘2' },
|
|
16
|
+
{ id: 'preview', label: 'Preview', shortcut: '⌘3' },
|
|
17
|
+
];
|
|
18
|
+
const BUTTONS = [
|
|
19
|
+
// Format group
|
|
20
|
+
{
|
|
21
|
+
id: 'bold',
|
|
22
|
+
label: 'B',
|
|
23
|
+
icon: 'B',
|
|
24
|
+
title: 'Bold (Ctrl+B)',
|
|
25
|
+
group: 'format',
|
|
26
|
+
iconStyle: { fontWeight: 700 },
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'italic',
|
|
30
|
+
label: 'I',
|
|
31
|
+
icon: 'I',
|
|
32
|
+
title: 'Italic (Ctrl+I)',
|
|
33
|
+
group: 'format',
|
|
34
|
+
iconStyle: { fontStyle: 'italic' },
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'strikethrough',
|
|
38
|
+
label: 'S',
|
|
39
|
+
icon: 'S',
|
|
40
|
+
title: 'Strikethrough',
|
|
41
|
+
group: 'format',
|
|
42
|
+
iconStyle: { textDecoration: 'line-through' },
|
|
43
|
+
},
|
|
44
|
+
{ id: 'code', label: '<>', icon: '`', title: 'Inline code', group: 'format' },
|
|
45
|
+
// Structure group
|
|
46
|
+
{ id: 'h1', label: 'H1', icon: 'H1', title: 'Heading 1', group: 'structure' },
|
|
47
|
+
{ id: 'h2', label: 'H2', icon: 'H2', title: 'Heading 2', group: 'structure' },
|
|
48
|
+
{ id: 'h3', label: 'H3', icon: 'H3', title: 'Heading 3', group: 'structure' },
|
|
49
|
+
{ id: 'quote', label: '❝', icon: '❝', title: 'Blockquote', group: 'structure' },
|
|
50
|
+
// Insert group
|
|
51
|
+
{ id: 'ul', label: '•', icon: '•', title: 'Bullet list', group: 'insert' },
|
|
52
|
+
{ id: 'ol', label: '1.', icon: '1.', title: 'Numbered list', group: 'insert' },
|
|
53
|
+
{ id: 'codeblock', label: '{ }', icon: '{ }', title: 'Code block', group: 'insert' },
|
|
54
|
+
{ id: 'hr', label: '—', icon: '—', title: 'Horizontal rule', group: 'insert' },
|
|
55
|
+
{ id: 'link', label: '🔗', icon: '🔗', title: 'Insert link', group: 'insert' },
|
|
56
|
+
];
|
|
57
|
+
// ─── Tiptap active-state map ────────────────────────────
|
|
58
|
+
/** Returns true if the given button id is currently active in Tiptap */
|
|
59
|
+
function isTiptapActive(editor, id) {
|
|
60
|
+
if (!editor)
|
|
61
|
+
return false;
|
|
62
|
+
switch (id) {
|
|
63
|
+
case 'bold':
|
|
64
|
+
return editor.isActive('bold');
|
|
65
|
+
case 'italic':
|
|
66
|
+
return editor.isActive('italic');
|
|
67
|
+
case 'strikethrough':
|
|
68
|
+
return editor.isActive('strike');
|
|
69
|
+
case 'code':
|
|
70
|
+
return editor.isActive('code');
|
|
71
|
+
case 'h1':
|
|
72
|
+
return editor.isActive('heading', { level: 1 });
|
|
73
|
+
case 'h2':
|
|
74
|
+
return editor.isActive('heading', { level: 2 });
|
|
75
|
+
case 'h3':
|
|
76
|
+
return editor.isActive('heading', { level: 3 });
|
|
77
|
+
case 'quote':
|
|
78
|
+
return editor.isActive('blockquote');
|
|
79
|
+
case 'ul':
|
|
80
|
+
return editor.isActive('bulletList');
|
|
81
|
+
case 'ol':
|
|
82
|
+
return editor.isActive('orderedList');
|
|
83
|
+
case 'codeblock':
|
|
84
|
+
return editor.isActive('codeBlock');
|
|
85
|
+
default:
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Formatting toolbar.
|
|
91
|
+
* - WYSIWYG: calls Tiptap chain commands (toggleBold, etc.)
|
|
92
|
+
* - Raw: appends markdown syntax to the source
|
|
93
|
+
*/
|
|
94
|
+
export function Toolbar({ className }) {
|
|
95
|
+
const { activeView, setActiveView, markdownSource, setMarkdownSource, tiptapEditor, monacoEditor, } = useEditorContext();
|
|
96
|
+
// Force re-render when Tiptap selection or formatting state changes
|
|
97
|
+
const [, forceUpdate] = useReducer((c) => c + 1, 0);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!tiptapEditor)
|
|
100
|
+
return;
|
|
101
|
+
tiptapEditor.on('transaction', forceUpdate);
|
|
102
|
+
return () => {
|
|
103
|
+
tiptapEditor.off('transaction', forceUpdate);
|
|
104
|
+
};
|
|
105
|
+
}, [tiptapEditor]);
|
|
106
|
+
// ── Tiptap handler ─────────────────────────────────────
|
|
107
|
+
const handleTiptap = useCallback((id) => {
|
|
108
|
+
if (!tiptapEditor)
|
|
109
|
+
return;
|
|
110
|
+
const chain = tiptapEditor.chain().focus();
|
|
111
|
+
switch (id) {
|
|
112
|
+
case 'bold':
|
|
113
|
+
chain.toggleBold().run();
|
|
114
|
+
break;
|
|
115
|
+
case 'italic':
|
|
116
|
+
chain.toggleItalic().run();
|
|
117
|
+
break;
|
|
118
|
+
case 'strikethrough':
|
|
119
|
+
chain.toggleStrike().run();
|
|
120
|
+
break;
|
|
121
|
+
case 'code':
|
|
122
|
+
chain.toggleCode().run();
|
|
123
|
+
break;
|
|
124
|
+
case 'h1':
|
|
125
|
+
chain.toggleHeading({ level: 1 }).run();
|
|
126
|
+
break;
|
|
127
|
+
case 'h2':
|
|
128
|
+
chain.toggleHeading({ level: 2 }).run();
|
|
129
|
+
break;
|
|
130
|
+
case 'h3':
|
|
131
|
+
chain.toggleHeading({ level: 3 }).run();
|
|
132
|
+
break;
|
|
133
|
+
case 'quote':
|
|
134
|
+
chain.toggleBlockquote().run();
|
|
135
|
+
break;
|
|
136
|
+
case 'ul':
|
|
137
|
+
chain.toggleBulletList().run();
|
|
138
|
+
break;
|
|
139
|
+
case 'ol':
|
|
140
|
+
chain.toggleOrderedList().run();
|
|
141
|
+
break;
|
|
142
|
+
case 'codeblock':
|
|
143
|
+
chain.toggleCodeBlock().run();
|
|
144
|
+
break;
|
|
145
|
+
case 'hr':
|
|
146
|
+
chain.setHorizontalRule().run();
|
|
147
|
+
break;
|
|
148
|
+
case 'link': {
|
|
149
|
+
const url = window.prompt('URL:');
|
|
150
|
+
if (url) {
|
|
151
|
+
chain
|
|
152
|
+
.setLink?.({ href: url })
|
|
153
|
+
.run();
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}, [tiptapEditor]);
|
|
159
|
+
// ── Raw markdown handler ───────────────────────────────
|
|
160
|
+
const handleRaw = useCallback((id) => {
|
|
161
|
+
if (monacoEditor) {
|
|
162
|
+
// Use Monaco's selection API for proper wrap/insert behavior
|
|
163
|
+
const selection = monacoEditor.getSelection();
|
|
164
|
+
const model = monacoEditor.getModel();
|
|
165
|
+
if (!selection || !model)
|
|
166
|
+
return;
|
|
167
|
+
const selectedText = model.getValueInRange(selection);
|
|
168
|
+
const hasSelection = selectedText.length > 0;
|
|
169
|
+
let replacement = '';
|
|
170
|
+
let newCursorOffset = 0; // offset from start of replacement to place cursor
|
|
171
|
+
// Inline wrapping: wrap selection or insert placeholder
|
|
172
|
+
const wrapInline = (before, after, placeholder) => {
|
|
173
|
+
if (hasSelection) {
|
|
174
|
+
replacement = before + selectedText + after;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
replacement = before + placeholder + after;
|
|
178
|
+
// Select the placeholder text after insertion
|
|
179
|
+
newCursorOffset = before.length;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
// Block-level: prefix each selected line, or insert a new block
|
|
183
|
+
const prefixLines = (prefix, placeholder) => {
|
|
184
|
+
if (hasSelection) {
|
|
185
|
+
replacement = selectedText
|
|
186
|
+
.split('\n')
|
|
187
|
+
.map((line) => prefix + line)
|
|
188
|
+
.join('\n');
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
replacement = prefix + placeholder;
|
|
192
|
+
newCursorOffset = prefix.length;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
switch (id) {
|
|
196
|
+
case 'bold':
|
|
197
|
+
wrapInline('**', '**', 'bold text');
|
|
198
|
+
break;
|
|
199
|
+
case 'italic':
|
|
200
|
+
wrapInline('*', '*', 'italic text');
|
|
201
|
+
break;
|
|
202
|
+
case 'strikethrough':
|
|
203
|
+
wrapInline('~~', '~~', 'strikethrough');
|
|
204
|
+
break;
|
|
205
|
+
case 'code':
|
|
206
|
+
wrapInline('`', '`', 'code');
|
|
207
|
+
break;
|
|
208
|
+
case 'h1':
|
|
209
|
+
prefixLines('# ', 'Heading 1');
|
|
210
|
+
break;
|
|
211
|
+
case 'h2':
|
|
212
|
+
prefixLines('## ', 'Heading 2');
|
|
213
|
+
break;
|
|
214
|
+
case 'h3':
|
|
215
|
+
prefixLines('### ', 'Heading 3');
|
|
216
|
+
break;
|
|
217
|
+
case 'quote':
|
|
218
|
+
prefixLines('> ', 'Quote');
|
|
219
|
+
break;
|
|
220
|
+
case 'ul':
|
|
221
|
+
prefixLines('- ', 'Item');
|
|
222
|
+
break;
|
|
223
|
+
case 'ol':
|
|
224
|
+
prefixLines('1. ', 'Item');
|
|
225
|
+
break;
|
|
226
|
+
case 'codeblock': {
|
|
227
|
+
const inner = hasSelection ? selectedText : 'code';
|
|
228
|
+
replacement = '```\n' + inner + '\n```';
|
|
229
|
+
if (!hasSelection)
|
|
230
|
+
newCursorOffset = 4; // after ```\n
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
case 'hr': {
|
|
234
|
+
replacement = '\n---\n';
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case 'link': {
|
|
238
|
+
if (hasSelection) {
|
|
239
|
+
replacement = '[' + selectedText + '](url)';
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
replacement = '[link text](url)';
|
|
243
|
+
newCursorOffset = 1; // inside the []
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Apply the edit via Monaco's executeEdits for proper undo support
|
|
249
|
+
const range = selection;
|
|
250
|
+
monacoEditor.executeEdits('toolbar', [{ range, text: replacement }]);
|
|
251
|
+
// If no selection, select the placeholder text so user can type over it
|
|
252
|
+
if (!hasSelection && newCursorOffset > 0) {
|
|
253
|
+
const startPos = model.getPositionAt(model.getOffsetAt(range.getStartPosition()) + newCursorOffset);
|
|
254
|
+
const _placeholderLen = replacement.length -
|
|
255
|
+
newCursorOffset -
|
|
256
|
+
(replacement.length -
|
|
257
|
+
replacement.lastIndexOf(replacement.charAt(replacement.length - 1)));
|
|
258
|
+
// Just place cursor after the prefix
|
|
259
|
+
monacoEditor.setPosition(startPos);
|
|
260
|
+
}
|
|
261
|
+
monacoEditor.focus();
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
// Fallback: no Monaco instance, just append
|
|
265
|
+
let insertion = '';
|
|
266
|
+
switch (id) {
|
|
267
|
+
case 'bold':
|
|
268
|
+
insertion = '**bold text**';
|
|
269
|
+
break;
|
|
270
|
+
case 'italic':
|
|
271
|
+
insertion = '*italic text*';
|
|
272
|
+
break;
|
|
273
|
+
case 'strikethrough':
|
|
274
|
+
insertion = '~~strikethrough~~';
|
|
275
|
+
break;
|
|
276
|
+
case 'code':
|
|
277
|
+
insertion = '`code`';
|
|
278
|
+
break;
|
|
279
|
+
case 'h1':
|
|
280
|
+
insertion = '\n# Heading 1\n';
|
|
281
|
+
break;
|
|
282
|
+
case 'h2':
|
|
283
|
+
insertion = '\n## Heading 2\n';
|
|
284
|
+
break;
|
|
285
|
+
case 'h3':
|
|
286
|
+
insertion = '\n### Heading 3\n';
|
|
287
|
+
break;
|
|
288
|
+
case 'quote':
|
|
289
|
+
insertion = '\n> Quote\n';
|
|
290
|
+
break;
|
|
291
|
+
case 'ul':
|
|
292
|
+
insertion = '\n- Item\n';
|
|
293
|
+
break;
|
|
294
|
+
case 'ol':
|
|
295
|
+
insertion = '\n1. Item\n';
|
|
296
|
+
break;
|
|
297
|
+
case 'codeblock':
|
|
298
|
+
insertion = '\n```\ncode\n```\n';
|
|
299
|
+
break;
|
|
300
|
+
case 'hr':
|
|
301
|
+
insertion = '\n---\n';
|
|
302
|
+
break;
|
|
303
|
+
case 'link':
|
|
304
|
+
insertion = '[link text](url)';
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
if (insertion) {
|
|
308
|
+
setMarkdownSource(markdownSource + insertion);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}, [monacoEditor, markdownSource, setMarkdownSource]);
|
|
312
|
+
const handleAction = useCallback((id) => {
|
|
313
|
+
if (activeView === 'wysiwyg' && tiptapEditor) {
|
|
314
|
+
handleTiptap(id);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
handleRaw(id);
|
|
318
|
+
}
|
|
319
|
+
}, [activeView, tiptapEditor, handleTiptap, handleRaw]);
|
|
320
|
+
const groups = ['format', 'structure', 'insert'];
|
|
321
|
+
const isWysiwyg = activeView === 'wysiwyg' && tiptapEditor;
|
|
322
|
+
const isPreview = activeView === 'preview';
|
|
323
|
+
// Detect current heading template (WYSIWYG mode only)
|
|
324
|
+
const currentTemplate = isWysiwyg
|
|
325
|
+
? tiptapEditor.isActive('heading')
|
|
326
|
+
? (tiptapEditor.getAttributes('heading')?.dataTemplate ?? '')
|
|
327
|
+
: null
|
|
328
|
+
: null;
|
|
329
|
+
const handleTemplatePick = (value) => {
|
|
330
|
+
if (!tiptapEditor)
|
|
331
|
+
return;
|
|
332
|
+
if (value === '') {
|
|
333
|
+
// Clear template
|
|
334
|
+
tiptapEditor
|
|
335
|
+
.chain()
|
|
336
|
+
.focus()
|
|
337
|
+
.updateAttributes('heading', { dataTemplate: null, dataTemplateParams: null })
|
|
338
|
+
.run();
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
tiptapEditor.chain().focus().updateAttributes('heading', { dataTemplate: value }).run();
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const templateNames = getAvailableTemplates();
|
|
345
|
+
return (_jsxs("div", { className: `squisq-toolbar ${className || ''}`, role: "toolbar", "aria-label": "Formatting toolbar", children: [_jsx("div", { className: "squisq-toolbar-view-tabs", role: "tablist", "aria-label": "Editor view", children: VIEWS.map((view) => (_jsx("button", { role: "tab", "data-view": view.id, "aria-selected": activeView === view.id, className: `squisq-toolbar-view-tab${activeView === view.id ? ' squisq-toolbar-view-tab--active' : ''}`, onClick: () => setActiveView(view.id), title: `${view.label} (${view.shortcut})`, children: view.label }, view.id))) }), !isPreview && (_jsxs("div", { className: "squisq-toolbar-actions", children: [groups.map((group, gi) => (_jsxs("div", { className: "squisq-toolbar-group", children: [gi > 0 && _jsx("div", { className: "squisq-toolbar-separator" }), BUTTONS.filter((b) => b.group === group).map((btn) => {
|
|
346
|
+
const active = isWysiwyg ? isTiptapActive(tiptapEditor, btn.id) : false;
|
|
347
|
+
return (_jsx("button", { className: `squisq-toolbar-button${active ? ' squisq-toolbar-button--active' : ''}`, title: btn.title, onClick: () => handleAction(btn.id), "aria-label": btn.title, "aria-pressed": active, style: btn.iconStyle, children: btn.icon }, btn.id));
|
|
348
|
+
})] }, group))), currentTemplate !== null && (_jsxs(_Fragment, { children: [_jsx("div", { className: "squisq-toolbar-separator" }), _jsx("div", { className: "squisq-toolbar-group squisq-template-picker", children: _jsxs("label", { className: "squisq-template-picker-label", title: "Block template for this heading", children: ["Template:", _jsxs("select", { className: "squisq-template-picker-select", value: currentTemplate, onChange: (e) => handleTemplatePick(e.target.value), children: [_jsx("option", { value: "", children: "\u2014 none \u2014" }), templateNames.map((name) => (_jsx("option", { value: name, children: name }, name)))] })] }) })] }))] }))] }));
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=Toolbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.js","sourceRoot":"","sources":["../src/Toolbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ViewSwitcher
|
|
3
|
+
*
|
|
4
|
+
* Tab bar for switching between Raw, WYSIWYG, and Preview editor views.
|
|
5
|
+
*/
|
|
6
|
+
export interface ViewSwitcherProps {
|
|
7
|
+
/** Additional class name */
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Tab-style view switcher for the three editor modes.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ViewSwitcher({ className }: ViewSwitcherProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=ViewSwitcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ViewSwitcher.d.ts","sourceRoot":"","sources":["../src/ViewSwitcher.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,EAAE,iBAAiB,2CAuB5D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* ViewSwitcher
|
|
4
|
+
*
|
|
5
|
+
* Tab bar for switching between Raw, WYSIWYG, and Preview editor views.
|
|
6
|
+
*/
|
|
7
|
+
import { useEditorContext } from './EditorContext';
|
|
8
|
+
const VIEWS = [
|
|
9
|
+
{ id: 'raw', label: 'Raw', shortcut: '⌘1' },
|
|
10
|
+
{ id: 'wysiwyg', label: 'Editor', shortcut: '⌘2' },
|
|
11
|
+
{ id: 'preview', label: 'Preview', shortcut: '⌘3' },
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Tab-style view switcher for the three editor modes.
|
|
15
|
+
*/
|
|
16
|
+
export function ViewSwitcher({ className }) {
|
|
17
|
+
const { activeView, setActiveView } = useEditorContext();
|
|
18
|
+
return (_jsx("div", { className: `squisq-view-switcher ${className || ''}`, role: "tablist", "aria-label": "Editor view", children: VIEWS.map((view) => (_jsx("button", { role: "tab", "aria-selected": activeView === view.id, className: `squisq-view-tab ${activeView === view.id ? 'squisq-view-tab--active' : ''}`, onClick: () => setActiveView(view.id), title: `${view.label} (${view.shortcut})`, children: view.label }, view.id))) }));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=ViewSwitcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ViewSwitcher.js","sourceRoot":"","sources":["../src/ViewSwitcher.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAmB,MAAM,iBAAiB,CAAC;AAEpE,MAAM,KAAK,GAA0D;IACnE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC3C,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;IAClD,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;CACpD,CAAC;AAOF;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,SAAS,EAAqB;IAC3D,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAEzD,OAAO,CACL,cACE,SAAS,EAAE,wBAAwB,SAAS,IAAI,EAAE,EAAE,EACpD,IAAI,EAAC,SAAS,gBACH,aAAa,YAEvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,iBAEE,IAAI,EAAC,KAAK,mBACK,UAAU,KAAK,IAAI,CAAC,EAAE,EACrC,SAAS,EAAE,mBAAmB,UAAU,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,EAAE,EACvF,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EACrC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,GAAG,YAExC,IAAI,CAAC,KAAK,IAPN,IAAI,CAAC,EAAE,CAQL,CACV,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WysiwygEditor
|
|
3
|
+
*
|
|
4
|
+
* Tiptap-based rich text editor that provides a WYSIWYG editing experience
|
|
5
|
+
* for markdown content. Uses squisq's parseMarkdown/stringifyMarkdown for
|
|
6
|
+
* conversion rather than Tiptap's built-in HTML serialization, ensuring
|
|
7
|
+
* perfect fidelity with the markdown format.
|
|
8
|
+
*
|
|
9
|
+
* Includes extensions for GFM features: tables, task lists, strikethrough,
|
|
10
|
+
* and code blocks.
|
|
11
|
+
*/
|
|
12
|
+
export interface WysiwygEditorProps {
|
|
13
|
+
/** Placeholder text when editor is empty */
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
/** Additional class name for the container */
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Rich WYSIWYG markdown editor built on Tiptap (ProseMirror).
|
|
20
|
+
* Binds to the shared EditorContext for source synchronization.
|
|
21
|
+
*/
|
|
22
|
+
export declare function WysiwygEditor({ placeholder, className, }: WysiwygEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
/**
|
|
24
|
+
* Hook to access the Tiptap editor instance for toolbar commands.
|
|
25
|
+
* The WysiwygEditor must be mounted as a sibling or descendant.
|
|
26
|
+
*/
|
|
27
|
+
export { useEditor as useTiptapEditor } from '@tiptap/react';
|
|
28
|
+
//# sourceMappingURL=WysiwygEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WysiwygEditor.d.ts","sourceRoot":"","sources":["../src/WysiwygEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4BH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,WAA2C,EAC3C,SAAS,GACV,EAAE,kBAAkB,2CA0EpB;AAED;;;GAGG;AAEH,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,eAAe,CAAC"}
|