Skip to content

Commit

Permalink
Reduce selection toolbar rerenders (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
12joan authored Dec 20, 2023
1 parent 35cb9a4 commit 5ae2925
Show file tree
Hide file tree
Showing 6 changed files with 419 additions and 389 deletions.
3 changes: 0 additions & 3 deletions client/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
setSelection,
useSaveSelection,
} from '~/lib/editor/restoreSelection';
import { SelectionToolbar } from '~/lib/editor/SelectionToolbar';
import { SlatePlaywrightEffects } from '~/lib/editor/slate-playwright';
import { useInitialValue } from '~/lib/editor/useInitialValue';
import { useNavigateAwayOnDelete } from '~/lib/editor/useNavigateAwayOnDelete';
Expand Down Expand Up @@ -209,8 +208,6 @@ export const Editor = ({ clientId, initialDocument }: EditorProps) => {
/>

<SlatePlaywrightEffects />

{!isReadOnly && <SelectionToolbar />}
</Plate>
),
[plugins, isReadOnly, fontSize, lockedProps]
Expand Down
53 changes: 0 additions & 53 deletions client/lib/editor/SelectionToolbar.tsx

This file was deleted.

2 changes: 2 additions & 0 deletions client/lib/editor/plugins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import { softBreakOptions } from '~/lib/editor/softBreak';
import { createSplitInsertedDataIntoParagraphsPlugin } from '~/lib/editor/splitInsertedDataIntoParagraphs';
import { tabbableOptions } from '~/lib/editor/tabbable';
import { groupedClassNames } from '../groupedClassNames';
import { createSelectionToolbarPlugin } from './selectionToolbar';

const makeElementComponent =
(Component: ElementType, className?: string) =>
Expand Down Expand Up @@ -167,6 +168,7 @@ export const usePlugins = () => {
createTrailingBlockPlugin(),
createAutoformatPlugin(autoformatOptions),
createSplitInsertedDataIntoParagraphsPlugin(),
createSelectionToolbarPlugin(),
],
[]
);
Expand Down
79 changes: 79 additions & 0 deletions client/lib/editor/selectionToolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { MouseEvent } from 'react';
import {
createPluginFactory,
isRangeInSameBlock,
isSelectionExpanded,
useEditorReadOnly,
useEditorState,
} from '@udecode/plate';
import { useSlateSelector } from 'slate-react';
import { FloatingToolbar, FloatingToolbarItem } from './FloatingToolbar';
import {
formattingButtonClassNames,
useInlineFormattingButtons,
} from './FormattingToolbar';

const SelectionToolbar = () => {
const open = useSlateSelector(
(editor) =>
isSelectionExpanded(editor as any) &&
(isRangeInSameBlock(editor as any) ?? false),
/**
* If open is true, we want to rerender every time the selection changes so
* that we keep the toolbar position up to date. If open is false, we only
* want to rerender when it becomes true.
*/
(prevOpen, newOpen) => !prevOpen && !newOpen
);

const readOnly = useEditorReadOnly();
if (readOnly) return null;

return (
<FloatingToolbar
open={open}
items={open && <SelectionToolbarInner />}
tippyProps={{
getReferenceClientRect: () => {
const selection = window.getSelection()!;
const range = selection.getRangeAt(0);
return range.getBoundingClientRect();
},
}}
containerProps={
{
'data-testid': 'selection-toolbar',
} as any
}
/>
);
};

const SelectionToolbarInner = () => {
const editor = useEditorState();

const formattingButtons = useInlineFormattingButtons(editor).filter(
({ disabled }) => !disabled
);

return (
<>
{formattingButtons.map(({ label, icon, active, onClick }) => (
<FloatingToolbarItem
key={label}
icon={icon}
label={label}
className={formattingButtonClassNames}
data-active={active}
onClick={onClick}
onMouseDown={(event: MouseEvent) => event.preventDefault()}
/>
))}
</>
);
};

export const createSelectionToolbarPlugin = createPluginFactory({
key: 'selectionToolbar',
renderAfterEditable: SelectionToolbar,
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@rails/actioncable": "^7.1.2",
"@tippyjs/react": "^4.2.6",
"@types/js-cookie": "^3.0.6",
"@udecode/plate": "^26.0.6",
"@udecode/plate": "^27.0.3",
"axios": "^1.6.2",
"comlink": "^4.4.1",
"compressorjs": "^1.2.1",
Expand Down Expand Up @@ -84,7 +84,7 @@
"tailwindcss": "^3.3.6",
"typescript": "^5.3.3",
"typescript-language-server": "^3.3.2",
"vite": "^5.0.10",
"vite": "^5.0.0",
"vite-plugin-ruby": "^5.0.0"
},
"packageManager": "yarn@4.0.2",
Expand Down
Loading

0 comments on commit 5ae2925

Please sign in to comment.