@bendyline/squisq-editor-react 1.2.2 → 1.4.0
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 +65 -1
- package/dist/EditorContext.d.ts.map +1 -1
- package/dist/EditorContext.js +31 -4
- package/dist/EditorContext.js.map +1 -1
- package/dist/EditorShell.d.ts +112 -2
- package/dist/EditorShell.d.ts.map +1 -1
- package/dist/EditorShell.js +95 -11
- package/dist/EditorShell.js.map +1 -1
- package/dist/ImageNodeView.d.ts.map +1 -1
- package/dist/ImageNodeView.js +12 -2
- package/dist/ImageNodeView.js.map +1 -1
- package/dist/MediaBin.d.ts +12 -1
- package/dist/MediaBin.d.ts.map +1 -1
- package/dist/MediaBin.js +29 -4
- package/dist/MediaBin.js.map +1 -1
- package/dist/MentionExtension.d.ts +22 -0
- package/dist/MentionExtension.d.ts.map +1 -0
- package/dist/MentionExtension.js +242 -0
- package/dist/MentionExtension.js.map +1 -0
- package/dist/RawEditor.d.ts +8 -1
- package/dist/RawEditor.d.ts.map +1 -1
- package/dist/RawEditor.js +167 -30
- package/dist/RawEditor.js.map +1 -1
- package/dist/TemplateAnnotation.d.ts.map +1 -1
- package/dist/TemplateAnnotation.js +4 -2
- package/dist/TemplateAnnotation.js.map +1 -1
- package/dist/Toolbar.d.ts +7 -1
- package/dist/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar.js +57 -18
- package/dist/Toolbar.js.map +1 -1
- package/dist/Tooltip.d.ts +10 -0
- package/dist/Tooltip.d.ts.map +1 -0
- package/dist/Tooltip.js +104 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/ViewSwitcher.d.ts +1 -1
- package/dist/ViewSwitcher.d.ts.map +1 -1
- package/dist/ViewSwitcher.js +10 -4
- package/dist/ViewSwitcher.js.map +1 -1
- package/dist/WysiwygEditor.d.ts +13 -2
- package/dist/WysiwygEditor.d.ts.map +1 -1
- package/dist/WysiwygEditor.js +239 -4
- package/dist/WysiwygEditor.js.map +1 -1
- package/dist/__tests__/detectMarkdown.test.d.ts +2 -0
- package/dist/__tests__/detectMarkdown.test.d.ts.map +1 -0
- package/dist/__tests__/detectMarkdown.test.js +69 -0
- package/dist/__tests__/detectMarkdown.test.js.map +1 -0
- package/dist/__tests__/fileKind.test.d.ts +2 -0
- package/dist/__tests__/fileKind.test.d.ts.map +1 -0
- package/dist/__tests__/fileKind.test.js +81 -0
- package/dist/__tests__/fileKind.test.js.map +1 -0
- package/dist/__tests__/mediaAttachmentFlow.test.d.ts +2 -0
- package/dist/__tests__/mediaAttachmentFlow.test.d.ts.map +1 -0
- package/dist/__tests__/mediaAttachmentFlow.test.js +99 -0
- package/dist/__tests__/mediaAttachmentFlow.test.js.map +1 -0
- package/dist/__tests__/tiptapBridge.test.js +49 -0
- package/dist/__tests__/tiptapBridge.test.js.map +1 -1
- package/dist/__tests__/tiptapImageRoundTrip.test.d.ts +2 -0
- package/dist/__tests__/tiptapImageRoundTrip.test.d.ts.map +1 -0
- package/dist/__tests__/tiptapImageRoundTrip.test.js +68 -0
- package/dist/__tests__/tiptapImageRoundTrip.test.js.map +1 -0
- package/dist/detectMarkdown.d.ts +20 -0
- package/dist/detectMarkdown.d.ts.map +1 -0
- package/dist/detectMarkdown.js +61 -0
- package/dist/detectMarkdown.js.map +1 -0
- package/dist/fileKind.d.ts +30 -0
- package/dist/fileKind.d.ts.map +1 -0
- package/dist/fileKind.js +123 -0
- package/dist/fileKind.js.map +1 -0
- package/dist/hooks/useFileDrop.d.ts.map +1 -1
- package/dist/hooks/useFileDrop.js +9 -7
- package/dist/hooks/useFileDrop.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mediaDragMime.d.ts +17 -0
- package/dist/mediaDragMime.d.ts.map +1 -0
- package/dist/mediaDragMime.js +22 -0
- package/dist/mediaDragMime.js.map +1 -0
- package/dist/tiptapBridge.d.ts.map +1 -1
- package/dist/tiptapBridge.js +99 -6
- package/dist/tiptapBridge.js.map +1 -1
- package/package.json +9 -7
- package/src/EditorContext.tsx +106 -3
- package/src/EditorShell.tsx +313 -21
- package/src/ImageNodeView.tsx +15 -2
- package/src/MediaBin.tsx +45 -4
- package/src/MentionExtension.tsx +258 -0
- package/src/RawEditor.tsx +193 -37
- package/src/TemplateAnnotation.ts +4 -2
- package/src/Toolbar.tsx +111 -48
- package/src/Tooltip.tsx +124 -0
- package/src/ViewSwitcher.tsx +15 -5
- package/src/WysiwygEditor.tsx +270 -5
- package/src/__tests__/detectMarkdown.test.ts +88 -0
- package/src/__tests__/fileKind.test.ts +96 -0
- package/src/__tests__/mediaAttachmentFlow.test.ts +110 -0
- package/src/__tests__/tiptapBridge.test.ts +58 -0
- package/src/__tests__/tiptapImageRoundTrip.test.ts +73 -0
- package/src/detectMarkdown.ts +62 -0
- package/src/fileKind.ts +134 -0
- package/src/hooks/useFileDrop.ts +10 -6
- package/src/index.ts +11 -0
- package/src/mediaDragMime.ts +32 -0
- package/src/styles/editor.css +214 -8
- package/src/tiptapBridge.ts +107 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageNodeView.js","sourceRoot":"","sources":["../src/ImageNodeView.tsx"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,KAAK,MAAM,yBAAyB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,SAAS,cAAc,CAAC,EAAE,IAAI,EAAiB;IAC7C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAoD,CAAC;IACtF,MAAM,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageNodeView.js","sourceRoot":"","sources":["../src/ImageNodeView.tsx"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,KAAK,MAAM,yBAAyB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,SAAS,cAAc,CAAC,EAAE,IAAI,EAAiB;IAC7C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAoD,CAAC;IACtF,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAC/D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,gBAAgB,KAAK,WAAW,CAAC;IAErD,MAAM,UAAU,GACd,GAAG;QACH,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QACxB,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACvB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QACxB,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;YAClC,cAAc,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,CAChC,CAAC,QAAQ,EAAE,EAAE;YACX,IAAI,CAAC,SAAS;gBAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC,EACD,GAAG,EAAE;YACH,IAAI,CAAC,SAAS;gBAAE,cAAc,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC,CACF,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC;IAErC,OAAO,CACL,KAAC,eAAe,IAAC,EAAE,EAAC,QAAQ,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YACvD,cACE,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,GAAG,IAAI,EAAE,EACd,KAAK,EAAE,KAAK,IAAI,SAAS,EACzB,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,cAAc,EAChF,KAAK,EACH,WAAW;gBACT,CAAC,CAAC;oBACE,QAAQ,EAAE,OAAO;oBACjB,SAAS,EAAE,OAAO;oBAClB,KAAK,EAAE,MAAM;oBACb,MAAM,EAAE,MAAM;oBACd,SAAS,EAAE,SAAS;oBACpB,OAAO,EAAE,OAAO;iBACjB;gBACH,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAE5D,GACc,CACnB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC,MAAM,CAAC;IACjD,WAAW;QACT,OAAO,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC;CACF,CAAC,CAAC"}
|
package/dist/MediaBin.d.ts
CHANGED
|
@@ -13,6 +13,17 @@ export interface MediaBinProps {
|
|
|
13
13
|
isDark: boolean;
|
|
14
14
|
/** Incremented externally to signal a re-scan of the media list */
|
|
15
15
|
refreshKey?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Fired after a successful upload via the MediaBin's own "+ Upload"
|
|
18
|
+
* button. `relativePath` is what the provider returned (the same
|
|
19
|
+
* value embedded in markdown refs, e.g. `attachments/xyz.png`);
|
|
20
|
+
* `name` is the uploader-chosen filename before storage renamed
|
|
21
|
+
* it. Consumers typically use this to insert a markdown image ref
|
|
22
|
+
* at the editor's cursor so the file actually participates in the
|
|
23
|
+
* outgoing message — previously files went to the bin and nowhere
|
|
24
|
+
* else, leaving the message body empty when the user hit Send.
|
|
25
|
+
*/
|
|
26
|
+
onMediaUploaded?: (relativePath: string, name: string, mimeType: string) => void | Promise<void>;
|
|
16
27
|
}
|
|
17
|
-
export declare function MediaBin({ mediaProvider, isDark, refreshKey }: MediaBinProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function MediaBin({ mediaProvider, isDark, refreshKey, onMediaUploaded }: MediaBinProps): import("react/jsx-runtime").JSX.Element;
|
|
18
29
|
//# sourceMappingURL=MediaBin.d.ts.map
|
package/dist/MediaBin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaBin.d.ts","sourceRoot":"","sources":["../src/MediaBin.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"MediaBin.d.ts","sourceRoot":"","sources":["../src/MediaBin.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,2BAA2B,CAAC;AAO3E,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClG;AA6BD,wBAAgB,QAAQ,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,EAAE,aAAa,2CAwM7F"}
|
package/dist/MediaBin.js
CHANGED
|
@@ -7,6 +7,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
7
7
|
* and provides an upload button to add new media.
|
|
8
8
|
*/
|
|
9
9
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
10
|
+
import { SQUISQ_MEDIA_MIME } from './mediaDragMime';
|
|
10
11
|
// ============================================
|
|
11
12
|
// Helpers
|
|
12
13
|
// ============================================
|
|
@@ -36,7 +37,7 @@ function isImageMime(mimeType) {
|
|
|
36
37
|
// ============================================
|
|
37
38
|
// Component
|
|
38
39
|
// ============================================
|
|
39
|
-
export function MediaBin({ mediaProvider, isDark, refreshKey }) {
|
|
40
|
+
export function MediaBin({ mediaProvider, isDark, refreshKey, onMediaUploaded }) {
|
|
40
41
|
const [entries, setEntries] = useState([]);
|
|
41
42
|
const [thumbUrls, setThumbUrls] = useState({});
|
|
42
43
|
const [loading, setLoading] = useState(false);
|
|
@@ -99,9 +100,19 @@ export function MediaBin({ mediaProvider, isDark, refreshKey }) {
|
|
|
99
100
|
try {
|
|
100
101
|
for (let i = 0; i < files.length; i++) {
|
|
101
102
|
const file = files[i];
|
|
103
|
+
if (!file)
|
|
104
|
+
continue;
|
|
102
105
|
const buffer = await file.arrayBuffer();
|
|
103
106
|
const mimeType = file.type || 'application/octet-stream';
|
|
104
|
-
await mediaProvider.addMedia(file.name, buffer, mimeType);
|
|
107
|
+
const relativePath = await mediaProvider.addMedia(file.name, buffer, mimeType);
|
|
108
|
+
if (onMediaUploaded) {
|
|
109
|
+
try {
|
|
110
|
+
await onMediaUploaded(relativePath, file.name, mimeType);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
/* callback is a nice-to-have; don't abort the upload batch */
|
|
114
|
+
}
|
|
115
|
+
}
|
|
105
116
|
}
|
|
106
117
|
// Re-scan
|
|
107
118
|
const list = await mediaProvider.listMedia();
|
|
@@ -131,11 +142,25 @@ export function MediaBin({ mediaProvider, isDark, refreshKey }) {
|
|
|
131
142
|
if (fileInputRef.current)
|
|
132
143
|
fileInputRef.current.value = '';
|
|
133
144
|
}
|
|
134
|
-
}, [mediaProvider]);
|
|
145
|
+
}, [mediaProvider, onMediaUploaded]);
|
|
135
146
|
return (_jsxs("div", { className: `squisq-media-bin${isDark ? ' squisq-media-bin--dark' : ''}`, children: [_jsxs("div", { className: "squisq-media-bin-header", children: [_jsxs("span", { className: "squisq-media-bin-title", children: ["Files ", entries.length > 0 && `(${entries.length})`] }), _jsx("button", { className: "squisq-media-bin-upload", onClick: handleUploadClick, disabled: !mediaProvider || loading, title: mediaProvider ? 'Upload files' : 'Load a content zip or select a storage slot first', children: "+ Upload" })] }), _jsxs("div", { className: "squisq-media-bin-list", children: [!mediaProvider && (_jsxs("div", { className: "squisq-media-bin-empty", children: ["No media context.", _jsx("br", {}), "Load a content zip or select a storage slot."] })), mediaProvider && entries.length === 0 && !loading && (_jsx("div", { className: "squisq-media-bin-empty", children: "No files yet." })), entries.map((entry) => {
|
|
136
147
|
const thumb = thumbUrls[entry.name];
|
|
137
148
|
const basename = entry.name.includes('/') ? entry.name.split('/').pop() : entry.name;
|
|
138
|
-
|
|
149
|
+
const isImage = isImageMime(entry.mimeType);
|
|
150
|
+
const altText = basename.replace(/\.[^.]+$/, '').replace(/[-_]/g, ' ');
|
|
151
|
+
const handleDragStart = (e) => {
|
|
152
|
+
if (!isImage)
|
|
153
|
+
return;
|
|
154
|
+
const payload = JSON.stringify({
|
|
155
|
+
name: entry.name,
|
|
156
|
+
mimeType: entry.mimeType,
|
|
157
|
+
alt: altText,
|
|
158
|
+
});
|
|
159
|
+
e.dataTransfer.setData(SQUISQ_MEDIA_MIME, payload);
|
|
160
|
+
e.dataTransfer.setData('text/plain', ``);
|
|
161
|
+
e.dataTransfer.effectAllowed = 'copy';
|
|
162
|
+
};
|
|
163
|
+
return (_jsxs("div", { className: "squisq-media-bin-item", title: `${entry.name}\n${entry.mimeType}\n${formatSize(entry.size)}`, draggable: isImage, onDragStart: handleDragStart, children: [thumb ? (_jsx("img", { src: thumb, alt: basename, className: "squisq-media-bin-thumb", draggable: false })) : (_jsx("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) })), _jsxs("div", { className: "squisq-media-bin-meta", children: [_jsx("div", { className: "squisq-media-bin-name", children: basename }), _jsx("div", { className: "squisq-media-bin-size", children: formatSize(entry.size) })] })] }, entry.name));
|
|
139
164
|
})] }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, style: { display: 'none' }, onChange: handleFileChange })] }));
|
|
140
165
|
}
|
|
141
166
|
//# sourceMappingURL=MediaBin.js.map
|
package/dist/MediaBin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaBin.js","sourceRoot":"","sources":["../src/MediaBin.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MediaBin.js","sourceRoot":"","sources":["../src/MediaBin.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MentionExtension
|
|
3
|
+
*
|
|
4
|
+
* Tiptap mention configuration paired with a small absolutely-positioned
|
|
5
|
+
* suggestion popover. Shares a caller-supplied async provider (see
|
|
6
|
+
* `MentionProvider` in EditorContext) with the Monaco `@` completion
|
|
7
|
+
* provider in `RawEditor`, so both editing modes surface the same roster.
|
|
8
|
+
*
|
|
9
|
+
* The mention chip renders as `<span data-mention data-kind data-id
|
|
10
|
+
* data-label class="mention">@Label</span>`, matching the wire format that
|
|
11
|
+
* `tiptapBridge` emits when converting markdown → Tiptap HTML. On serialize
|
|
12
|
+
* back to markdown, the bridge emits `@[Label](kind:id)`.
|
|
13
|
+
*/
|
|
14
|
+
import type { MentionProvider } from './EditorContext';
|
|
15
|
+
/**
|
|
16
|
+
* Build the Tiptap mention extension for an editor. The returned extension
|
|
17
|
+
* captures a reference to `getProvider` at configure-time and calls it on
|
|
18
|
+
* every keystroke — keep the reference stable so we don't recreate the
|
|
19
|
+
* editor just to change who answers the `@` query.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildMentionExtension(getProvider: () => MentionProvider | null): import("@tiptap/core").Node<import("@tiptap/extension-mention").MentionOptions<any, import("@tiptap/extension-mention").MentionNodeAttrs>, any>;
|
|
22
|
+
//# sourceMappingURL=MentionExtension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionExtension.d.ts","sourceRoot":"","sources":["../src/MentionExtension.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAkBzE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,eAAe,GAAG,IAAI,mJAwF9E"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MentionExtension
|
|
3
|
+
*
|
|
4
|
+
* Tiptap mention configuration paired with a small absolutely-positioned
|
|
5
|
+
* suggestion popover. Shares a caller-supplied async provider (see
|
|
6
|
+
* `MentionProvider` in EditorContext) with the Monaco `@` completion
|
|
7
|
+
* provider in `RawEditor`, so both editing modes surface the same roster.
|
|
8
|
+
*
|
|
9
|
+
* The mention chip renders as `<span data-mention data-kind data-id
|
|
10
|
+
* data-label class="mention">@Label</span>`, matching the wire format that
|
|
11
|
+
* `tiptapBridge` emits when converting markdown → Tiptap HTML. On serialize
|
|
12
|
+
* back to markdown, the bridge emits `@[Label](kind:id)`.
|
|
13
|
+
*/
|
|
14
|
+
import Mention from '@tiptap/extension-mention';
|
|
15
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
16
|
+
/**
|
|
17
|
+
* Fallback namespace for defensive code paths — used when a mention node
|
|
18
|
+
* somehow lacks a `kind` attribute (e.g. legacy HTML parsed without one).
|
|
19
|
+
* Inserts from the suggestion popover always carry the candidate's own
|
|
20
|
+
* `scheme`, so this only surfaces for malformed/legacy content.
|
|
21
|
+
*/
|
|
22
|
+
const FALLBACK_KIND = 'mention';
|
|
23
|
+
/**
|
|
24
|
+
* Build the Tiptap mention extension for an editor. The returned extension
|
|
25
|
+
* captures a reference to `getProvider` at configure-time and calls it on
|
|
26
|
+
* every keystroke — keep the reference stable so we don't recreate the
|
|
27
|
+
* editor just to change who answers the `@` query.
|
|
28
|
+
*/
|
|
29
|
+
export function buildMentionExtension(getProvider) {
|
|
30
|
+
return Mention.configure({
|
|
31
|
+
HTMLAttributes: {
|
|
32
|
+
class: 'mention',
|
|
33
|
+
'data-mention': 'true',
|
|
34
|
+
},
|
|
35
|
+
renderHTML({ options, node }) {
|
|
36
|
+
const label = node.attrs.label ?? node.attrs.id ?? '';
|
|
37
|
+
const id = node.attrs.id ?? '';
|
|
38
|
+
const kind = node.attrs.kind ?? FALLBACK_KIND;
|
|
39
|
+
return [
|
|
40
|
+
'span',
|
|
41
|
+
{
|
|
42
|
+
...options.HTMLAttributes,
|
|
43
|
+
'data-kind': kind,
|
|
44
|
+
'data-id': id,
|
|
45
|
+
'data-label': label,
|
|
46
|
+
},
|
|
47
|
+
`@${label}`,
|
|
48
|
+
];
|
|
49
|
+
},
|
|
50
|
+
renderText({ node }) {
|
|
51
|
+
const label = node.attrs.label ?? node.attrs.id ?? '';
|
|
52
|
+
const id = node.attrs.id ?? '';
|
|
53
|
+
const kind = node.attrs.kind ?? FALLBACK_KIND;
|
|
54
|
+
return `@[${label}](${kind}:${id})`;
|
|
55
|
+
},
|
|
56
|
+
}).extend({
|
|
57
|
+
addAttributes() {
|
|
58
|
+
return {
|
|
59
|
+
id: {
|
|
60
|
+
default: null,
|
|
61
|
+
parseHTML: (el) => el.getAttribute('data-id'),
|
|
62
|
+
renderHTML: (attrs) => (attrs.id ? { 'data-id': attrs.id } : {}),
|
|
63
|
+
},
|
|
64
|
+
label: {
|
|
65
|
+
default: null,
|
|
66
|
+
parseHTML: (el) => el.getAttribute('data-label'),
|
|
67
|
+
renderHTML: (attrs) => (attrs.label ? { 'data-label': attrs.label } : {}),
|
|
68
|
+
},
|
|
69
|
+
kind: {
|
|
70
|
+
default: FALLBACK_KIND,
|
|
71
|
+
parseHTML: (el) => el.getAttribute('data-kind') ?? FALLBACK_KIND,
|
|
72
|
+
renderHTML: (attrs) => ({ 'data-kind': attrs.kind ?? FALLBACK_KIND }),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
addOptions() {
|
|
77
|
+
return {
|
|
78
|
+
...(this.parent?.() ?? {}),
|
|
79
|
+
suggestion: {
|
|
80
|
+
char: '@',
|
|
81
|
+
// Custom plugin key so the mention suggestion doesn't collide
|
|
82
|
+
// with any future `:` or `/` popovers.
|
|
83
|
+
pluginKey: new PluginKey('mentionSuggestion'),
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
command: ({ editor, range, props }) => {
|
|
86
|
+
const id = props?.id ?? '';
|
|
87
|
+
const label = props?.label ?? id;
|
|
88
|
+
const kind = props?.kind ?? FALLBACK_KIND;
|
|
89
|
+
editor
|
|
90
|
+
.chain()
|
|
91
|
+
.focus()
|
|
92
|
+
.insertContentAt(range, [
|
|
93
|
+
{
|
|
94
|
+
type: 'mention',
|
|
95
|
+
attrs: { id, label, kind },
|
|
96
|
+
},
|
|
97
|
+
{ type: 'text', text: ' ' },
|
|
98
|
+
])
|
|
99
|
+
.run();
|
|
100
|
+
},
|
|
101
|
+
items: async ({ query }) => {
|
|
102
|
+
const provider = getProvider();
|
|
103
|
+
if (!provider)
|
|
104
|
+
return [];
|
|
105
|
+
try {
|
|
106
|
+
return await provider(query);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
render: renderSuggestionFactory(),
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Lightweight suggestion popover. Uses a plain absolutely-positioned div
|
|
120
|
+
* anchored to the caret rect — no tippy.js needed. Keyboard nav handled via
|
|
121
|
+
* the `onKeyDown` hook Tiptap wires up.
|
|
122
|
+
*/
|
|
123
|
+
function renderSuggestionFactory() {
|
|
124
|
+
return () => {
|
|
125
|
+
let container = null;
|
|
126
|
+
let state = { items: [], selected: 0 };
|
|
127
|
+
let currentProps = null;
|
|
128
|
+
const update = () => {
|
|
129
|
+
if (!container || !currentProps)
|
|
130
|
+
return;
|
|
131
|
+
container.innerHTML = '';
|
|
132
|
+
if (state.items.length === 0) {
|
|
133
|
+
container.style.display = 'none';
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
container.style.display = 'block';
|
|
137
|
+
for (let i = 0; i < state.items.length; i++) {
|
|
138
|
+
const item = state.items[i];
|
|
139
|
+
const btn = document.createElement('button');
|
|
140
|
+
btn.type = 'button';
|
|
141
|
+
btn.className = 'squisq-mention-item' + (i === state.selected ? ' is-selected' : '');
|
|
142
|
+
btn.dataset.index = String(i);
|
|
143
|
+
btn.innerHTML = '';
|
|
144
|
+
const label = document.createElement('span');
|
|
145
|
+
label.className = 'squisq-mention-label';
|
|
146
|
+
label.textContent = item.label;
|
|
147
|
+
btn.appendChild(label);
|
|
148
|
+
if (item.description) {
|
|
149
|
+
const desc = document.createElement('span');
|
|
150
|
+
desc.className = 'squisq-mention-desc';
|
|
151
|
+
desc.textContent = item.description;
|
|
152
|
+
btn.appendChild(desc);
|
|
153
|
+
}
|
|
154
|
+
btn.addEventListener('mousedown', (ev) => {
|
|
155
|
+
ev.preventDefault();
|
|
156
|
+
selectAt(i);
|
|
157
|
+
});
|
|
158
|
+
container.appendChild(btn);
|
|
159
|
+
}
|
|
160
|
+
positionTo(container, currentProps.clientRect);
|
|
161
|
+
};
|
|
162
|
+
const selectAt = (index) => {
|
|
163
|
+
const item = state.items[index];
|
|
164
|
+
if (!item || !currentProps)
|
|
165
|
+
return;
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
167
|
+
const command = currentProps.command;
|
|
168
|
+
if (typeof command === 'function') {
|
|
169
|
+
command({ id: item.id, label: item.label, kind: item.scheme });
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
return {
|
|
173
|
+
onStart: (props) => {
|
|
174
|
+
currentProps = props;
|
|
175
|
+
state = { items: props.items ?? [], selected: 0 };
|
|
176
|
+
if (!container) {
|
|
177
|
+
container = document.createElement('div');
|
|
178
|
+
container.className = 'squisq-mention-popover';
|
|
179
|
+
container.style.position = 'absolute';
|
|
180
|
+
container.style.zIndex = '10000';
|
|
181
|
+
document.body.appendChild(container);
|
|
182
|
+
}
|
|
183
|
+
update();
|
|
184
|
+
},
|
|
185
|
+
onUpdate: (props) => {
|
|
186
|
+
currentProps = props;
|
|
187
|
+
if (Array.isArray(props.items)) {
|
|
188
|
+
state = { items: props.items, selected: 0 };
|
|
189
|
+
}
|
|
190
|
+
update();
|
|
191
|
+
},
|
|
192
|
+
onKeyDown: ({ event }) => {
|
|
193
|
+
if (!state.items.length)
|
|
194
|
+
return false;
|
|
195
|
+
if (event.key === 'ArrowDown') {
|
|
196
|
+
state.selected = (state.selected + 1) % state.items.length;
|
|
197
|
+
update();
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
if (event.key === 'ArrowUp') {
|
|
201
|
+
state.selected = (state.selected - 1 + state.items.length) % state.items.length;
|
|
202
|
+
update();
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
if (event.key === 'Enter' || event.key === 'Tab') {
|
|
206
|
+
selectAt(state.selected);
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
if (event.key === 'Escape') {
|
|
210
|
+
state = { items: [], selected: 0 };
|
|
211
|
+
update();
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
},
|
|
216
|
+
onExit: () => {
|
|
217
|
+
if (container?.parentNode)
|
|
218
|
+
container.parentNode.removeChild(container);
|
|
219
|
+
container = null;
|
|
220
|
+
currentProps = null;
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function positionTo(el, clientRect) {
|
|
226
|
+
const rect = clientRect?.();
|
|
227
|
+
if (!rect)
|
|
228
|
+
return;
|
|
229
|
+
// Anchor just below the caret; fall back to above when there's no room.
|
|
230
|
+
const viewportH = window.innerHeight;
|
|
231
|
+
const below = rect.bottom + 4;
|
|
232
|
+
const estH = Math.min(240, el.offsetHeight || 200);
|
|
233
|
+
const fitsBelow = below + estH < viewportH;
|
|
234
|
+
el.style.left = `${rect.left + window.scrollX}px`;
|
|
235
|
+
if (fitsBelow) {
|
|
236
|
+
el.style.top = `${below + window.scrollY}px`;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
el.style.top = `${rect.top + window.scrollY - estH - 4}px`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=MentionExtension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionExtension.js","sourceRoot":"","sources":["../src/MentionExtension.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,OAAO,MAAM,2BAA2B,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAO7C;;;;;GAKG;AACH,MAAM,aAAa,GAAG,SAAS,CAAC;AAOhC;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAyC;IAC7E,OAAO,OAAO,CAAC,SAAS,CAAC;QACvB,cAAc,EAAE;YACd,KAAK,EAAE,SAAS;YAChB,cAAc,EAAE,MAAM;SACvB;QACD,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;YAC1B,MAAM,KAAK,GACR,IAAI,CAAC,KAAK,CAAC,KAA4B,IAAK,IAAI,CAAC,KAAK,CAAC,EAAyB,IAAI,EAAE,CAAC;YAC1F,MAAM,EAAE,GAAI,IAAI,CAAC,KAAK,CAAC,EAAyB,IAAI,EAAE,CAAC;YACvD,MAAM,IAAI,GAAI,IAAI,CAAC,KAAK,CAAC,IAA2B,IAAI,aAAa,CAAC;YACtE,OAAO;gBACL,MAAM;gBACN;oBACE,GAAG,OAAO,CAAC,cAAc;oBACzB,WAAW,EAAE,IAAI;oBACjB,SAAS,EAAE,EAAE;oBACb,YAAY,EAAE,KAAK;iBACpB;gBACD,IAAI,KAAK,EAAE;aACZ,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,EAAE,IAAI,EAAE;YACjB,MAAM,KAAK,GACR,IAAI,CAAC,KAAK,CAAC,KAA4B,IAAK,IAAI,CAAC,KAAK,CAAC,EAAyB,IAAI,EAAE,CAAC;YAC1F,MAAM,EAAE,GAAI,IAAI,CAAC,KAAK,CAAC,EAAyB,IAAI,EAAE,CAAC;YACvD,MAAM,IAAI,GAAI,IAAI,CAAC,KAAK,CAAC,IAA2B,IAAI,aAAa,CAAC;YACtE,OAAO,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,CAAC;QACtC,CAAC;KACF,CAAC,CAAC,MAAM,CAAC;QACR,aAAa;YACX,OAAO;gBACL,EAAE,EAAE;oBACF,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC;oBAC7C,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACjE;gBACD,KAAK,EAAE;oBACL,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC;oBAChD,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC1E;gBACD,IAAI,EAAE;oBACJ,OAAO,EAAE,aAAa;oBACtB,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,aAAa;oBAChE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC;iBACtE;aACF,CAAC;QACJ,CAAC;QACD,UAAU;YACR,OAAO;gBACL,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC;gBAC1B,UAAU,EAAE;oBACV,IAAI,EAAE,GAAG;oBACT,8DAA8D;oBAC9D,uCAAuC;oBACvC,SAAS,EAAE,IAAI,SAAS,CAAC,mBAAmB,CAAC;oBAC7C,8DAA8D;oBAC9D,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAgD,EAAE,EAAE;wBAClF,MAAM,EAAE,GAAI,KAAK,EAAE,EAAoB,IAAI,EAAE,CAAC;wBAC9C,MAAM,KAAK,GAAI,KAAK,EAAE,KAAuB,IAAI,EAAE,CAAC;wBACpD,MAAM,IAAI,GAAI,KAAK,EAAE,IAA2B,IAAI,aAAa,CAAC;wBAClE,MAAM;6BACH,KAAK,EAAE;6BACP,KAAK,EAAE;6BACP,eAAe,CAAC,KAAK,EAAE;4BACtB;gCACE,IAAI,EAAE,SAAS;gCACf,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;6BAC3B;4BACD,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE;yBAC5B,CAAC;6BACD,GAAG,EAAE,CAAC;oBACX,CAAC;oBACD,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAqB,EAAE,EAAE;wBAC5C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;wBAC/B,IAAI,CAAC,QAAQ;4BAAE,OAAO,EAAE,CAAC;wBACzB,IAAI,CAAC;4BACH,OAAO,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;wBAC/B,CAAC;wBAAC,MAAM,CAAC;4BACP,OAAO,EAAE,CAAC;wBACZ,CAAC;oBACH,CAAC;oBACD,MAAM,EAAE,uBAAuB,EAAE;iBAClC;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,uBAAuB;IAC9B,OAAO,GAAG,EAAE;QACV,IAAI,SAAS,GAA0B,IAAI,CAAC;QAC5C,IAAI,KAAK,GAAoB,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACxD,IAAI,YAAY,GAA2B,IAAI,CAAC;QAEhD,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY;gBAAE,OAAO;YACxC,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;YACzB,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;gBACjC,OAAO;YACT,CAAC;YACD,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;YAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC5B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAC7C,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC;gBACpB,GAAG,CAAC,SAAS,GAAG,qBAAqB,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrF,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC9B,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;gBACnB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBAC7C,KAAK,CAAC,SAAS,GAAG,sBAAsB,CAAC;gBACzC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;gBAC/B,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gBACvB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;oBAC5C,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC;oBACvC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;oBACpC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;gBACD,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE;oBACvC,EAAE,CAAC,cAAc,EAAE,CAAC;oBACpB,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACd,CAAC,CAAC,CAAC;gBACH,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;YAED,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,EAAE;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY;gBAAE,OAAO;YACnC,8DAA8D;YAC9D,MAAM,OAAO,GAAI,YAAoB,CAAC,OAAO,CAAC;YAC9C,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAClC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,KAAsB,EAAE,EAAE;gBAClC,YAAY,GAAG,KAAK,CAAC;gBACrB,KAAK,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;oBAC1C,SAAS,CAAC,SAAS,GAAG,wBAAwB,CAAC;oBAC/C,SAAS,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;oBACtC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC;oBACjC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;gBACvC,CAAC;gBACD,MAAM,EAAE,CAAC;YACX,CAAC;YACD,QAAQ,EAAE,CAAC,KAAsB,EAAE,EAAE;gBACnC,YAAY,GAAG,KAAK,CAAC;gBACrB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/B,KAAK,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBAC9C,CAAC;gBACD,MAAM,EAAE,CAAC;YACX,CAAC;YACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAA4B,EAAE,EAAE;gBACjD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM;oBAAE,OAAO,KAAK,CAAC;gBACtC,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;oBAC9B,KAAK,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC3D,MAAM,EAAE,CAAC;oBACT,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC5B,KAAK,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;oBAChF,MAAM,EAAE,CAAC;oBACT,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;oBACjD,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACzB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC3B,KAAK,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;oBACnC,MAAM,EAAE,CAAC;oBACT,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,EAAE,GAAG,EAAE;gBACX,IAAI,SAAS,EAAE,UAAU;oBAAE,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;gBACvE,SAAS,GAAG,IAAI,CAAC;gBACjB,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CACjB,EAAkB,EAClB,UAAqD;IAErD,MAAM,IAAI,GAAG,UAAU,EAAE,EAAE,CAAC;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,wEAAwE;IACxE,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC;IAClD,IAAI,SAAS,EAAE,CAAC;QACd,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
package/dist/RawEditor.d.ts
CHANGED
|
@@ -16,10 +16,17 @@ export interface RawEditorProps {
|
|
|
16
16
|
wordWrap?: 'on' | 'off' | 'wordWrapColumn' | 'bounded';
|
|
17
17
|
/** Additional class name for the container */
|
|
18
18
|
className?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Chat-composer mode: Enter fires this callback (submit) and Cmd/Ctrl+Enter
|
|
21
|
+
* inserts a newline. When undefined, behaves normally.
|
|
22
|
+
*/
|
|
23
|
+
submitOnEnter?: () => void;
|
|
24
|
+
/** Make Monaco read-only (no edits, no cursor blink). */
|
|
25
|
+
readOnly?: boolean;
|
|
19
26
|
}
|
|
20
27
|
/**
|
|
21
28
|
* Raw markdown editor using Monaco Editor.
|
|
22
29
|
* Binds to the shared EditorContext for source synchronization.
|
|
23
30
|
*/
|
|
24
|
-
export declare function RawEditor({ theme, minimap, fontSize, wordWrap, className, }: RawEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function RawEditor({ theme, minimap, fontSize, wordWrap, className, submitOnEnter, readOnly, }: RawEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
25
32
|
//# sourceMappingURL=RawEditor.d.ts.map
|
package/dist/RawEditor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RawEditor.d.ts","sourceRoot":"","sources":["../src/RawEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"RawEditor.d.ts","sourceRoot":"","sources":["../src/RawEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACvD,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAY,EACZ,OAAe,EACf,QAAa,EACb,QAAe,EACf,SAAS,EACT,aAAa,EACb,QAAgB,GACjB,EAAE,cAAc,2CAgQhB"}
|