From 230a33e91092a93c6c3da21a60facc94c5c1116b Mon Sep 17 00:00:00 2001 From: Richard Olsson Date: Sat, 18 Jan 2025 18:31:18 +0100 Subject: [PATCH 1/5] Fix positioning of block inserts --- src/zui/ZUIEditor/EditorOverlays/index.tsx | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/zui/ZUIEditor/EditorOverlays/index.tsx b/src/zui/ZUIEditor/EditorOverlays/index.tsx index 390fa992c..b58f4e660 100644 --- a/src/zui/ZUIEditor/EditorOverlays/index.tsx +++ b/src/zui/ZUIEditor/EditorOverlays/index.tsx @@ -105,20 +105,29 @@ const EditorOverlays: FC = ({ blocks, enableVariable }) => { const blockDividers: BlockDividerData[] = [ { pos: 0, - y: 0, + y: 20, }, - ...state.doc.children.map((blockNode) => { - pos += blockNode.nodeSize; - const rect = view.coordsAtPos(pos - 1); + ]; + + const containerRect = view.dom.getBoundingClientRect(); + state.doc.children.forEach((blockNode) => { + const elem = view.nodeDOM(pos); + + pos += blockNode.nodeSize; + + if (elem instanceof HTMLElement) { + if (elem.nodeName == 'P' && elem.textContent?.trim().length == 0) { + return; + } - const containerRect = view.dom.getBoundingClientRect(); + const rect = elem.getBoundingClientRect(); - return { - pos: pos, + blockDividers.push({ + pos, y: rect.bottom - containerRect.top, - }; - }), - ]; + }); + } + }); const showBlockToolbar = !showBlockMenu && !!currentBlock && !typing; From c72200972dec936f1c028f4b9ece8f69d481e88d Mon Sep 17 00:00:00 2001 From: Richard Olsson Date: Sat, 18 Jan 2025 18:32:30 +0100 Subject: [PATCH 2/5] Fix bug causing new paragraphs to replace images --- src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx | 5 ++--- src/zui/ZUIEditor/extensions/BlockMenuExtension.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx b/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx index df58ab535..03d5008b5 100644 --- a/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx +++ b/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx @@ -12,7 +12,7 @@ type BlockInsertProps = { }; const BlockInsert: FC = ({ blockDividers, mouseY }) => { - const { insertParagraph, focus } = useCommands(); + const { insertEmptyParagraph, focus } = useCommands(); return ( @@ -44,9 +44,8 @@ const BlockInsert: FC = ({ blockDividers, mouseY }) => { > { - insertParagraph(' ', { selection: pos }); + insertEmptyParagraph(pos); focus(pos); }} > diff --git a/src/zui/ZUIEditor/extensions/BlockMenuExtension.ts b/src/zui/ZUIEditor/extensions/BlockMenuExtension.ts index 206495817..a97c6b6e5 100644 --- a/src/zui/ZUIEditor/extensions/BlockMenuExtension.ts +++ b/src/zui/ZUIEditor/extensions/BlockMenuExtension.ts @@ -9,6 +9,7 @@ import { Handler, PlainExtension, } from 'remirror'; +import { ParagraphExtension } from 'remirror/extensions'; type BlockMenuOptions = { blockFactories: Record Node>; @@ -68,6 +69,17 @@ class BlockMenuExtension extends PlainExtension { }; } + /* eslint-disable @typescript-eslint/ban-ts-comment */ + //@ts-ignore + @command() + insertEmptyParagraph(pos: number): CommandFunction { + return ({ dispatch, tr }) => { + const node = this.store.getExtension(ParagraphExtension).type.create(); + dispatch?.(tr.insert(pos, node)); + return true; + }; + } + get name(): string { return 'zblockmenu'; } From 7db66185ba6e01fc21b73fed764808b220362f1a Mon Sep 17 00:00:00 2001 From: Richard Olsson Date: Sat, 18 Jan 2025 18:42:49 +0100 Subject: [PATCH 3/5] Tweak styling of overlays --- src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx | 4 ++-- src/zui/ZUIEditor/EditorOverlays/index.tsx | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx b/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx index 03d5008b5..fc9df5b06 100644 --- a/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx +++ b/src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx @@ -18,8 +18,8 @@ const BlockInsert: FC = ({ blockDividers, mouseY }) => { {blockDividers.map(({ pos, y }, index) => { const visible = Math.abs(mouseY - y) < 20; - const isFirst = index == 0; - const offset = isFirst ? -6 : 12; + const offset = 8; + return ( = ({ blocks, enableVariable }) => { const blockDividers: BlockDividerData[] = [ { pos: 0, - y: 20, + y: 8, }, ]; @@ -141,12 +141,15 @@ const EditorOverlays: FC = ({ blocks, enableVariable }) => { )} From 809ab4a42cc9a1b7dc3f12e9d6ee72cd3b592d42 Mon Sep 17 00:00:00 2001 From: Richard Olsson Date: Sat, 18 Jan 2025 19:10:27 +0100 Subject: [PATCH 4/5] Add link to placeholder to open block menu --- src/zui/ZUIEditor/EmptyBlockPlaceholder.tsx | 39 ++++++++++++++++----- src/zui/ZUIEditor/index.tsx | 2 +- src/zui/l10n/messageIds.ts | 7 +++- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/zui/ZUIEditor/EmptyBlockPlaceholder.tsx b/src/zui/ZUIEditor/EmptyBlockPlaceholder.tsx index 9a877409a..13d7fd5f4 100644 --- a/src/zui/ZUIEditor/EmptyBlockPlaceholder.tsx +++ b/src/zui/ZUIEditor/EmptyBlockPlaceholder.tsx @@ -1,27 +1,50 @@ -import { Box, Typography } from '@mui/material'; -import { usePositioner } from '@remirror/react'; +import { Box, Link, Typography } from '@mui/material'; +import { useCommands, usePositioner } from '@remirror/react'; import { FC } from 'react'; -type Props = { - placeholder: string; -}; +import { Msg } from 'core/i18n'; +import messageIds from 'zui/l10n/messageIds'; -const EmptyBlockPlaceholder: FC = ({ placeholder }) => { +const EmptyBlockPlaceholder: FC = () => { const positioner = usePositioner('emptyBlockStart'); + const { focus, insertText } = useCommands(); return ( {positioner.active && ( - {placeholder} + { + const pos = positioner.data.pos; + if (pos) { + insertText('/', { from: positioner.data.pos }); + focus(pos + 2); + } + }} + sx={{ + cursor: 'pointer', + }} + > + + + ), + }} + /> )} diff --git a/src/zui/ZUIEditor/index.tsx b/src/zui/ZUIEditor/index.tsx index a45ab1bf8..6fd4c35af 100644 --- a/src/zui/ZUIEditor/index.tsx +++ b/src/zui/ZUIEditor/index.tsx @@ -151,7 +151,7 @@ const ZUIEditor: FC = ({ }))} enableVariable={!!enableVariable} /> - + {enableImage && } diff --git a/src/zui/l10n/messageIds.ts b/src/zui/l10n/messageIds.ts index 7e34f503e..eac102738 100644 --- a/src/zui/l10n/messageIds.ts +++ b/src/zui/l10n/messageIds.ts @@ -140,7 +140,12 @@ export default makeMessages('zui', { textPlaceholder: m('Add link text here'), }, }, - placeholder: m('Type / to insert block or just type some text'), + placeholder: { + label: m<{ link: ReactElement }>( + 'Type / or {link} to insert block, or just type some text' + ), + link: m('click here'), + }, variables: { firstName: m('First Name'), fullName: m('Full Name'), From 0aabdfc965b514a454f166b36facf7991792faa1 Mon Sep 17 00:00:00 2001 From: Richard Olsson Date: Sat, 18 Jan 2025 19:11:24 +0100 Subject: [PATCH 5/5] Hide block menu when placeholder is visible --- src/zui/ZUIEditor/EditorOverlays/index.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/zui/ZUIEditor/EditorOverlays/index.tsx b/src/zui/ZUIEditor/EditorOverlays/index.tsx index 55d4055ad..883b92ef0 100644 --- a/src/zui/ZUIEditor/EditorOverlays/index.tsx +++ b/src/zui/ZUIEditor/EditorOverlays/index.tsx @@ -5,6 +5,7 @@ import { usePositioner, } from '@remirror/react'; import { FC, useCallback, useEffect, useState } from 'react'; +import { ProsemirrorNode } from '@remirror/pm/suggest'; import { Box } from '@mui/material'; import BlockToolbar from './BlockToolbar'; @@ -18,6 +19,7 @@ export type BlockDividerData = { }; type BlockData = { + node: ProsemirrorNode; rect: DOMRect; type: string; }; @@ -54,6 +56,7 @@ const EditorOverlays: FC = ({ blocks, enableVariable }) => { const x = nodeRect.x - editorRect.x; const y = nodeRect.y - editorRect.y; setCurrentBlock({ + node, rect: { ...nodeRect.toJSON(), left: x, @@ -129,7 +132,11 @@ const EditorOverlays: FC = ({ blocks, enableVariable }) => { } }); - const showBlockToolbar = !showBlockMenu && !!currentBlock && !typing; + const isEmptyParagraph = + currentBlock?.type == 'paragraph' && currentBlock?.node.textContent == ''; + + const showBlockToolbar = + !showBlockMenu && !!currentBlock && !typing && !isEmptyParagraph; const showBlockInsert = !showBlockMenu && !typing;