@lobehub/editor 4.18.0 → 4.19.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/es/index.d.ts CHANGED
@@ -91,7 +91,7 @@ import { SerializedMentionNode } from "./plugins/mention/node/MentionNode.js";
91
91
  import { MentionPlugin, MentionPluginOptions } from "./plugins/mention/plugin/index.js";
92
92
  import { ReactMentionPluginProps } from "./plugins/mention/react/type.js";
93
93
  import { ReactMentionPlugin } from "./plugins/mention/react/ReactMentionPlugin.js";
94
- import { ISlashMenuOption, ISlashOption, ISlashService, SlashOptions } from "./plugins/slash/service/i-slash-service.js";
94
+ import { ISlashDividerOption, ISlashMenuOption, ISlashOption, ISlashSectionOption, ISlashService, SlashOptions, flattenSlashOptions, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption } from "./plugins/slash/service/i-slash-service.js";
95
95
  import { ITriggerContext, SlashPlugin, SlashPluginOptions } from "./plugins/slash/plugin/index.js";
96
96
  import { MenuRenderProps, ReactSlashOptionProps, ReactSlashPluginProps, SlashMenuProps } from "./plugins/slash/react/type.js";
97
97
  import { SlashMenu } from "./plugins/slash/react/components/SlashMenu.js";
@@ -122,4 +122,4 @@ declare function enableHotReload(): void;
122
122
  */
123
123
  declare function disableHotReload(): void;
124
124
  //#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, ISlashMenuOption, ISlashOption, 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, genServiceId, generateEditorId, getHotkeyById, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, isPunctuationChar, isPureUrl, isValidUrl, moment, noop, prodSafeLogger, reconcileDecorator, registerBlockMoveCommand, registerEditorKernel, registerLinkHighlightCommand, registerToolbarCommand, resetRandomKey, scrollIntoView, unregisterEditorKernel, useHasDiffNode, useLexicalComposerContext, useLexicalEditor };
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 };
package/es/index.js CHANGED
@@ -88,6 +88,7 @@ import { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST
88
88
  import ReactListPlugin from "./plugins/list/react/ReactListPlugin.js";
89
89
  import { ReactMathPlugin } from "./plugins/math/react/index.js";
90
90
  import ReactMentionPlugin from "./plugins/mention/react/ReactMentionPlugin.js";
91
+ import { flattenSlashOptions, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption } from "./plugins/slash/service/i-slash-service.js";
91
92
  import { SlashPlugin } from "./plugins/slash/plugin/index.js";
92
93
  import SlashMenu from "./plugins/slash/react/components/SlashMenu.js";
93
94
  import ReactSlashOption from "./plugins/slash/react/ReactSlashOption.js";
@@ -127,4 +128,4 @@ function disableHotReload() {
127
128
  }
128
129
  }
129
130
  //#endregion
130
- 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, genServiceId, generateEditorId, getHotkeyById, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, isPunctuationChar, isPureUrl, isValidUrl, moment, noop, prodSafeLogger, reconcileDecorator, registerBlockMoveCommand, registerEditorKernel, registerLinkHighlightCommand, registerToolbarCommand, resetRandomKey, scrollIntoView, unregisterEditorKernel, useHasDiffNode, useLexicalComposerContext, useLexicalEditor };
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 };
@@ -1,4 +1,4 @@
1
- import { ISlashMenuOption, ISlashOption, ISlashService, SlashOptions } from "./service/i-slash-service.js";
1
+ import { ISlashDividerOption, ISlashMenuOption, ISlashOption, ISlashSectionOption, ISlashService, SlashOptions, flattenSlashOptions, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption } from "./service/i-slash-service.js";
2
2
  import { ITriggerContext, SlashPlugin, SlashPluginOptions } from "./plugin/index.js";
3
3
  import { MenuRenderProps, ReactSlashOptionProps, ReactSlashPluginProps, SlashMenuProps } from "./react/type.js";
4
4
  import { SlashMenu } from "./react/components/SlashMenu.js";
@@ -3,7 +3,7 @@ import { noop } from "../../../editor-kernel/utils.js";
3
3
  import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context.js";
4
4
  import { useLexicalEditor } from "../../../editor-kernel/react/useLexicalEditor.js";
5
5
  import { $splitNodeContainingQuery } from "../utils/utils.js";
6
- import { ISlashService } from "../service/i-slash-service.js";
6
+ import { ISlashService, flattenSlashOptions } from "../service/i-slash-service.js";
7
7
  import { SlashPlugin } from "../plugin/index.js";
