chore: Refactoring some editor controls (#5023)

* Refactor EmojiMenu

* Refactor CommandMenu to functional component

* Remove more direct props, refactor to useEditor

* Remove hardcoded IDs

* Refactor SelectionToolbar to functional component

* fix: Positioning of suggestion menu on long paragraphs
This commit is contained in:
Tom Moor
2023-03-13 21:05:06 -04:00
committed by GitHub
parent f6ac73a741
commit 4182cbd5d0
12 changed files with 891 additions and 928 deletions

View File

@@ -1,8 +1,11 @@
import FuzzySearch from "fuzzy-search";
import gemojies from "gemoji";
import React from "react";
import CommandMenu, { Props } from "./CommandMenu";
import { useEditor } from "./EditorContext";
import EmojiMenuItem from "./EmojiMenuItem";
import SuggestionsMenu, {
Props as SuggestionsMenuProps,
} from "./SuggestionsMenu";
type Emoji = {
name: string;
@@ -21,19 +24,16 @@ const searcher = new FuzzySearch<{
sort: true,
});
class EmojiMenu extends React.PureComponent<
Omit<
Props<Emoji>,
| "renderMenuItem"
| "items"
| "onLinkToolbarOpen"
| "embeds"
| "onClearSearch"
>
> {
get items(): Emoji[] {
const { search = "" } = this.props;
type Props = Omit<
SuggestionsMenuProps<Emoji>,
"renderMenuItem" | "items" | "onLinkToolbarOpen" | "embeds" | "onClearSearch"
>;
const EmojiMenu = (props: Props) => {
const { search = "" } = props;
const { view } = useEditor();
const items = React.useMemo(() => {
const n = search.toLowerCase();
const result = searcher.search(n).map((item) => {
const description = item.description;
@@ -48,42 +48,37 @@ class EmojiMenu extends React.PureComponent<
});
return result.slice(0, 10);
}
}, [search]);
clearSearch = () => {
const { state, dispatch } = this.props.view;
const clearSearch = React.useCallback(() => {
const { state, dispatch } = view;
// clear search input
dispatch(
state.tr.insertText(
"",
state.selection.$from.pos - (this.props.search ?? "").length - 1,
state.selection.$from.pos - (props.search ?? "").length - 1,
state.selection.to
)
);
};
}, [view, props.search]);
render() {
const containerId = "emoji-menu-container";
return (
<CommandMenu
{...this.props}
id={containerId}
filterable={false}
onClearSearch={this.clearSearch}
renderMenuItem={(item, _index, options) => (
<EmojiMenuItem
onClick={options.onClick}
selected={options.selected}
title={item.description}
emoji={item.emoji}
containerId={containerId}
/>
)}
items={this.items}
/>
);
}
}
return (
<SuggestionsMenu
{...props}
filterable={false}
onClearSearch={clearSearch}
renderMenuItem={(item, _index, options) => (
<EmojiMenuItem
onClick={options.onClick}
selected={options.selected}
title={item.description}
emoji={item.emoji}
/>
)}
items={items}
/>
);
};
export default EmojiMenu;