Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 49 additions & 14 deletions packages/modules.editor/src/hooks/useBlockMenuActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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();
Expand Down Expand Up @@ -110,6 +144,7 @@ export const useBlockMenuActions = (
downloadImage,
moveDown,
moveUp,
insertBlock,
};
};

Expand Down
10 changes: 5 additions & 5 deletions packages/modules.editor/src/ui/components/BlockMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand All @@ -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"
>
<DropdownMenuItem className={menuItemClass} onSelect={() => changeType('paragraph')}>
<DropdownMenuItem className={menuItemClass} onSelect={() => insertBlock('paragraph')}>
<Text size="sm" className="size-6" />
<span>Текст</span>
</DropdownMenuItem>

<DropdownMenuItem className={menuItemClass} onSelect={() => changeType('heading1')}>
<DropdownMenuItem className={menuItemClass} onSelect={() => insertBlock('heading1')}>
<H1 size="sm" className="size-6" />
<span>Заголовок 1</span>
</DropdownMenuItem>

<DropdownMenuItem className={menuItemClass} onSelect={() => changeType('heading2')}>
<DropdownMenuItem className={menuItemClass} onSelect={() => insertBlock('heading2')}>
<H2 size="sm" className="size-6" />
<span>Заголовок 2</span>
</DropdownMenuItem>

<DropdownMenuItem className={menuItemClass} onSelect={() => changeType('heading3')}>
<DropdownMenuItem className={menuItemClass} onSelect={() => insertBlock('heading3')}>
<H3 size="sm" className="size-6" />
<span>Заголовок 3</span>
</DropdownMenuItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}, []);
Expand All @@ -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;
Expand Down
Loading