8
8
  import SlashMenu from "./components/SlashMenu.js";
9
9
  import { setCancelablePromise } from "./utils.js";
@@ -35,6 +35,12 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
35
35
  const handleActiveKeyChange = useCallback((key) => {
36
36
  setActiveKey(key);
37
37
  }, []);
38
+ const setInitialActiveKey = useCallback((items) => {
39
+ if (!activeKey) {
40
+ const firstOption = flattenSlashOptions(items)[0];
41
+ setActiveKey(firstOption?.key ? String(firstOption.key) : null);
42
+ }
43
+ }, [activeKey]);
38
44
  useLayoutEffect(() => {
39
45
  const options = Children.map(children, (child) => {
40
46
  if (!child) return null;
@@ -53,7 +59,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
53
59
  cancelRef.current.cancel();
54
60
  if (Array.isArray(ctx.items)) {
55
61
  setOptions(ctx.items);
56
- if (!activeKey) setActiveKey(ctx.items?.[0]?.key);
62
+ setInitialActiveKey(ctx.items);
57
63
  } else {
58
64
  setLoading(true);
59
65
  const pr = setCancelablePromise((resolve, reject) => {
@@ -62,7 +68,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
62
68
  pr.promise.then((items) => {
63
69
  const typedItems = items;
64
70
  setOptions(typedItems);
65
- if (!activeKey) setActiveKey(typedItems?.[0]?.key);
71
+ setInitialActiveKey(typedItems);
66
72
  });
67
73
  cancelRef.current.cancel = () => {
68
74
  pr.cancel();
@@ -80,9 +86,9 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
80
86
  }
81
87
  });
82
88
  }, [
83
- activeKey,
84
89
  editor,
85
- close
90
+ close,
91
+ setInitialActiveKey
86
92
  ]);
87
93
  useLayoutEffect(() => {
88
94
  const slash = editor.requireService(ISlashService);
@@ -97,7 +103,6 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
97
103
  }
98
104
  }, [children]);
99
105
  const handleMenuSelect = useCallback((option) => {
100
- if ("type" in option && option.type === "divider") return;
101
106
  const lexicalEditor = editor.getLexicalEditor();
102
107
  if (lexicalEditor && resolution) lexicalEditor.update(() => {
103
108
  (resolution.match ? $splitNodeContainingQuery(resolution.match) : null)?.remove();
@@ -112,7 +117,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
112
117
  close
113
118
  ]);
114
119
  useLexicalEditor(() => {
115
- const pureOptions = options.filter((item) => !("type" in item && item.type === "divider") && "key" in item && Boolean(item.key));
120
+ const pureOptions = flattenSlashOptions(options).filter((item) => Boolean(item.key));
116
121
  return mergeRegister(editor.registerHighCommand(KEY_ARROW_DOWN_COMMAND, (payload) => {
117
122
  const event = payload;
118
123
  if (pureOptions !== null && pureOptions.length) {
@@ -144,7 +149,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
144
149
  }, COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_TAB_COMMAND, (payload) => {
145
150
  const event = payload;
146
151
  if (options === null || activeKey === null) return false;
147
- const selectedOption = options.find((opt) => "key" in opt && opt.key === activeKey);
152
+ const selectedOption = flattenSlashOptions(options).find((opt) => opt.key === activeKey);
148
153
  if (!selectedOption) return false;
149
154
  event.preventDefault();
150
155
  event.stopImmediatePropagation();
@@ -155,7 +160,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
155
160
  event.preventDefault();
156
161
  event.stopImmediatePropagation();
157
162
  if (options !== null && activeKey !== null) {
158
- const selectedOption = options.find((opt) => "key" in opt && opt.key === activeKey);
163
+ const selectedOption = flattenSlashOptions(options).find((opt) => opt.key === activeKey);
159
164
  if (selectedOption) handleMenuSelect(selectedOption);
160
165
  }
161
166
  return true;
@@ -1,19 +1,18 @@
1
1
  "use client";
2
- import { Icon, menuSharedStyles } from "@lobehub/ui";
2
+ import { flattenSlashOptions, isSlashDividerOption, isSlashSectionOption } from "../../service/i-slash-service.js";
3
+ import { Icon, LOBE_THEME_APP_ID, menuSharedStyles } from "@lobehub/ui";
3
4
  import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import { createStaticStyles } from "antd-style";
6
7
  import { createPortal } from "react-dom";
7
- import { flip, offset, shift, useFloating } from "@floating-ui/react";
8
+ import { autoUpdate, flip, offset, shift, size, useFloating } from "@floating-ui/react";
8
9
  //#region src/plugins/slash/react/components/DefaultSlashMenu.tsx
9
- const LOBE_THEME_APP_ID$1 = "lobe-ui-theme-app";
10
10
  const styles = createStaticStyles(({ css, cssVar }) => ({
11
11
  popup: css`
12
12
  scrollbar-width: none;
13
13
 
14
14
  overflow-y: auto;
15
15
 
16
- min-width: 200px;
17
16
  max-height: min(50vh, 400px);
18
17
  padding: 4px;
19
18
  border-radius: ${cssVar.borderRadius};
@@ -24,14 +23,155 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
24
23
  0 0 15px 0 #00000008,
25
24
  0 2px 30px 0 #00000014,
26
25
  0 0 0 1px ${cssVar.colorBorder} inset;
26
+ `,
27
+ popupCaret: css`
28
+ width: max-content;
29
+ min-width: 200px;
27
30
  `,
28
31
  root: css`
29
32
  z-index: 1100;
30
- width: max-content;
33
+ `,
34
+ section: css`
35
+ margin-block-start: 4px;
36
+ `,
37
+ sectionFirst: css`
38
+ margin-block-start: 0;
39
+ `,
40
+ sectionLabel: css`
41
+ padding-block: 12px 6px;
42
+ padding-inline: 8px;
43
+
44
+ font-size: 12px;
45
+ line-height: 1;
46
+ color: ${cssVar.colorTextDescription};
47
+
48
+ &:first-child {
49
+ padding-block-start: 6px;
50
+ }
51
+ `,
52
+ text: css`
53
+ display: flex;
54
+ flex: 1 1 auto;
55
+ flex-wrap: wrap;
56
+ gap: 2px 8px;
57
+ align-items: baseline;
58
+
59
+ min-width: 0;
60
+ `,
61
+ textDescription: css`
62
+ overflow: hidden;
63
+ flex: 0 1 auto;
64
+
65
+ min-width: 0;
66
+
67
+ color: ${cssVar.colorTextDescription};
68
+ text-overflow: ellipsis;
69
+ white-space: nowrap;
70
+ `,
71
+ textLabel: css`
72
+ overflow: hidden;
73
+ flex: 0 1 auto;
74
+
75
+ max-width: min(42ch, 55%);
76
+
77
+ font-weight: 500;
78
+ color: ${cssVar.colorText};
79
+ text-overflow: ellipsis;
80
+ white-space: nowrap;
31
81
  `
32
82
  }));
33
- const isDividerOption = (option) => "type" in option && option.type === "divider";
34
- const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, open, options, placement: forcePlacement, position }) => {
83
+ const renderMenuItem = (item, activeKey, onSelect) => {
84
+ const isHighlighted = item.key === activeKey;
85
+ const isDisabled = Boolean(item.disabled);
86
+ const description = item.metadata?.description;
87
+ return /* @__PURE__ */ jsxs("div", {
88
+ "aria-disabled": isDisabled || void 0,
89
+ className: menuSharedStyles.item,
90
+ "data-disabled": isDisabled ? "" : void 0,
91
+ "data-highlighted": isHighlighted ? "" : void 0,
92
+ onClick: () => {
93
+ if (isDisabled) return;
94
+ onSelect(item);
95
+ },
96
+ onMouseDown: (event) => event.preventDefault(),
97
+ role: "menuitem",
98
+ children: [
99
+ item.icon ? /* @__PURE__ */ jsx("span", {
100
+ className: menuSharedStyles.icon,
101
+ children: /* @__PURE__ */ jsx(Icon, { icon: item.icon })
102
+ }) : null,
103
+ /* @__PURE__ */ jsxs("span", {
104
+ className: styles.text,
105
+ children: [/* @__PURE__ */ jsx("span", {
106
+ className: styles.textLabel,
107
+ children: item.label
108
+ }), description ? /* @__PURE__ */ jsx("span", {
109
+ className: styles.textDescription,
110
+ children: description
111
+ }) : null]
112
+ }),
113
+ item.extra ? /* @__PURE__ */ jsx("span", {
114
+ className: menuSharedStyles.extra,
115
+ children: item.extra
116
+ }) : null
117
+ ]
118
+ }, String(item.key));
119
+ };
120
+ const renderItems = (options, activeKey, loading, onSelect) => {
121
+ if (loading) return /* @__PURE__ */ jsx("div", {
122
+ className: menuSharedStyles.empty,
123
+ children: "Loading..."
124
+ });
125
+ return options.map((opt, index) => {
126
+ if (isSlashDividerOption(opt)) return /* @__PURE__ */ jsx("div", { className: menuSharedStyles.separator }, `__divider_${index}`);
127
+ if (isSlashSectionOption(opt)) return /* @__PURE__ */ jsxs("div", {
128
+ className: `${styles.section} ${index === 0 ? styles.sectionFirst : ""}`,
129
+ children: [/* @__PURE__ */ jsx("div", {
130
+ className: styles.sectionLabel,
131
+ children: opt.label
132
+ }), opt.items.map((item) => renderMenuItem(item, activeKey, onSelect))]
133
+ }, String(opt.key ?? `__section_${index}`));
134
+ return renderMenuItem(opt, activeKey, onSelect);
135
+ });
136
+ };
137
+ const resolvePortalContainer = () => {
138
+ if (typeof document === "undefined") return null;
139
+ return document.getElementById(LOBE_THEME_APP_ID) ?? document.body;
140
+ };
141
+ const FullWidthSlashMenu = ({ activeKey, anchor, loading, onSelect, open, options, placement }) => {
142
+ const resolvedPlacement = placement === "bottom" ? "bottom-start" : "top-start";
143
+ const { refs, floatingStyles, isPositioned } = useFloating({
144
+ elements: { reference: anchor },
145
+ middleware: [
146
+ offset(8),
147
+ size({ apply({ rects, elements }) {
148
+ elements.floating.style.width = `${rects.reference.width}px`;
149
+ } }),
150
+ flip({ fallbackPlacements: placement === "bottom" ? ["top-start"] : ["bottom-start"] }),
151
+ shift({ padding: 8 })
152
+ ],
153
+ open,
154
+ placement: resolvedPlacement,
155
+ strategy: "fixed",
156
+ whileElementsMounted: autoUpdate
157
+ });
158
+ const portalContainer = resolvePortalContainer();
159
+ if (!portalContainer) return null;
160
+ return createPortal(/* @__PURE__ */ jsx("div", {
161
+ className: styles.root,
162
+ "data-resolved-placement": resolvedPlacement,
163
+ ref: refs.setFloating,
164
+ style: {
165
+ ...floatingStyles,
166
+ visibility: isPositioned ? "visible" : "hidden"
167
+ },
168
+ children: /* @__PURE__ */ jsx("div", {
169
+ className: styles.popup,
170
+ children: renderItems(options, activeKey, loading, onSelect)
171
+ })
172
+ }), portalContainer);
173
+ };
174
+ const CaretSlashMenu = ({ activeKey, loading, onSelect, open, options, placement: forcePlacement, position }) => {
35
175
  const resolvedPlacement = forcePlacement ? `${forcePlacement}-start` : "top-start";
36
176
  const middleware = useMemo(() => [
37
177
  offset(8),
@@ -62,62 +202,19 @@ const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, ope
62
202
  useEffect(() => {
63
203
  if (!open) return;
64
204
  const onScroll = () => update();
65
- const container = getPopupContainer?.();
66
205
  window.addEventListener("scroll", onScroll, {
67
206
  capture: true,
68
207
  passive: true
69
208
  });
70
- if (container) container.addEventListener("scroll", onScroll, { passive: true });
71
209
  return () => {
72
210
  window.removeEventListener("scroll", onScroll, { capture: true });
73
- if (container) container.removeEventListener("scroll", onScroll);
74
211
  };
75
- }, [
76
- open,
77
- getPopupContainer,
78
- update
79
- ]);
80
- const hasVisibleItems = options?.some((item) => !isDividerOption(item));
81
- if (!open || !hasVisibleItems) return null;
82
- const portalContainer = getPopupContainer?.() || document.getElementById(LOBE_THEME_APP_ID$1) || document.body;
83
- const renderedItems = loading ? /* @__PURE__ */ jsx("div", {
84
- className: menuSharedStyles.empty,
85
- children: "Loading..."
86
- }) : options.map((opt, index) => {
87
- if (isDividerOption(opt)) return /* @__PURE__ */ jsx("div", { className: menuSharedStyles.separator }, `__divider_${index}`);
88
- const item = opt;
89
- const isHighlighted = item.key === activeKey;
90
- const isDisabled = Boolean(item.disabled);
91
- return /* @__PURE__ */ jsxs("div", {
92
- "aria-disabled": isDisabled || void 0,
93
- className: menuSharedStyles.item,
94
- "data-disabled": isDisabled ? "" : void 0,
95
- "data-highlighted": isHighlighted ? "" : void 0,
96
- onClick: () => {
97
- if (isDisabled) return;
98
- onSelect(item);
99
- },
100
- onMouseDown: (event) => event.preventDefault(),
101
- role: "menuitem",
102
- children: [
103
- item.icon ? /* @__PURE__ */ jsx("span", {
104
- className: menuSharedStyles.icon,
105
- children: /* @__PURE__ */ jsx(Icon, { icon: item.icon })
106
- }) : null,
107
- /* @__PURE__ */ jsx("span", {
108
- className: menuSharedStyles.label,
109
- children: item.label
110
- }),
111
- item.extra ? /* @__PURE__ */ jsx("span", {
112
- className: menuSharedStyles.extra,
113
- children: item.extra
114
- }) : null
115
- ]
116
- }, String(item.key));
117
- });
212
+ }, [open, update]);
213
+ const portalContainer = resolvePortalContainer();
214
+ if (!portalContainer) return null;
118
215
  return createPortal(/* @__PURE__ */ jsx("div", {
119
- className: styles.root,
120
- "data-resloved-placement": resolvedPlacement,
216
+ className: `${styles.root} ${styles.popupCaret}`,
217
+ "data-resolved-placement": resolvedPlacement,
121
218
  ref: refs.setFloating,
122
219
  style: {
123
220
  ...floatingStyles,
@@ -125,10 +222,34 @@ const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, ope
125
222
  },
126
223
  children: /* @__PURE__ */ jsx("div", {
127
224
  className: styles.popup,
128
- children: renderedItems
225
+ children: renderItems(options, activeKey, loading, onSelect)
129
226
  })
130
227
  }), portalContainer);
131
228
  };
229
+ const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, open, options, placement, position }) => {
230
+ const hasVisibleItems = flattenSlashOptions(options).length > 0;
231
+ if (!open || !hasVisibleItems) return null;
232
+ const anchor = getPopupContainer?.() ?? null;
233
+ if (anchor) return /* @__PURE__ */ jsx(FullWidthSlashMenu, {
234
+ activeKey,
235
+ anchor,
236
+ loading,
237
+ onSelect,
238
+ open,
239
+ options,
240
+ placement: placement ?? "top"
241
+ });
242
+ if (!position) return null;
243
+ return /* @__PURE__ */ jsx(CaretSlashMenu, {
244
+ activeKey,
245
+ loading,
246
+ onSelect,
247
+ open,
248
+ options,
249
+ placement,
250
+ position
251
+ });
252
+ };
132
253
  DefaultSlashMenu.displayName = "DefaultSlashMenu";
133
254
  //#endregion
134
255
  export { DefaultSlashMenu as default };
@@ -94,8 +94,11 @@ interface SlashMenuProps {
94
94
  options: Array<ISlashOption>;
95
95
  /** Force menu placement direction, skipping auto-flip detection */
96
96
  placement?: 'bottom' | 'top';
97
- /** Menu position */
98
- position: {
97
+ /**
98
+ * Caret position used by the floating fallback when no getPopupContainer
99
+ * is provided. Ignored in full-width mode.
100
+ */
101
+ position?: {
99
102
  getRect?: () => DOMRect;
100
103
  rect?: DOMRect;
101
104
  x: number;
@@ -1,5 +1,6 @@
1
1
  import { IEditor, IServiceID } from "../../../types/kernel.js";
2
2
  import { DropdownMenuItemType } from "@lobehub/ui";
3
+ import { ReactNode } from "react";
3
4
  import Fuse, { IFuseOptions } from "fuse.js";
4
5
 
5
6
  //#region src/plugins/slash/service/i-slash-service.d.ts
@@ -10,7 +11,17 @@ interface ISlashMenuOption extends DropdownMenuItemType {
10
11
  metadata?: Record<string, any>;
11
12
  onSelect?: (editor: IEditor, matchingString: string) => void;
12
13
  }
13
- type ISlashOption = ISlashMenuOption | ISlashDividerOption;
14
+ interface ISlashSectionOption {
15
+ items: ISlashMenuOption[];
16
+ key?: string;
17
+ label: ReactNode;
18
+ type: 'section';
19
+ }
20
+ type ISlashOption = ISlashMenuOption | ISlashDividerOption | ISlashSectionOption;
21
+ declare const isSlashDividerOption: (option: ISlashOption) => option is ISlashDividerOption;
22
+ declare const isSlashSectionOption: (option: ISlashOption) => option is ISlashSectionOption;
23
+ declare const isSlashMenuOption: (option: ISlashOption) => option is ISlashMenuOption;
24
+ declare const flattenSlashOptions: (options: ISlashOption[]) => ISlashMenuOption[];
14
25
  interface SlashOptions {
15
26
  allowWhitespace?: boolean;
16
27
  /**
@@ -47,4 +58,4 @@ interface ISlashService {
47
58
  }
48
59
  declare const ISlashService: IServiceID<ISlashService>;
49
60
  //#endregion
50
- export { ISlashMenuOption, ISlashOption, ISlashService, SlashOptions };
61
+ export { ISlashDividerOption, ISlashMenuOption, ISlashOption, ISlashSectionOption, ISlashService, SlashOptions, flattenSlashOptions, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption };
@@ -4,6 +4,14 @@ import { getBasicTypeaheadTriggerMatch } from "../utils/utils.js";
4
4
  import Fuse from "fuse.js";
5
5
  //#region src/plugins/slash/service/i-slash-service.ts
6
6
  init_debug();
7
+ const isSlashDividerOption = (option) => "type" in option && option.type === "divider";
8
+ const isSlashSectionOption = (option) => "type" in option && option.type === "section";
9
+ const isSlashMenuOption = (option) => !isSlashDividerOption(option) && !isSlashSectionOption(option);
10
+ const flattenSlashOptions = (options) => options.flatMap((option) => {
11
+ if (isSlashDividerOption(option)) return [];
12
+ if (isSlashSectionOption(option)) return option.items;
13
+ return [option];
14
+ });
7
15
  const ISlashService = genServiceId("SlashService");
8
16
  var SlashService = class {
9
17
  constructor(kernel) {
@@ -25,7 +33,7 @@ var SlashService = class {
25
33
  }));
26
34
  this.logger.debug(`⚡ Slash trigger: ${options.trigger}`);
27
35
  if (Array.isArray(options.items)) {
28
- const searchableItems = options.items.filter((item) => !("type" in item) || item.type !== "divider");
36
+ const searchableItems = flattenSlashOptions(options.items);
29
37
  const fuseConfig = options.fuseOptions || { keys: options.searchKeys || ["key"] };
30
38
  this.triggerFuseMap.set(options.trigger, new Fuse(searchableItems, fuseConfig));
31
39
  }
@@ -52,4 +60,4 @@ var SlashService = class {
52
60
  }
53
61
  };
54
62
  //#endregion
55
- export { ISlashService, SlashService };
63
+ export { ISlashService, SlashService, flattenSlashOptions, isSlashDividerOption, isSlashMenuOption, isSlashSectionOption };
@@ -38,11 +38,11 @@ const ChatInput = (props) => {
38
38
  return /* @__PURE__ */ jsxs(Flexbox, {
39
39
  className: cx(isDarkMode ? styles.containerDark : styles.containerLight, styles.root, className),
40
40
  height: fullscreen ? "100%" : void 0,
41
+ ref: slashMenuRef,
41
42
  style,
42
43
  width: "100%",
43
44
  ...rest,
44
45
  children: [
45
- slashMenuRef && /* @__PURE__ */ jsx("div", { ref: slashMenuRef }),
46
46
  /* @__PURE__ */ jsx("div", {
47
47
  className: cx(styles.header, classNames?.header),
48
48
  ref: headerRef,
@@ -21,6 +21,11 @@ interface ChatInputProps extends Omit<FlexboxProps, 'height'> {
21
21
  resize?: boolean;
22
22
  resizeMaxHeightOffset?: number;
23
23
  showResizeHandle?: boolean;
24
+ /**
25
+ * Ref attached to the ChatInput root element. Pass the same ref to
26
+ * `<Editor getPopupContainer={() => ref.current}>` to anchor the slash /
27
+ * mention menu to the ChatInput's outer edges (full-width).
28
+ */
24
29
  slashMenuRef?: Ref<HTMLDivElement>;
25
30
  styles?: {
26
31
  body?: CSSProperties;
package/es/react.d.ts CHANGED
@@ -15,10 +15,6 @@ import { Editor } from "./react/Editor/index.js";
15
15
  import { EditorProvider, EditorProviderConfig, EditorProviderProps, useEditorContent } from "./react/EditorProvider/index.js";
16
16
  import { FloatActionsProps } from "./react/FloatActions/type.js";
17
17
  import { FloatActions } from "./react/FloatActions/FloatActions.js";
18
- import { FloatMenuProps } from "./react/FloatMenu/type.js";
19
- import { FloatMenu } from "./react/FloatMenu/FloatMenu.js";
20
18
  import { SendButtonProps } from "./react/SendButton/type.js";
21
19
  import { SendButton } from "./react/SendButton/SendButton.js";
22
- import { SlashMenuProps } from "./react/SlashMenu/type.js";
23
- import { SlashMenu } from "./react/SlashMenu/SlashMenu.js";
24
- 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, FloatMenu, type FloatMenuProps, SendButton, type SendButtonProps, SlashMenu, type SlashMenuProps, useEditor, useEditorContent, useEditorState, withProps };
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 };
package/es/react.js CHANGED
@@ -9,7 +9,5 @@ import { EditorProvider, useEditorContent } from "./react/EditorProvider/index.j
9
9
  import { withProps } from "./react/Editor/utils.js";
10
10
  import Editor from "./react/Editor/index.js";
11
11
  import FloatActions from "./react/FloatActions/FloatActions.js";
12
- import FloatMenu from "./react/FloatMenu/FloatMenu.js";
13
12
  import SendButton from "./react/SendButton/SendButton.js";
14
- import SlashMenu from "./react/SlashMenu/SlashMenu.js";
15
- export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, ChatInputActions, CodeLanguageSelect, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, EditorProvider, FloatActions, FloatMenu, SendButton, SlashMenu, useEditor, useEditorContent, useEditorState, withProps };
13
+ export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, ChatInputActions, CodeLanguageSelect, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, EditorProvider, FloatActions, SendButton, useEditor, useEditorContent, useEditorState, withProps };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/editor",
3
- "version": "4.18.0",
3
+ "version": "4.19.0",
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",
@@ -1,7 +0,0 @@
1
- import { FloatMenuProps } from "./type.js";
2
- import { FC } from "react";
3
-
4
- //#region src/react/FloatMenu/FloatMenu.d.ts
5
- declare const FloatMenu: FC<FloatMenuProps>;
6
- //#endregion
7
- export { FloatMenu };
@@ -1,32 +0,0 @@
1
- "use client";
2
- import { styles } from "./style.js";
3
- import { Block, Flexbox } from "@lobehub/ui";
4
- import { jsx } from "react/jsx-runtime";
5
- import { cx } from "antd-style";
6
- import { createPortal } from "react-dom";
7
- //#region src/react/FloatMenu/FloatMenu.tsx
8
- const FloatMenu = ({ className, style, getPopupContainer, children, maxHeight = "min(50vh, 640px)", open, placement = "top", styles: customStyles, classNames }) => {
9
- const parent = getPopupContainer();
10
- if (!parent) return;
11
- if (!open) return;
12
- return createPortal(/* @__PURE__ */ jsx(Flexbox, {
13
- className: cx(placement === "bottom" ? styles.rootBottom : styles.rootTop, classNames?.root),
14
- paddingInline: 8,
15
- style: customStyles?.root,
16
- width: "100%",
17
- children: /* @__PURE__ */ jsx(Block, {
18
- className: cx(styles.container, className, classNames?.container),
19
- shadow: true,
20
- style: {
21
- maxHeight,
22
- ...style,
23
- ...customStyles?.container
24
- },
25
- variant: "outlined",
26
- children
27
- })
28
- }), parent);
29
- };
30
- FloatMenu.displayName = "FloatMenu";
31
- //#endregion
32
- export { FloatMenu as default };
@@ -1,2 +0,0 @@
1
- import { FloatMenuProps } from "./type.js";
2
- import { FloatMenu } from "./FloatMenu.js";
@@ -1,28 +0,0 @@
1
- import { createStaticStyles } from "antd-style";
2
- //#region src/react/FloatMenu/style.ts
3
- const styles = createStaticStyles(({ css, cssVar }) => ({
4
- container: css`
5
- position: relative;
6
- overflow: hidden auto;
7
- background: ${cssVar.colorBgElevated};
8
- `,
9
- containerWithMaxHeight: css`
10
- /* maxHeight is set via inline style as it's dynamic */
11
- `,
12
- rootBottom: css`
13
- position: absolute;
14
- z-index: 9999;
15
- inset-block-start: 100%;
16
- inset-inline-start: 0;
17
-
18
- padding-block-start: 8px;
19
- `,
20
- rootTop: css`
21
- position: absolute;
22
- inset-block-start: -8px;
23
- inset-inline-start: 0;
24
- transform: translateY(-100%);
25
- `
26
- }));
27
- //#endregion
28
- export { styles };
@@ -1,25 +0,0 @@
1
- import { BlockProps } from "@lobehub/ui";
2
- import { CSSProperties, ReactNode } from "react";
3
-
4
- //#region src/react/FloatMenu/type.d.ts
5
- interface FloatMenuProps {
6
- children?: ReactNode;
7
- className?: string;
8
- classNames?: {
9
- container?: string;
10
- root?: string;
11
- };
12
- containerProps?: Omit<BlockProps, 'children'>;
13
- getPopupContainer: () => HTMLDivElement | null;
14
- maxHeight?: string | number;
15
- open?: boolean;
16
- /** Menu placement direction: 'top' (default) or 'bottom' */
17
- placement?: 'bottom' | 'top';
18
- style?: CSSProperties;
19
- styles?: {
20
- container?: CSSProperties;
21
- root?: CSSProperties;
22
- };
23
- }
24
- //#endregion
25
- export { FloatMenuProps };
@@ -1,7 +0,0 @@
1
- import { SlashMenuProps } from "./type.js";
2
- import { FC } from "react";
3
-
4
- //#region src/react/SlashMenu/SlashMenu.d.ts
5
- declare const SlashMenu: FC<SlashMenuProps>;
6
- //#endregion
7
- export { SlashMenu };
@@ -1,40 +0,0 @@
1
- "use client";
2
- import FloatMenu from "../FloatMenu/FloatMenu.js";
3
- import { Menu } from "@lobehub/ui";
4
- import { useCallback } from "react";
5
- import { jsx } from "react/jsx-runtime";
6
- //#region src/react/SlashMenu/SlashMenu.tsx
7
- const SlashMenu = ({ options, activeKey, loading, onSelect, classNames, styles: customStyles, menuProps, ...floatMenuProps }) => {
8
- const handleMenuClick = useCallback(({ key }) => {
9
- if (!onSelect) return;
10
- const option = options.find((item) => "key" in item && item.key === key);
11
- if (option) onSelect?.(option);
12
- }, [options, onSelect]);
13
- return /* @__PURE__ */ jsx(FloatMenu, {
14
- classNames: {
15
- container: classNames?.container,
16
- root: classNames?.root
17
- },
18
- styles: {
19
- container: customStyles?.container,
20
- root: customStyles?.root
21
- },
22
- ...floatMenuProps,
23
- children: /* @__PURE__ */ jsx(Menu, {
24
- className: classNames?.menu,
25
- items: loading ? [{
26
- disabled: true,
27
- key: "loading",
28
- label: "Loading..."
29
- }] : options,
30
- mode: "inline",
31
- onClick: handleMenuClick,
32
- selectedKeys: activeKey ? [activeKey] : void 0,
33
- style: customStyles?.menu,
34
- ...menuProps
35
- })
36
- });
37
- };
38
- SlashMenu.displayName = "SlashMenu";
39
- //#endregion
40
- export { SlashMenu as default };
@@ -1,2 +0,0 @@
1
- import { SlashMenuProps } from "./type.js";
2
- import { SlashMenu } from "./SlashMenu.js";
@@ -1,17 +0,0 @@
1
- import { MenuRenderProps } from "../../plugins/slash/react/type.js";
2
- import { FloatMenuProps } from "../FloatMenu/type.js";
3
- import { MenuProps } from "@lobehub/ui";
4
- import { CSSProperties } from "react";
5
-
6
- //#region src/react/SlashMenu/type.d.ts
7
- interface SlashMenuProps extends MenuRenderProps, Omit<FloatMenuProps, 'children'> {
8
- classNames?: FloatMenuProps['classNames'] & {
9
- menu?: string;
10
- };
11
- menuProps?: MenuProps;
12
- styles?: FloatMenuProps['styles'] & {
13
- menu?: CSSProperties;
14
- };
15
- }
16
- //#endregion
17
- export { SlashMenuProps };