Skip to content

Commit 6c3f5c2

Browse files
committed
🐛 fix(block): hide floating menu when editor is not editable
Treat `editable === false` as a suppressed state inside ReactBlockPlugin so the left-side add-block button and drag handle do not render when the editor is read-only. Add a Toggle Editable demo for verification.
1 parent a07f692 commit 6c3f5c2

3 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/plugins/block/react/ReactBlockPlugin.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { createPortal } from 'react-dom';
2121

2222
import { useLexicalEditor } from '@/editor-kernel/react';
2323
import { useLexicalComposerContext } from '@/editor-kernel/react/react-context';
24+
import { useEditable } from '@/editor-kernel/react/useEditable';
2425
import { ILocaleKeys } from '@/types';
2526
import { createDebugLogger } from '@/utils/debug';
2627

@@ -108,7 +109,8 @@ const ReactBlockPlugin: FC<ReactBlockPluginProps> = (props) => {
108109
const [isDragging, setIsDragging] = useState(false);
109110
const [focusedTableBlockId, setFocusedTableBlockId] = useState<string | null>(null);
110111
const [blockMenuService, setBlockMenuService] = useState<BlockMenuService | null>(null);
111-
const blockMenuSuppressed = blockMenuService?.isMenuSuppressed() ?? false;
112+
const { editable } = useEditable();
113+
const blockMenuSuppressed = (blockMenuService?.isMenuSuppressed() ?? false) || editable === false;
112114

113115
useLayoutEffect(() => {
114116
if (locale) {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { IEditor, ReactBlockPlugin } from '@lobehub/editor';
2+
import { Editor, useEditor } from '@lobehub/editor/react';
3+
import { Button, type CollapseProps, Flexbox, Text } from '@lobehub/ui';
4+
import { debounce } from 'es-toolkit';
5+
import { type FC, useMemo, useState } from 'react';
6+
7+
import Container from './Container';
8+
import content from './disableMakrdownData.json';
9+
10+
const Demo: FC<Pick<CollapseProps, 'collapsible' | 'defaultActiveKey'>> = (props) => {
11+
const editor = useEditor();
12+
const [editable, setEditable] = useState(true);
13+
const [json, setJson] = useState('');
14+
const [markdown, setMarkdown] = useState('');
15+
16+
const handleChange = useMemo(
17+
() =>
18+
debounce((editor: IEditor) => {
19+
const markdownContent = editor.getDocument('markdown') as unknown as string;
20+
const jsonContent = editor.getDocument('json') as unknown as Record<string, any>;
21+
setMarkdown(markdownContent || '');
22+
setJson(JSON.stringify(jsonContent || {}, null, 2));
23+
}, 300),
24+
[],
25+
);
26+
27+
const handleInit = (editor: IEditor) => {
28+
handleChange(editor);
29+
};
30+
31+
return (
32+
<Container json={json} markdown={markdown} {...props}>
33+
<Flexbox align={'center'} gap={12} horizontal style={{ padding: 16 }}>
34+
<Button onClick={() => setEditable((value) => !value)} type={'primary'}>
35+
Toggle editable (current: {String(editable)})
36+
</Button>
37+
<Text type={'secondary'}>
38+
When editable is false, the left-side add-block / drag handle should disappear.
39+
</Text>
40+
</Flexbox>
41+
<Editor
42+
content={content}
43+
editable={editable}
44+
editor={editor}
45+
onInit={handleInit}
46+
onTextChange={handleChange}
47+
placeholder={'Type something...'}
48+
plugins={[ReactBlockPlugin]}
49+
/>
50+
</Container>
51+
);
52+
};
53+
54+
export default Demo;

src/react/Editor/index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ Editor is a powerful and extensible rich text editor component designed for mode
3232

3333
<code src="./demos/disableMarkdown.tsx" nopadding iframe></code>
3434

35+
## Toggle Editable
36+
37+
When `editable` is `false`, the floating block menu (add-block button and drag handle) on the left side should not appear.
38+
39+
<code src="./demos/editable.tsx" nopadding iframe></code>
40+
3541
## Paste as Plain Text
3642

3743
Force all pasted content to be inserted as plain text, stripping any rich text formatting (bold, italic, links, etc).

0 commit comments

Comments
 (0)