diff --git a/packages/modules.editor/src/hooks/useBlockMenuActions.ts b/packages/modules.editor/src/hooks/useBlockMenuActions.ts index ea49b144..6bb0836d 100644 --- a/packages/modules.editor/src/hooks/useBlockMenuActions.ts +++ b/packages/modules.editor/src/hooks/useBlockMenuActions.ts @@ -33,19 +33,55 @@ export const useBlockMenuActions = ( const insertImage = (src: string, alt?: string) => { if (!editor || !editor.isEditable) return; - const endPos = editor.state.doc.content.size; + const activeBlock = getCurrentBlock(editor); + + if (!activeBlock?.node) return; + + const insertPos = activeBlock.pos + activeBlock.node.nodeSize; + editor .chain() .focus() - .insertContentAt(endPos, [ - { - type: 'image', - attrs: { src, alt }, - }, - ]) + .insertContentAt(insertPos, { + type: 'image', + attrs: { src, alt }, + }) .run(); }; + const createBlock = ( + editor: Editor | null, + type: BlockTypeT, + activeBlock: ActiveBlockT | undefined, + ) => { + if (!editor || !editor.isEditable || !type || !activeBlock) return; + + const currentBlock = getCurrentBlock(editor, activeBlock); + + if (!currentBlock?.node) return; + + const config = NODE_TYPES_MAP[type]; + if (!config) return; + + const insertPos = currentBlock.pos + currentBlock.node.nodeSize; + + const nodeType = editor.schema.nodes[config.type]; + if (!nodeType) return; + + const newNode = nodeType.createAndFill(config.attrs); + if (!newNode) return; + + editor.chain().focus().insertContentAt(insertPos, newNode.toJSON()).run(); + }; + + const downloadImage = (src: string) => { + const link = document.createElement('a'); + link.setAttribute('target', '_blank'); + link.href = src; + link.download = 'image.png'; + link.click(); + }; + const changeType = (type?: BlockTypeT) => { if (!editor || !editor.isEditable || !type || !getActiveBlock) return; @@ -69,15 +105,13 @@ export const useBlockMenuActions = ( }); }; - const downloadImage = (src: string) => { - const link = document.createElement('a'); - link.setAttribute('target', '_blank'); - link.href = src; - link.download = 'image.png'; - link.click(); + // В момент вызова получаем свежую позицию + const insertBlock = (type: BlockTypeT) => { + if (!getActiveBlock) return; + const activeBlock = getActiveBlock(); + return createBlock(editor, type, activeBlock); }; - // В момент вызова получаем свежую позицию const moveUp = () => { if (!getActiveBlock) return; const activeBlock = getActiveBlock(); @@ -110,6 +144,7 @@ export const useBlockMenuActions = ( downloadImage, moveDown, moveUp, + insertBlock, }; }; diff --git a/packages/modules.editor/src/ui/components/BlockMenu.tsx b/packages/modules.editor/src/ui/components/BlockMenu.tsx index 7488f496..44566fd9 100644 --- a/packages/modules.editor/src/ui/components/BlockMenu.tsx +++ b/packages/modules.editor/src/ui/components/BlockMenu.tsx @@ -43,7 +43,7 @@ export const BlockMenu = ({ }: BlockMenuPropsT) => { const isMac = navigator.platform.toUpperCase().includes('MAC'); const { openModal } = useInterfaceStore(); - const { changeType, duplicate, remove, moveUp, moveDown } = useBlockMenuActions( + const { insertBlock, duplicate, remove, moveUp, moveDown } = useBlockMenuActions( editor, getActiveBlock, ); @@ -65,22 +65,22 @@ export const BlockMenu = ({ onCloseAutoFocus={(e) => e.preventDefault()} className="border-gray-10 bg-gray-0 flex w-auto flex-col gap-1 space-y-1 rounded-lg border p-2 text-gray-100" > - changeType('paragraph')}> + insertBlock('paragraph')}> Текст - changeType('heading1')}> + insertBlock('heading1')}>

Заголовок 1 - changeType('heading2')}> + insertBlock('heading2')}>

Заголовок 2 - changeType('heading3')}> + insertBlock('heading3')}>

Заголовок 3 diff --git a/packages/modules.editor/src/ui/components/DragHandleWrapper.tsx b/packages/modules.editor/src/ui/components/DragHandleWrapper.tsx index ddc341f3..bd67a6c8 100644 --- a/packages/modules.editor/src/ui/components/DragHandleWrapper.tsx +++ b/packages/modules.editor/src/ui/components/DragHandleWrapper.tsx @@ -26,7 +26,7 @@ export const DragHandleWrapper = ({ const handleNodeChange = useCallback((data: ActiveBlockT) => { if (!data?.node || data?.pos === null) return; - const id = data.node.attrs?.['data-uid'] ?? data.node.attrs?.id ?? null; + const id = data.node.attrs?.['id'] ?? data.node.attrs?.id ?? null; activeBlockRef.current = { pos: data.pos, id }; }, []); @@ -44,7 +44,7 @@ export const DragHandleWrapper = ({ let found: ActiveBlockT | undefined; doc.descendants((node, nodePos) => { if (found) return false; - const nodeId = node.attrs?.['data-uid'] ?? node.attrs?.id; + const nodeId = node.attrs?.['id'] ?? node.attrs?.id; if (nodeId === id && node.isBlock) { found = { editor, node, pos: nodePos }; return false;