Skip to content

Commit

Permalink
Merge pull request #2480 from zetkin/undocumented/zui-editor-overlays…
Browse files Browse the repository at this point in the history
…-fixes

Improvements to `ZUIEditor` overlays
  • Loading branch information
ziggabyte authored Jan 21, 2025
2 parents 21b0d81 + 0aabdfc commit ef8c8f0
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 31 deletions.
9 changes: 4 additions & 5 deletions src/zui/ZUIEditor/EditorOverlays/BlockInsert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ type BlockInsertProps = {
};

const BlockInsert: FC<BlockInsertProps> = ({ blockDividers, mouseY }) => {
const { insertParagraph, focus } = useCommands();
const { insertEmptyParagraph, focus } = useCommands();

return (
<Box position="relative">
{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 (
<Box
key={index}
Expand All @@ -44,9 +44,8 @@ const BlockInsert: FC<BlockInsertProps> = ({ blockDividers, mouseY }) => {
>
<Paper>
<IconButton
disabled={!insertParagraph.enabled(' ', { selection: pos })}
onClick={() => {
insertParagraph(' ', { selection: pos });
insertEmptyParagraph(pos);
focus(pos);
}}
>
Expand Down
51 changes: 35 additions & 16 deletions src/zui/ZUIEditor/EditorOverlays/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -18,6 +19,7 @@ export type BlockDividerData = {
};

type BlockData = {
node: ProsemirrorNode;
rect: DOMRect;
type: string;
};
Expand Down Expand Up @@ -63,6 +65,7 @@ const EditorOverlays: FC<Props> = ({
const x = nodeRect.x - editorRect.x;
const y = nodeRect.y - editorRect.y;
setCurrentBlock({
node,
rect: {
...nodeRect.toJSON(),
left: x,
Expand Down Expand Up @@ -114,22 +117,35 @@ const EditorOverlays: FC<Props> = ({
const blockDividers: BlockDividerData[] = [
{
pos: 0,
y: 0,
y: 8,
},
...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 isEmptyParagraph =
currentBlock?.type == 'paragraph' && currentBlock?.node.textContent == '';

const showBlockToolbar = !showBlockMenu && !!currentBlock && !typing;
const showBlockToolbar =
!showBlockMenu && !!currentBlock && !typing && !isEmptyParagraph;

const showBlockInsert = !showBlockMenu && !typing;

Expand All @@ -141,12 +157,15 @@ const EditorOverlays: FC<Props> = ({
<Box position="relative">
<Box
border={1}
height={currentBlock?.rect.height}
left={currentBlock?.rect.left}
height={currentBlock?.rect.height + 16}
left={currentBlock?.rect.left - 8}
position="absolute"
sx={{ pointerEvents: 'none' }}
top={currentBlock?.rect.top}
width={currentBlock?.rect.width}
sx={{
opacity: 0.5,
pointerEvents: 'none',
}}
top={currentBlock?.rect.top - 8}
width={currentBlock?.rect.width + 16}
/>
</Box>
)}
Expand Down
39 changes: 31 additions & 8 deletions src/zui/ZUIEditor/EmptyBlockPlaceholder.tsx
Original file line number Diff line number Diff line change
@@ -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<Props> = ({ placeholder }) => {
const EmptyBlockPlaceholder: FC = () => {
const positioner = usePositioner('emptyBlockStart');
const { focus, insertText } = useCommands();

return (
<Box ref={positioner.ref} position="relative">
{positioner.active && (
<Typography
sx={{
'&:hover': {
opacity: 1,
},
left: positioner.x,
opacity: 0.5,
pointerEvents: 'none',
position: 'absolute',
top: positioner.y,
transition: 'opacity 0.5s',
}}
>
{placeholder}
<Msg
id={messageIds.editor.placeholder.label}
values={{
link: (
<Link
onClick={() => {
const pos = positioner.data.pos;
if (pos) {
insertText('/', { from: positioner.data.pos });
focus(pos + 2);
}
}}
sx={{
cursor: 'pointer',
}}
>
<Msg id={messageIds.editor.placeholder.link} />
</Link>
),
}}
/>
</Typography>
)}
</Box>
Expand Down
12 changes: 12 additions & 0 deletions src/zui/ZUIEditor/extensions/BlockMenuExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Handler,
PlainExtension,
} from 'remirror';
import { ParagraphExtension } from 'remirror/extensions';

type BlockMenuOptions = {
blockFactories: Record<string, CommandFunction>;
Expand Down Expand Up @@ -53,6 +54,17 @@ class BlockMenuExtension extends PlainExtension<BlockMenuOptions> {
};
}

/* 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';
}
Expand Down
2 changes: 1 addition & 1 deletion src/zui/ZUIEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ const ZUIEditor: FC<Props> = ({
enableLink={!!enableLink}
enableVariable={!!enableVariable}
/>
<EmptyBlockPlaceholder placeholder={messages.placeholder()} />
<EmptyBlockPlaceholder />
{enableImage && <ImageExtensionUI orgId={orgId} />}
<ButtonExtensionUI />
<LinkExtensionUI />
Expand Down
7 changes: 6 additions & 1 deletion src/zui/l10n/messageIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,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'),
Expand Down

0 comments on commit ef8c8f0

Please sign in to comment.