@lobehub/editor 4.19.2 → 4.20.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/es/index.d.ts +4 -1
- package/es/index.js +2 -1
- package/es/plugins/collaboration/index.d.ts +3 -0
- package/es/plugins/collaboration/react/ReactCollaborationPlugin.d.ts +7 -0
- package/es/plugins/collaboration/react/ReactCollaborationPlugin.js +89 -0
- package/es/plugins/collaboration/react/index.d.ts +2 -0
- package/es/plugins/collaboration/react/type.d.ts +61 -0
- package/es/plugins/collaboration/utils.d.ts +13 -0
- package/es/plugins/collaboration/utils.js +85 -0
- package/es/plugins/slash/react/components/DefaultSlashMenu.js +10 -4
- package/es/react/Editor/Editor.js +8 -2
- package/es/react/Editor/type.d.ts +2 -0
- package/es/react.d.ts +2 -1
- package/package.json +4 -2
package/es/index.d.ts
CHANGED
|
@@ -34,6 +34,9 @@ import { bundledLanguagesInfo } from "./plugins/codeblock/index.js";
|
|
|
34
34
|
import { INSERT_CODEMIRROR_COMMAND, SELECT_AFTER_CODEMIRROR_COMMAND, SELECT_BEFORE_CODEMIRROR_COMMAND } from "./plugins/codemirror-block/command/index.js";
|
|
35
35
|
import { CodemirrorPlugin, CodemirrorPluginOptions } from "./plugins/codemirror-block/plugin/index.js";
|
|
36
36
|
import { ReactCodemirrorPlugin } from "./plugins/codemirror-block/react/ReactCodemirrorNode.js";
|
|
37
|
+
import { CollaborationUser } from "./plugins/collaboration/utils.js";
|
|
38
|
+
import { CollaborationProviderFactory, EditorCollaborationConfig, ReactCollaborationPluginProps } from "./plugins/collaboration/react/type.js";
|
|
39
|
+
import { ReactCollaborationPlugin } from "./plugins/collaboration/react/ReactCollaborationPlugin.js";
|
|
37
40
|
import { INSERT_HEADING_COMMAND, INSERT_QUOTE_COMMAND } from "./plugins/common/command/index.js";
|
|
38
41
|
import { $createCursorNode, $isCardLikeElementNode, $isCursorNode, CardLikeElementNode, cursorNodeSerialized } from "./plugins/common/node/cursor.js";
|
|
39
42
|
import { CommonPlugin, CommonPluginOptions } from "./plugins/common/plugin/index.js";
|
|
@@ -122,4 +125,4 @@ declare function enableHotReload(): void;
|
|
|
122
125
|
*/
|
|
123
126
|
declare function disableHotReload(): void;
|
|
124
127
|
//#endregion
|
|
125
|
-
export { $closest, $closestNodeType, $createCursorNode, $getNearestNodeFromDOMNode, $getNodeFromDOMNode, $isCardLikeElementNode, $isCursorNode, ANCHOR_PADDING_CSS_VAR, AutoCompletePlugin, BlockDragTarget, BlockMenuService, BlockMovePayload, BlockPlugin, BlockPluginOptions, CONTENT_BLOCKS_DATA_TYPE, CardLikeElementNode, CodePlugin, CodeblockPlugin, CodeblockPluginOptions, CodemirrorPlugin, CodemirrorPluginOptions, CommonPlugin, CommonPluginOptions, ContentBlock, ContentBlocksDataSource, ContentBlocksPlugin, ContentBlocksPluginOptions, DEFAULT_BLOCK_ANCHOR_PADDING, DEFAULT_HEADLESS_EDITOR_PLUGINS, DOM_DOCUMENT_FRAGMENT_TYPE, DOM_DOCUMENT_TYPE, DOM_ELEMENT_TYPE, DOM_TEXT_TYPE, DataSource, DiffAction, EDITOR_THEME_KEY, ExtractContentBlocksOptions, FileContentBlock, FileListItem, FilePlugin, FilePluginOptions, GET_MARKDOWN_SELECTION_COMMAND, HIDE_TOOLBAR_COMMAND, HOVER_COMMAND, HRPlugin, HRPluginOptions, HeadlessDocumentType, HeadlessEditor, HeadlessEditorExport, HeadlessEditorExportOptions, HeadlessEditorHydrationInput, HeadlessEditorOptions, HeadlessLiteXMLBatchOperation, HeadlessLiteXMLInsertOperation, HeadlessLiteXMLOperation, HeadlessLiteXMLRemoveOperation, HeadlessLiteXMLReplaceOperation, HotkeyEnum, HotkeyId, HotkeyItem, HotkeyScopeEnum, HotkeyScopeId, IBlockActionButton, IBlockActionButtonIcon, IBlockMenuItem, IBlockMenuRenderContext, IBlockMenuService, IBlockSelectHandler, type IEditor, ILinkService, ILitexmlService, IMarkdownShortCutService, INSERT_CHECK_LIST_COMMAND, INSERT_CODEINLINE_COMMAND, INSERT_CODEMIRROR_COMMAND, INSERT_FILE_COMMAND, INSERT_HEADING_COMMAND, INSERT_HORIZONTAL_RULE_COMMAND, INSERT_IMAGE_COMMAND, INSERT_LINK_COMMAND, INSERT_LINK_HIGHLIGHT_COMMAND, INSERT_MARKDOWN_COMMAND, INSERT_MATH_COMMAND, INSERT_MENTION_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_QUOTE_COMMAND, INSERT_TABLE_COLUMN_COMMAND, INSERT_TABLE_COMMAND, INSERT_TABLE_ROW_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INodePlugin, INodePluginOptions, INodeService, ISlashDividerOption, ISlashMenuOption, ISlashOption, ISlashSectionOption, ISlashService, ITableControllerMenuActionItem, ITableControllerMenuItem, ITableControllerMenuRenderContext, ITableControllerMenuSeparatorItem, ITableControllerMenuService, ITriggerContext, IUploadService, ImageContentBlock, ImageListItem, ImagePlugin, ImagePluginOptions, Kernel, KeyEnum, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND, LexicalErrorBoundary, LexicalPortalContainer, LinkHighlightPlugin, LinkHighlightPluginOptions, LinkPlugin, LinkPluginOptions, ListPlugin, ListPluginOptions, LitexmlDataSource, LitexmlPlugin, LitexmlPluginOptions, LitexmlService, MARKDOWN_READER_LEVEL, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX, MOVE_BLOCK_COMMAND, MarkdownPlugin, MathPlugin, MediaLists, MentionPlugin, MentionPluginOptions, MenuRenderProps, ModifierCombination, REMOVE_LIST_COMMAND, ReactAutoCompletePlugin, ReactBlockPlugin, ReactBlockPluginProps, ReactCodePlugin, ReactCodeblockPlugin, ReactCodeblockPluginProps, ReactCodemirrorPlugin, ReactEditor, ReactEditorContent, ReactEditorContentProps, ReactFilePlugin, ReactFilePluginProps, ReactHRPlugin, ReactHRPluginProps, ReactImagePlugin, ReactImagePluginProps, ReactLinkHighlightPlugin, ReactLinkPlugin, ReactLinkPluginProps, ReactListPlugin, ReactListPluginProps, ReactLiteXmlPlugin, ReactMarkdownPlugin, ReactMathPlugin, ReactMentionPlugin, ReactMentionPluginProps, ReactNodePlugin, ReactPlainText, ReactPlainTextProps, ReactSlashOption, ReactSlashOptionProps, ReactSlashPlugin, ReactSlashPluginProps, ReactTablePlugin, ReactToolbarPlugin, ReactVirtualBlockPlugin, SELECT_AFTER_CODEMIRROR_COMMAND, SELECT_BEFORE_CODEMIRROR_COMMAND, SELECT_TABLE_COMMAND, SHOW_TOOLBAR_COMMAND, SerializedMentionNode, SlashMenu, SlashMenuProps, SlashOptions, SlashPlugin, SlashPluginOptions, TableControllerMenuAxis, TableControllerMenuService, TablePlugin, TablePluginOptions, TextContentBlock, ToolbarCommandOptions, UPDATE_CODEBLOCK_LANG, UPDATE_LIST_START_COMMAND, UPLOAD_PRIORITY_HIGH, UPLOAD_PRIORITY_LOW, UPLOAD_PRIORITY_MEDIUM, UploadPlugin, UploadPluginOptions, VirtualBlockPlugin, VirtualBlockPluginOptions, XMLReaderFunc, XMLReaderRecord, XMLWriterFunc, XMLWriterRecord, assert, browserDebug, bundledLanguagesInfo, compareNodeOrder, createDebugLogger, createEmptyEditorState, createHeadlessEditor, cursorNodeSerialized, debugLogger, debugLoggers, detectCodeLanguage, detectLanguage, devConsole, disableHotReload, enableHotReload, extractContentBlocks, extractMediaFromEditorState, extractMediaLists, flattenSlashOptions, genServiceId, generateEditorId, getHotkeyById, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, isPunctuationChar, isPureUrl, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption, isValidUrl, moment, noop, prodSafeLogger, reconcileDecorator, registerBlockMoveCommand, registerEditorKernel, registerLinkHighlightCommand, registerToolbarCommand, resetRandomKey, scrollIntoView, unregisterEditorKernel, useHasDiffNode, useLexicalComposerContext, useLexicalEditor };
|
|
128
|
+
export { $closest, $closestNodeType, $createCursorNode, $getNearestNodeFromDOMNode, $getNodeFromDOMNode, $isCardLikeElementNode, $isCursorNode, ANCHOR_PADDING_CSS_VAR, AutoCompletePlugin, BlockDragTarget, BlockMenuService, BlockMovePayload, BlockPlugin, BlockPluginOptions, CONTENT_BLOCKS_DATA_TYPE, CardLikeElementNode, CodePlugin, CodeblockPlugin, CodeblockPluginOptions, CodemirrorPlugin, CodemirrorPluginOptions, CollaborationProviderFactory, CollaborationUser, CommonPlugin, CommonPluginOptions, ContentBlock, ContentBlocksDataSource, ContentBlocksPlugin, ContentBlocksPluginOptions, DEFAULT_BLOCK_ANCHOR_PADDING, DEFAULT_HEADLESS_EDITOR_PLUGINS, DOM_DOCUMENT_FRAGMENT_TYPE, DOM_DOCUMENT_TYPE, DOM_ELEMENT_TYPE, DOM_TEXT_TYPE, DataSource, DiffAction, EDITOR_THEME_KEY, EditorCollaborationConfig, ExtractContentBlocksOptions, FileContentBlock, FileListItem, FilePlugin, FilePluginOptions, GET_MARKDOWN_SELECTION_COMMAND, HIDE_TOOLBAR_COMMAND, HOVER_COMMAND, HRPlugin, HRPluginOptions, HeadlessDocumentType, HeadlessEditor, HeadlessEditorExport, HeadlessEditorExportOptions, HeadlessEditorHydrationInput, HeadlessEditorOptions, HeadlessLiteXMLBatchOperation, HeadlessLiteXMLInsertOperation, HeadlessLiteXMLOperation, HeadlessLiteXMLRemoveOperation, HeadlessLiteXMLReplaceOperation, HotkeyEnum, HotkeyId, HotkeyItem, HotkeyScopeEnum, HotkeyScopeId, IBlockActionButton, IBlockActionButtonIcon, IBlockMenuItem, IBlockMenuRenderContext, IBlockMenuService, IBlockSelectHandler, type IEditor, ILinkService, ILitexmlService, IMarkdownShortCutService, INSERT_CHECK_LIST_COMMAND, INSERT_CODEINLINE_COMMAND, INSERT_CODEMIRROR_COMMAND, INSERT_FILE_COMMAND, INSERT_HEADING_COMMAND, INSERT_HORIZONTAL_RULE_COMMAND, INSERT_IMAGE_COMMAND, INSERT_LINK_COMMAND, INSERT_LINK_HIGHLIGHT_COMMAND, INSERT_MARKDOWN_COMMAND, INSERT_MATH_COMMAND, INSERT_MENTION_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_QUOTE_COMMAND, INSERT_TABLE_COLUMN_COMMAND, INSERT_TABLE_COMMAND, INSERT_TABLE_ROW_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INodePlugin, INodePluginOptions, INodeService, ISlashDividerOption, ISlashMenuOption, ISlashOption, ISlashSectionOption, ISlashService, ITableControllerMenuActionItem, ITableControllerMenuItem, ITableControllerMenuRenderContext, ITableControllerMenuSeparatorItem, ITableControllerMenuService, ITriggerContext, IUploadService, ImageContentBlock, ImageListItem, ImagePlugin, ImagePluginOptions, Kernel, KeyEnum, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND, LexicalErrorBoundary, LexicalPortalContainer, LinkHighlightPlugin, LinkHighlightPluginOptions, LinkPlugin, LinkPluginOptions, ListPlugin, ListPluginOptions, LitexmlDataSource, LitexmlPlugin, LitexmlPluginOptions, LitexmlService, MARKDOWN_READER_LEVEL, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX, MOVE_BLOCK_COMMAND, MarkdownPlugin, MathPlugin, MediaLists, MentionPlugin, MentionPluginOptions, MenuRenderProps, ModifierCombination, REMOVE_LIST_COMMAND, ReactAutoCompletePlugin, ReactBlockPlugin, ReactBlockPluginProps, ReactCodePlugin, ReactCodeblockPlugin, ReactCodeblockPluginProps, ReactCodemirrorPlugin, ReactCollaborationPlugin, ReactCollaborationPluginProps, ReactEditor, ReactEditorContent, ReactEditorContentProps, ReactFilePlugin, ReactFilePluginProps, ReactHRPlugin, ReactHRPluginProps, ReactImagePlugin, ReactImagePluginProps, ReactLinkHighlightPlugin, ReactLinkPlugin, ReactLinkPluginProps, ReactListPlugin, ReactListPluginProps, ReactLiteXmlPlugin, ReactMarkdownPlugin, ReactMathPlugin, ReactMentionPlugin, ReactMentionPluginProps, ReactNodePlugin, ReactPlainText, ReactPlainTextProps, ReactSlashOption, ReactSlashOptionProps, ReactSlashPlugin, ReactSlashPluginProps, ReactTablePlugin, ReactToolbarPlugin, ReactVirtualBlockPlugin, SELECT_AFTER_CODEMIRROR_COMMAND, SELECT_BEFORE_CODEMIRROR_COMMAND, SELECT_TABLE_COMMAND, SHOW_TOOLBAR_COMMAND, SerializedMentionNode, SlashMenu, SlashMenuProps, SlashOptions, SlashPlugin, SlashPluginOptions, TableControllerMenuAxis, TableControllerMenuService, TablePlugin, TablePluginOptions, TextContentBlock, ToolbarCommandOptions, UPDATE_CODEBLOCK_LANG, UPDATE_LIST_START_COMMAND, UPLOAD_PRIORITY_HIGH, UPLOAD_PRIORITY_LOW, UPLOAD_PRIORITY_MEDIUM, UploadPlugin, UploadPluginOptions, VirtualBlockPlugin, VirtualBlockPluginOptions, XMLReaderFunc, XMLReaderRecord, XMLWriterFunc, XMLWriterRecord, assert, browserDebug, bundledLanguagesInfo, compareNodeOrder, createDebugLogger, createEmptyEditorState, createHeadlessEditor, cursorNodeSerialized, debugLogger, debugLoggers, detectCodeLanguage, detectLanguage, devConsole, disableHotReload, enableHotReload, extractContentBlocks, extractMediaFromEditorState, extractMediaLists, flattenSlashOptions, genServiceId, generateEditorId, getHotkeyById, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, isPunctuationChar, isPureUrl, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption, isValidUrl, moment, noop, prodSafeLogger, reconcileDecorator, registerBlockMoveCommand, registerEditorKernel, registerLinkHighlightCommand, registerToolbarCommand, resetRandomKey, scrollIntoView, unregisterEditorKernel, useHasDiffNode, useLexicalComposerContext, useLexicalEditor };
|
package/es/index.js
CHANGED
|
@@ -72,6 +72,7 @@ import { CodeblockPlugin } from "./plugins/codeblock/plugin/index.js";
|
|
|
72
72
|
import ReactCodeblockPlugin from "./plugins/codeblock/react/ReactCodeblockPlugin.js";
|
|
73
73
|
import { bundledLanguagesInfo } from "./plugins/codeblock/index.js";
|
|
74
74
|
import ReactCodemirrorPlugin from "./plugins/codemirror-block/react/ReactCodemirrorNode.js";
|
|
75
|
+
import ReactCollaborationPlugin from "./plugins/collaboration/react/ReactCollaborationPlugin.js";
|
|
75
76
|
import { CONTENT_BLOCKS_DATA_TYPE } from "./plugins/content-blocks/types.js";
|
|
76
77
|
import { extractContentBlocks } from "./plugins/content-blocks/utils/extract.js";
|
|
77
78
|
import { ContentBlocksDataSource } from "./plugins/content-blocks/data-source/content-blocks-data-source.js";
|
|
@@ -128,4 +129,4 @@ function disableHotReload() {
|
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
//#endregion
|
|
131
|
-
export { $closest, $closestNodeType, $createCursorNode, $getNearestNodeFromDOMNode, $getNodeFromDOMNode, $isCardLikeElementNode, $isCursorNode, ANCHOR_PADDING_CSS_VAR, AutoCompletePlugin, BlockMenuService, BlockPlugin, CONTENT_BLOCKS_DATA_TYPE, CardLikeElementNode, CodePlugin, CodeblockPlugin, CodemirrorPlugin, CommonPlugin, ContentBlocksDataSource, ContentBlocksPlugin, DEFAULT_BLOCK_ANCHOR_PADDING, DEFAULT_HEADLESS_EDITOR_PLUGINS, DOM_DOCUMENT_FRAGMENT_TYPE, DOM_DOCUMENT_TYPE, DOM_ELEMENT_TYPE, DOM_TEXT_TYPE, DataSource, DiffAction, EDITOR_THEME_KEY, FilePlugin, GET_MARKDOWN_SELECTION_COMMAND, HIDE_TOOLBAR_COMMAND, HOVER_COMMAND, HRPlugin, HeadlessEditor, HotkeyEnum, HotkeyScopeEnum, IBlockMenuService, ILinkService, ILitexmlService, IMarkdownShortCutService, INSERT_CHECK_LIST_COMMAND, INSERT_CODEINLINE_COMMAND, INSERT_CODEMIRROR_COMMAND, INSERT_FILE_COMMAND, INSERT_HEADING_COMMAND, INSERT_HORIZONTAL_RULE_COMMAND, INSERT_IMAGE_COMMAND, INSERT_LINK_COMMAND, INSERT_LINK_HIGHLIGHT_COMMAND, INSERT_MARKDOWN_COMMAND, INSERT_MATH_COMMAND, INSERT_MENTION_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_QUOTE_COMMAND, INSERT_TABLE_COLUMN_COMMAND, INSERT_TABLE_COMMAND, INSERT_TABLE_ROW_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INodePlugin, INodeService, ITableControllerMenuService, IUploadService, ImagePlugin, Kernel, KeyEnum, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND, LexicalErrorBoundary, LexicalPortalContainer, LinkHighlightPlugin, LinkPlugin, ListPlugin, LitexmlDataSource, LitexmlPlugin, LitexmlService, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX, MOVE_BLOCK_COMMAND, MarkdownPlugin, MathPlugin, MentionPlugin, REMOVE_LIST_COMMAND, ReactAutoCompletePlugin, ReactBlockPlugin, ReactCodePlugin, ReactCodeblockPlugin, ReactCodemirrorPlugin, ReactEditor, ReactEditorContent, ReactFilePlugin, ReactHRPlugin, ReactImagePlugin, ReactLinkHighlightPlugin, ReactLinkPlugin, ReactListPlugin, ReactLiteXmlPlugin, ReactMarkdownPlugin, ReactMathPlugin, ReactMentionPlugin, ReactNodePlugin, ReactPlainText, ReactSlashOption, ReactSlashPlugin, ReactTablePlugin, ReactToolbarPlugin, ReactVirtualBlockPlugin, SELECT_AFTER_CODEMIRROR_COMMAND, SELECT_BEFORE_CODEMIRROR_COMMAND, SELECT_TABLE_COMMAND, SHOW_TOOLBAR_COMMAND, SlashMenu, SlashPlugin, TableControllerMenuService, TablePlugin, UPDATE_CODEBLOCK_LANG, UPDATE_LIST_START_COMMAND, UPLOAD_PRIORITY_HIGH, UPLOAD_PRIORITY_LOW, UPLOAD_PRIORITY_MEDIUM, UploadPlugin, VirtualBlockPlugin, assert, browserDebug, bundledLanguagesInfo, compareNodeOrder, createDebugLogger, createEmptyEditorState, createHeadlessEditor, cursorNodeSerialized, debugLogger, debugLoggers, detectCodeLanguage, detectLanguage, devConsole, disableHotReload, enableHotReload, extractContentBlocks, extractMediaFromEditorState, extractMediaLists, flattenSlashOptions, genServiceId, generateEditorId, getHotkeyById, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, isPunctuationChar, isPureUrl, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption, isValidUrl, moment, noop, prodSafeLogger, reconcileDecorator, registerBlockMoveCommand, registerEditorKernel, registerLinkHighlightCommand, registerToolbarCommand, resetRandomKey, scrollIntoView, unregisterEditorKernel, useHasDiffNode, useLexicalComposerContext, useLexicalEditor };
|
|
132
|
+
export { $closest, $closestNodeType, $createCursorNode, $getNearestNodeFromDOMNode, $getNodeFromDOMNode, $isCardLikeElementNode, $isCursorNode, ANCHOR_PADDING_CSS_VAR, AutoCompletePlugin, BlockMenuService, BlockPlugin, CONTENT_BLOCKS_DATA_TYPE, CardLikeElementNode, CodePlugin, CodeblockPlugin, CodemirrorPlugin, CommonPlugin, ContentBlocksDataSource, ContentBlocksPlugin, DEFAULT_BLOCK_ANCHOR_PADDING, DEFAULT_HEADLESS_EDITOR_PLUGINS, DOM_DOCUMENT_FRAGMENT_TYPE, DOM_DOCUMENT_TYPE, DOM_ELEMENT_TYPE, DOM_TEXT_TYPE, DataSource, DiffAction, EDITOR_THEME_KEY, FilePlugin, GET_MARKDOWN_SELECTION_COMMAND, HIDE_TOOLBAR_COMMAND, HOVER_COMMAND, HRPlugin, HeadlessEditor, HotkeyEnum, HotkeyScopeEnum, IBlockMenuService, ILinkService, ILitexmlService, IMarkdownShortCutService, INSERT_CHECK_LIST_COMMAND, INSERT_CODEINLINE_COMMAND, INSERT_CODEMIRROR_COMMAND, INSERT_FILE_COMMAND, INSERT_HEADING_COMMAND, INSERT_HORIZONTAL_RULE_COMMAND, INSERT_IMAGE_COMMAND, INSERT_LINK_COMMAND, INSERT_LINK_HIGHLIGHT_COMMAND, INSERT_MARKDOWN_COMMAND, INSERT_MATH_COMMAND, INSERT_MENTION_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_QUOTE_COMMAND, INSERT_TABLE_COLUMN_COMMAND, INSERT_TABLE_COMMAND, INSERT_TABLE_ROW_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INodePlugin, INodeService, ITableControllerMenuService, IUploadService, ImagePlugin, Kernel, KeyEnum, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND, LexicalErrorBoundary, LexicalPortalContainer, LinkHighlightPlugin, LinkPlugin, ListPlugin, LitexmlDataSource, LitexmlPlugin, LitexmlService, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX, MOVE_BLOCK_COMMAND, MarkdownPlugin, MathPlugin, MentionPlugin, REMOVE_LIST_COMMAND, ReactAutoCompletePlugin, ReactBlockPlugin, ReactCodePlugin, ReactCodeblockPlugin, ReactCodemirrorPlugin, ReactCollaborationPlugin, ReactEditor, ReactEditorContent, ReactFilePlugin, ReactHRPlugin, ReactImagePlugin, ReactLinkHighlightPlugin, ReactLinkPlugin, ReactListPlugin, ReactLiteXmlPlugin, ReactMarkdownPlugin, ReactMathPlugin, ReactMentionPlugin, ReactNodePlugin, ReactPlainText, ReactSlashOption, ReactSlashPlugin, ReactTablePlugin, ReactToolbarPlugin, ReactVirtualBlockPlugin, SELECT_AFTER_CODEMIRROR_COMMAND, SELECT_BEFORE_CODEMIRROR_COMMAND, SELECT_TABLE_COMMAND, SHOW_TOOLBAR_COMMAND, SlashMenu, SlashPlugin, TableControllerMenuService, TablePlugin, UPDATE_CODEBLOCK_LANG, UPDATE_LIST_START_COMMAND, UPLOAD_PRIORITY_HIGH, UPLOAD_PRIORITY_LOW, UPLOAD_PRIORITY_MEDIUM, UploadPlugin, VirtualBlockPlugin, assert, browserDebug, bundledLanguagesInfo, compareNodeOrder, createDebugLogger, createEmptyEditorState, createHeadlessEditor, cursorNodeSerialized, debugLogger, debugLoggers, detectCodeLanguage, detectLanguage, devConsole, disableHotReload, enableHotReload, extractContentBlocks, extractMediaFromEditorState, extractMediaLists, flattenSlashOptions, genServiceId, generateEditorId, getHotkeyById, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, isPunctuationChar, isPureUrl, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption, isValidUrl, moment, noop, prodSafeLogger, reconcileDecorator, registerBlockMoveCommand, registerEditorKernel, registerLinkHighlightCommand, registerToolbarCommand, resetRandomKey, scrollIntoView, unregisterEditorKernel, useHasDiffNode, useLexicalComposerContext, useLexicalEditor };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactCollaborationPluginProps } from "./type.js";
|
|
2
|
+
import { FC } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/collaboration/react/ReactCollaborationPlugin.d.ts
|
|
5
|
+
declare const ReactCollaborationPlugin: FC<ReactCollaborationPluginProps>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { ReactCollaborationPlugin };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLexicalEditor } from "../../../editor-kernel/react/useLexicalEditor.js";
|
|
3
|
+
import { getOrCreateYDoc, initializeCollaborationUser, registerCollaborationBinding } from "../utils.js";
|
|
4
|
+
import { useMemo, useRef } from "react";
|
|
5
|
+
import { Doc } from "yjs";
|
|
6
|
+
//#region src/plugins/collaboration/react/ReactCollaborationPlugin.tsx
|
|
7
|
+
const defaultYjsDocMap = /* @__PURE__ */ new Map();
|
|
8
|
+
const createProviderStatusHandler = (statusChangeRef) => {
|
|
9
|
+
return function handleProviderStatus({ status }) {
|
|
10
|
+
statusChangeRef.current?.(status);
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
const createProviderSyncHandler = (syncRef) => {
|
|
14
|
+
return function handleProviderSync(isSynced) {
|
|
15
|
+
syncRef.current?.(isSynced);
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const createCursorContainer = (rootElement) => {
|
|
19
|
+
const parentElement = rootElement?.parentElement;
|
|
20
|
+
if (!rootElement || !parentElement) return null;
|
|
21
|
+
if (getComputedStyle(parentElement).position === "static") parentElement.style.position = "relative";
|
|
22
|
+
const container = document.createElement("div");
|
|
23
|
+
container.dataset.lobeEditorCollaborationCursors = "true";
|
|
24
|
+
container.style.inset = "0";
|
|
25
|
+
container.style.pointerEvents = "none";
|
|
26
|
+
container.style.position = "absolute";
|
|
27
|
+
container.style.zIndex = "20";
|
|
28
|
+
parentElement.append(container);
|
|
29
|
+
return container;
|
|
30
|
+
};
|
|
31
|
+
const ReactCollaborationPlugin = ({ connect = true, cursorContainer, excludedProperties, id, onStatusChange, onSync, providerFactory, shouldBootstrap, syncCursorPositionsFn, user, yjsDocMap }) => {
|
|
32
|
+
const statusChangeRef = useRef(onStatusChange);
|
|
33
|
+
const syncRef = useRef(onSync);
|
|
34
|
+
statusChangeRef.current = onStatusChange;
|
|
35
|
+
syncRef.current = onSync;
|
|
36
|
+
const docMap = useMemo(() => yjsDocMap ?? defaultYjsDocMap, [yjsDocMap]);
|
|
37
|
+
useLexicalEditor((lexicalEditor) => {
|
|
38
|
+
let teardown;
|
|
39
|
+
const timeoutId = setTimeout(() => {
|
|
40
|
+
const doc = getOrCreateYDoc(id, docMap, () => new Doc());
|
|
41
|
+
const provider = providerFactory(id, docMap);
|
|
42
|
+
const effectiveDoc = docMap.get(id) ?? doc;
|
|
43
|
+
const ownedCursorContainer = cursorContainer ?? createCursorContainer(lexicalEditor.getRootElement());
|
|
44
|
+
initializeCollaborationUser(provider, user);
|
|
45
|
+
const statusHandler = createProviderStatusHandler(statusChangeRef);
|
|
46
|
+
const syncHandler = createProviderSyncHandler(syncRef);
|
|
47
|
+
provider.on("status", statusHandler);
|
|
48
|
+
provider.on("sync", syncHandler);
|
|
49
|
+
const { cleanup } = registerCollaborationBinding({
|
|
50
|
+
cursorContainer: ownedCursorContainer,
|
|
51
|
+
doc: effectiveDoc,
|
|
52
|
+
excludedProperties,
|
|
53
|
+
id,
|
|
54
|
+
lexicalEditor,
|
|
55
|
+
provider,
|
|
56
|
+
shouldBootstrap,
|
|
57
|
+
syncCursorPositionsFn,
|
|
58
|
+
yjsDocMap: docMap
|
|
59
|
+
});
|
|
60
|
+
if (connect) provider.connect();
|
|
61
|
+
teardown = () => {
|
|
62
|
+
cleanup();
|
|
63
|
+
provider.off("status", statusHandler);
|
|
64
|
+
provider.off("sync", syncHandler);
|
|
65
|
+
provider.awareness.setLocalState(null);
|
|
66
|
+
provider.disconnect();
|
|
67
|
+
if (!cursorContainer) ownedCursorContainer?.remove();
|
|
68
|
+
};
|
|
69
|
+
}, 0);
|
|
70
|
+
return () => {
|
|
71
|
+
clearTimeout(timeoutId);
|
|
72
|
+
teardown?.();
|
|
73
|
+
};
|
|
74
|
+
}, [
|
|
75
|
+
connect,
|
|
76
|
+
cursorContainer,
|
|
77
|
+
docMap,
|
|
78
|
+
excludedProperties,
|
|
79
|
+
id,
|
|
80
|
+
providerFactory,
|
|
81
|
+
shouldBootstrap,
|
|
82
|
+
syncCursorPositionsFn,
|
|
83
|
+
user
|
|
84
|
+
]);
|
|
85
|
+
return null;
|
|
86
|
+
};
|
|
87
|
+
ReactCollaborationPlugin.displayName = "ReactCollaborationPlugin";
|
|
88
|
+
//#endregion
|
|
89
|
+
export { ReactCollaborationPlugin as default };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CollaborationUser } from "../utils.js";
|
|
2
|
+
import { Doc } from "yjs";
|
|
3
|
+
import { ExcludedProperties, Provider, SyncCursorPositionsFn } from "@lexical/yjs";
|
|
4
|
+
|
|
5
|
+
//#region src/plugins/collaboration/react/type.d.ts
|
|
6
|
+
type CollaborationProviderFactory = (id: string, yjsDocMap: Map<string, Doc>) => Provider;
|
|
7
|
+
interface EditorCollaborationConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Whether the provider should connect immediately.
|
|
10
|
+
* Set this to false when the business shell needs to create the editor before joining the room.
|
|
11
|
+
*
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
connect?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Optional DOM node used by Lexical/Yjs to render remote cursor overlays.
|
|
17
|
+
* When omitted, the editor creates and owns a cursor container beside the root element.
|
|
18
|
+
*/
|
|
19
|
+
cursorContainer?: HTMLElement | null;
|
|
20
|
+
/**
|
|
21
|
+
* Lexical node properties excluded from Yjs synchronization.
|
|
22
|
+
*/
|
|
23
|
+
excludedProperties?: ExcludedProperties;
|
|
24
|
+
/**
|
|
25
|
+
* Stable collaboration room id. For workspace pages, this should be derived from
|
|
26
|
+
* workspaceId + pageId by the business shell.
|
|
27
|
+
*/
|
|
28
|
+
id: string;
|
|
29
|
+
/**
|
|
30
|
+
* Provider connection status callback.
|
|
31
|
+
*/
|
|
32
|
+
onStatusChange?: (status: string) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Provider sync state callback.
|
|
35
|
+
*/
|
|
36
|
+
onSync?: (isSynced: boolean) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Factory that adapts the business collaboration transport to Lexical's Provider contract.
|
|
39
|
+
*/
|
|
40
|
+
providerFactory: CollaborationProviderFactory;
|
|
41
|
+
/**
|
|
42
|
+
* Bootstrap the current Lexical editor state into Yjs only when the Y.Doc root is empty.
|
|
43
|
+
* Use this for lazy migration from legacy page JSON.
|
|
44
|
+
*
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
shouldBootstrap?: boolean;
|
|
48
|
+
syncCursorPositionsFn?: SyncCursorPositionsFn;
|
|
49
|
+
/**
|
|
50
|
+
* Current user's collaboration identity and awareness metadata.
|
|
51
|
+
*/
|
|
52
|
+
user: CollaborationUser;
|
|
53
|
+
/**
|
|
54
|
+
* Optional externally-owned Y.Doc registry. Supplying this lets the business shell
|
|
55
|
+
* control document lifetime across page mounts.
|
|
56
|
+
*/
|
|
57
|
+
yjsDocMap?: Map<string, Doc>;
|
|
58
|
+
}
|
|
59
|
+
type ReactCollaborationPluginProps = EditorCollaborationConfig;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { CollaborationProviderFactory, EditorCollaborationConfig, ReactCollaborationPluginProps };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LexicalEditor } from "lexical";
|
|
2
|
+
import { Doc } from "yjs";
|
|
3
|
+
import { ExcludedProperties, Provider, SyncCursorPositionsFn } from "@lexical/yjs";
|
|
4
|
+
|
|
5
|
+
//#region src/plugins/collaboration/utils.d.ts
|
|
6
|
+
interface CollaborationUser {
|
|
7
|
+
awarenessData?: Record<string, unknown>;
|
|
8
|
+
color: string;
|
|
9
|
+
focusing?: boolean;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { CollaborationUser };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { COLLABORATION_TAG } from "lexical";
|
|
2
|
+
import { createBindingV2__EXPERIMENTAL, initLocalState, syncCursorPositions, syncLexicalUpdateToYjsV2__EXPERIMENTAL, syncYjsChangesToLexicalV2__EXPERIMENTAL, syncYjsStateToLexicalV2__EXPERIMENTAL } from "@lexical/yjs";
|
|
3
|
+
//#region src/plugins/collaboration/utils.ts
|
|
4
|
+
const getOrCreateYDoc = (id, yjsDocMap, createDoc) => {
|
|
5
|
+
const existingDoc = yjsDocMap.get(id);
|
|
6
|
+
if (existingDoc) return existingDoc;
|
|
7
|
+
const doc = createDoc();
|
|
8
|
+
yjsDocMap.set(id, doc);
|
|
9
|
+
return doc;
|
|
10
|
+
};
|
|
11
|
+
const initializeCollaborationUser = (provider, user) => {
|
|
12
|
+
initLocalState(provider, user.name, user.color, user.focusing ?? true, user.awarenessData ?? {});
|
|
13
|
+
};
|
|
14
|
+
const isStaleLexicalNodeError = (error) => error instanceof Error && error.message.includes("Lexical node does not exist in active editor state");
|
|
15
|
+
const registerCollaborationBinding = ({ cursorContainer, doc, excludedProperties, id, lexicalEditor, provider, shouldBootstrap = false, syncCursorPositionsFn = syncCursorPositions, yjsDocMap }) => {
|
|
16
|
+
const binding = createBindingV2__EXPERIMENTAL(lexicalEditor, id, doc, yjsDocMap, { excludedProperties });
|
|
17
|
+
binding.cursorsContainer = cursorContainer ?? null;
|
|
18
|
+
if (binding.root.length > 0) syncYjsStateToLexicalV2__EXPERIMENTAL(binding, provider);
|
|
19
|
+
else if (shouldBootstrap) {
|
|
20
|
+
const editorState = lexicalEditor.getEditorState();
|
|
21
|
+
syncLexicalUpdateToYjsV2__EXPERIMENTAL(binding, provider, editorState, editorState, new Map([["root", true]]), /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
|
|
22
|
+
}
|
|
23
|
+
const yjsObserver = (events, transaction) => {
|
|
24
|
+
if (transaction.origin === binding) return;
|
|
25
|
+
syncYjsChangesToLexicalV2__EXPERIMENTAL(binding, provider, events, transaction, false);
|
|
26
|
+
};
|
|
27
|
+
const reloadObserver = (nextDoc) => {
|
|
28
|
+
if (nextDoc === doc) syncYjsStateToLexicalV2__EXPERIMENTAL(binding, provider);
|
|
29
|
+
};
|
|
30
|
+
let isCleanedUp = false;
|
|
31
|
+
let cursorSyncQueued = false;
|
|
32
|
+
let cursorSyncRetryQueued = false;
|
|
33
|
+
const syncCursorsSafely = () => {
|
|
34
|
+
try {
|
|
35
|
+
syncCursorPositionsFn(binding, provider);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (!isStaleLexicalNodeError(error)) throw error;
|
|
38
|
+
if (cursorSyncRetryQueued) return;
|
|
39
|
+
cursorSyncRetryQueued = true;
|
|
40
|
+
syncYjsStateToLexicalV2__EXPERIMENTAL(binding, provider);
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
cursorSyncRetryQueued = false;
|
|
43
|
+
if (isCleanedUp) return;
|
|
44
|
+
try {
|
|
45
|
+
syncCursorPositionsFn(binding, provider);
|
|
46
|
+
} catch (retryError) {
|
|
47
|
+
if (!isStaleLexicalNodeError(retryError)) throw retryError;
|
|
48
|
+
}
|
|
49
|
+
}, 0);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const scheduleCursorSync = () => {
|
|
53
|
+
if (cursorSyncQueued) return;
|
|
54
|
+
cursorSyncQueued = true;
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
cursorSyncQueued = false;
|
|
57
|
+
if (isCleanedUp) return;
|
|
58
|
+
syncCursorsSafely();
|
|
59
|
+
}, 0);
|
|
60
|
+
};
|
|
61
|
+
const awarenessObserver = () => {
|
|
62
|
+
scheduleCursorSync();
|
|
63
|
+
};
|
|
64
|
+
const unregisterUpdateListener = lexicalEditor.registerUpdateListener(({ dirtyElements, editorState, normalizedNodes, prevEditorState, tags }) => {
|
|
65
|
+
syncLexicalUpdateToYjsV2__EXPERIMENTAL(binding, provider, prevEditorState, editorState, dirtyElements, normalizedNodes, tags);
|
|
66
|
+
scheduleCursorSync();
|
|
67
|
+
});
|
|
68
|
+
binding.root.observeDeep(yjsObserver);
|
|
69
|
+
provider.on("reload", reloadObserver);
|
|
70
|
+
provider.awareness.on("update", awarenessObserver);
|
|
71
|
+
return {
|
|
72
|
+
binding,
|
|
73
|
+
cleanup: () => {
|
|
74
|
+
isCleanedUp = true;
|
|
75
|
+
unregisterUpdateListener();
|
|
76
|
+
binding.root.unobserveDeep(yjsObserver);
|
|
77
|
+
provider.off("reload", reloadObserver);
|
|
78
|
+
provider.awareness.off("update", awarenessObserver);
|
|
79
|
+
lexicalEditor.update(() => {}, { tag: COLLABORATION_TAG });
|
|
80
|
+
binding.cursorsContainer = null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
//#endregion
|
|
85
|
+
export { getOrCreateYDoc, initializeCollaborationUser, registerCollaborationBinding };
|
|
@@ -14,7 +14,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
14
14
|
overflow-y: auto;
|
|
15
15
|
|
|
16
16
|
max-height: min(50vh, 400px);
|
|
17
|
-
padding:
|
|
17
|
+
padding: 6px;
|
|
18
18
|
border-radius: ${cssVar.borderRadius};
|
|
19
19
|
|
|
20
20
|
background: ${cssVar.colorBgElevated};
|
|
@@ -23,23 +23,29 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
23
23
|
0 0 15px 0 #00000008,
|
|
24
24
|
0 2px 30px 0 #00000014,
|
|
25
25
|
0 0 0 1px ${cssVar.colorBorder} inset;
|
|
26
|
+
|
|
27
|
+
[role='menuitem'] {
|
|
28
|
+
min-height: 40px;
|
|
29
|
+
padding-block: 8px;
|
|
30
|
+
padding-inline: 12px;
|
|
31
|
+
}
|
|
26
32
|
`,
|
|
27
33
|
popupCaret: css`
|
|
28
34
|
width: max-content;
|
|
29
|
-
min-width:
|
|
35
|
+
min-width: 220px;
|
|
30
36
|
`,
|
|
31
37
|
root: css`
|
|
32
38
|
z-index: 1100;
|
|
33
39
|
`,
|
|
34
40
|
section: css`
|
|
35
|
-
margin-block-start:
|
|
41
|
+
margin-block-start: 6px;
|
|
36
42
|
`,
|
|
37
43
|
sectionFirst: css`
|
|
38
44
|
margin-block-start: 0;
|
|
39
45
|
`,
|
|
40
46
|
sectionLabel: css`
|
|
41
47
|
padding-block: 12px 6px;
|
|
42
|
-
padding-inline:
|
|
48
|
+
padding-inline: 12px;
|
|
43
49
|
|
|
44
50
|
font-size: 12px;
|
|
45
51
|
line-height: 1;
|
|
@@ -3,6 +3,7 @@ import { ReactEditor } from "../../editor-kernel/react/react-editor.js";
|
|
|
3
3
|
import ReactMarkdownPlugin from "../../plugins/markdown/react/index.js";
|
|
4
4
|
import ReactEditorContent from "../../plugins/common/react/ReactEditorContent.js";
|
|
5
5
|
import ReactPlainText from "../../plugins/common/react/ReactPlainText.js";
|
|
6
|
+
import ReactCollaborationPlugin from "../../plugins/collaboration/react/ReactCollaborationPlugin.js";
|
|
6
7
|
import ReactMentionPlugin from "../../plugins/mention/react/ReactMentionPlugin.js";
|
|
7
8
|
import ReactSlashOption from "../../plugins/slash/react/ReactSlashOption.js";
|
|
8
9
|
import ReactSlashPlugin from "../../plugins/slash/react/ReactSlashPlugin.js";
|
|
@@ -11,14 +12,18 @@ import { createElement, memo, useMemo } from "react";
|
|
|
11
12
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
13
|
import { debounce } from "es-toolkit";
|
|
13
14
|
//#region src/react/Editor/Editor.tsx
|
|
14
|
-
const Editor = memo(({ content, style, className, debounceWait = 100, editable, editor, onInit, onChange, placeholder, lineEmptyPlaceholder, plugins = [], slashOption = {}, slashPlacement, getPopupContainer, mentionOption = {}, variant, onKeyDown, children, type = "json", onPressEnter, onFocus, onBlur, autoFocus, enablePasteMarkdown = true, autoFormatMarkdown = true, markdownOption = true, pasteMarkdownAutoConvertThreshold, pasteAsPlainText = false, pasteVSCodeAsCodeBlock = true, onCompositionStart, onCompositionEnd, onContextMenu, onTextChange }) => {
|
|
15
|
+
const Editor = memo(({ content, style, className, collaboration, debounceWait = 100, editable, editor, onInit, onChange, placeholder, lineEmptyPlaceholder, plugins = [], slashOption = {}, slashPlacement, getPopupContainer, mentionOption = {}, variant, onKeyDown, children, type = "json", onPressEnter, onFocus, onBlur, autoFocus, enablePasteMarkdown = true, autoFormatMarkdown = true, markdownOption = true, pasteMarkdownAutoConvertThreshold, pasteAsPlainText = false, pasteVSCodeAsCodeBlock = true, onCompositionStart, onCompositionEnd, onContextMenu, onTextChange }) => {
|
|
15
16
|
const { config } = useEditorContent();
|
|
16
17
|
const enableSlash = Boolean(slashOption?.items && slashOption.items.length > 0);
|
|
17
18
|
const enableMention = Boolean(mentionOption?.items && mentionOption.items.length > 0);
|
|
18
19
|
const { markdownWriter, ...restMentionOption } = mentionOption;
|
|
19
20
|
const debouncedOnChange = useMemo(() => onChange ? debounce(onChange, debounceWait) : void 0, [onChange, debounceWait]);
|
|
20
21
|
const debouncedOnTextChange = useMemo(() => onTextChange ? debounce(onTextChange, debounceWait) : void 0, [onTextChange, debounceWait]);
|
|
21
|
-
const memoPlugins = useMemo(() => [
|
|
22
|
+
const memoPlugins = useMemo(() => [
|
|
23
|
+
collaboration && [ReactCollaborationPlugin, collaboration],
|
|
24
|
+
enablePasteMarkdown && autoFormatMarkdown && ReactMarkdownPlugin,
|
|
25
|
+
...plugins
|
|
26
|
+
].filter(Boolean).map((plugin, index) => {
|
|
22
27
|
if (typeof plugin === "function") return createElement(plugin, { key: index });
|
|
23
28
|
return createElement(plugin[0], {
|
|
24
29
|
key: index,
|
|
@@ -26,6 +31,7 @@ const Editor = memo(({ content, style, className, debounceWait = 100, editable,
|
|
|
26
31
|
});
|
|
27
32
|
}), [
|
|
28
33
|
plugins,
|
|
34
|
+
collaboration,
|
|
29
35
|
enablePasteMarkdown,
|
|
30
36
|
autoFormatMarkdown,
|
|
31
37
|
ReactMarkdownPlugin
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IEditor } from "../../types/kernel.js";
|
|
2
|
+
import { EditorCollaborationConfig } from "../../plugins/collaboration/react/type.js";
|
|
2
3
|
import { ReactEditorContentProps, ReactPlainTextProps } from "../../plugins/common/react/type.js";
|
|
3
4
|
import { ReactMentionPluginProps } from "../../plugins/mention/react/type.js";
|
|
4
5
|
import { ReactSlashOptionProps } from "../../plugins/slash/react/type.js";
|
|
@@ -18,6 +19,7 @@ interface EditorProps extends Partial<ReactEditorContentProps>, Omit<ReactPlainT
|
|
|
18
19
|
autoFormatMarkdown?: boolean;
|
|
19
20
|
children?: ReactNode;
|
|
20
21
|
className?: string;
|
|
22
|
+
collaboration?: false | EditorCollaborationConfig;
|
|
21
23
|
/**
|
|
22
24
|
* Debounce wait time in milliseconds for onChange and onTextChange callbacks
|
|
23
25
|
* @default 100
|
package/es/react.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ANCHOR_PADDING_CSS_VAR, DEFAULT_BLOCK_ANCHOR_PADDING } from "./plugins/block/react/style.js";
|
|
2
|
+
import { CollaborationProviderFactory, EditorCollaborationConfig } from "./plugins/collaboration/react/type.js";
|
|
2
3
|
import { ChatInputProps } from "./react/ChatInput/type.js";
|
|
3
4
|
import { ChatInput } from "./react/ChatInput/ChatInput.js";
|
|
4
5
|
import { ChatInputActionBarProps } from "./react/ChatInputActionBar/type.js";
|
|
@@ -17,4 +18,4 @@ import { FloatActionsProps } from "./react/FloatActions/type.js";
|
|
|
17
18
|
import { FloatActions } from "./react/FloatActions/FloatActions.js";
|
|
18
19
|
import { SendButtonProps } from "./react/SendButton/type.js";
|
|
19
20
|
import { SendButton } from "./react/SendButton/SendButton.js";
|
|
20
|
-
export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, type ChatInputActionBarProps, type ChatInputActionEvent, ChatInputActions, type ChatInputActionsProps, type ChatInputProps, CodeLanguageSelect, type CodeLanguageSelectProps, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, type EditorProps, EditorProvider, type EditorProviderConfig, type EditorProviderProps, type EditorState, FloatActions, type FloatActionsProps, SendButton, type SendButtonProps, useEditor, useEditorContent, useEditorState, withProps };
|
|
21
|
+
export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, type ChatInputActionBarProps, type ChatInputActionEvent, ChatInputActions, type ChatInputActionsProps, type ChatInputProps, CodeLanguageSelect, type CodeLanguageSelectProps, type CollaborationProviderFactory, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, type EditorCollaborationConfig, type EditorProps, EditorProvider, type EditorProviderConfig, type EditorProviderProps, type EditorState, FloatActions, type FloatActionsProps, SendButton, type SendButtonProps, useEditor, useEditorContent, useEditorState, withProps };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/editor",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.20.1",
|
|
4
4
|
"description": "A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lobehub",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"@lexical/selection": "0.42.0",
|
|
98
98
|
"@lexical/table": "0.42.0",
|
|
99
99
|
"@lexical/utils": "0.42.0",
|
|
100
|
+
"@lexical/yjs": "0.42.0",
|
|
100
101
|
"@shikijs/core": "^3.20.0",
|
|
101
102
|
"@shikijs/engine-javascript": "^3.20.0",
|
|
102
103
|
"@xmldom/xmldom": "^0.8.11",
|
|
@@ -121,7 +122,8 @@
|
|
|
121
122
|
"remark-supersub": "^1.0.0",
|
|
122
123
|
"shiki": "^3.20.0",
|
|
123
124
|
"ts-key-enum": "^3.0.13",
|
|
124
|
-
"use-merge-value": "^1.2.0"
|
|
125
|
+
"use-merge-value": "^1.2.0",
|
|
126
|
+
"yjs": "^13.6.31"
|
|
125
127
|
},
|
|
126
128
|
"peerDependencies": {
|
|
127
129
|
"@lobehub/ui": "^5.0.0",
|