perf: Don't render SuggestionMenu contents until active
This commit is contained in:
@@ -79,6 +79,7 @@ function SuggestionsMenu<T extends MenuItem>(props: Props<T>) {
|
||||
const { view, commands } = useEditor();
|
||||
const { showToast: onShowToast } = useToasts();
|
||||
const dictionary = useDictionary();
|
||||
const hasActivated = React.useRef(false);
|
||||
const menuRef = React.useRef<HTMLDivElement>(null);
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
const [position, setPosition] = React.useState<Position>(defaultPosition);
|
||||
@@ -87,6 +88,12 @@ function SuggestionsMenu<T extends MenuItem>(props: Props<T>) {
|
||||
>();
|
||||
const [selectedIndex, setSelectedIndex] = React.useState(0);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (props.isActive) {
|
||||
hasActivated.current = true;
|
||||
}
|
||||
}, [props.isActive]);
|
||||
|
||||
const calculatePosition = React.useCallback(
|
||||
(props: Props) => {
|
||||
if (!props.isActive) {
|
||||
@@ -534,73 +541,77 @@ function SuggestionsMenu<T extends MenuItem>(props: Props<T>) {
|
||||
return (
|
||||
<Portal>
|
||||
<Wrapper active={isActive} ref={menuRef} hiddenScrollbars {...position}>
|
||||
{insertItem ? (
|
||||
<LinkInputWrapper>
|
||||
<LinkInput
|
||||
type="text"
|
||||
placeholder={
|
||||
insertItem.title
|
||||
? dictionary.pasteLinkWithTitle(insertItem.title)
|
||||
: dictionary.pasteLink
|
||||
}
|
||||
onKeyDown={handleLinkInputKeydown}
|
||||
onPaste={handleLinkInputPaste}
|
||||
autoFocus
|
||||
/>
|
||||
</LinkInputWrapper>
|
||||
) : (
|
||||
<List>
|
||||
{items.map((item, index) => {
|
||||
if (item.name === "separator") {
|
||||
return (
|
||||
<ListItem key={index}>
|
||||
<hr />
|
||||
{(isActive || hasActivated.current) && (
|
||||
<>
|
||||
{insertItem ? (
|
||||
<LinkInputWrapper>
|
||||
<LinkInput
|
||||
type="text"
|
||||
placeholder={
|
||||
insertItem.title
|
||||
? dictionary.pasteLinkWithTitle(insertItem.title)
|
||||
: dictionary.pasteLink
|
||||
}
|
||||
onKeyDown={handleLinkInputKeydown}
|
||||
onPaste={handleLinkInputPaste}
|
||||
autoFocus
|
||||
/>
|
||||
</LinkInputWrapper>
|
||||
) : (
|
||||
<List>
|
||||
{items.map((item, index) => {
|
||||
if (item.name === "separator") {
|
||||
return (
|
||||
<ListItem key={index}>
|
||||
<hr />
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
if (!item.title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handlePointer = () => {
|
||||
if (selectedIndex !== index) {
|
||||
setSelectedIndex(index);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={index}
|
||||
onPointerMove={handlePointer}
|
||||
onPointerDown={handlePointer}
|
||||
>
|
||||
{props.renderMenuItem(item as any, index, {
|
||||
selected: index === selectedIndex,
|
||||
onClick: () => handleClickItem(item),
|
||||
})}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
{items.length === 0 && (
|
||||
<ListItem>
|
||||
<Empty>{dictionary.noResults}</Empty>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
if (!item.title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handlePointer = () => {
|
||||
if (selectedIndex !== index) {
|
||||
setSelectedIndex(index);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={index}
|
||||
onPointerMove={handlePointer}
|
||||
onPointerDown={handlePointer}
|
||||
>
|
||||
{props.renderMenuItem(item as any, index, {
|
||||
selected: index === selectedIndex,
|
||||
onClick: () => handleClickItem(item),
|
||||
})}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
{items.length === 0 && (
|
||||
<ListItem>
|
||||
<Empty>{dictionary.noResults}</Empty>
|
||||
</ListItem>
|
||||
)}
|
||||
</List>
|
||||
)}
|
||||
</List>
|
||||
)}
|
||||
{uploadFile && (
|
||||
<VisuallyHidden>
|
||||
<label>
|
||||
<Trans>Import document</Trans>
|
||||
<input
|
||||
type="file"
|
||||
ref={inputRef}
|
||||
onChange={handleFilesPicked}
|
||||
multiple
|
||||
/>
|
||||
</label>
|
||||
</VisuallyHidden>
|
||||
{uploadFile && (
|
||||
<VisuallyHidden>
|
||||
<label>
|
||||
<Trans>Import document</Trans>
|
||||
<input
|
||||
type="file"
|
||||
ref={inputRef}
|
||||
onChange={handleFilesPicked}
|
||||
multiple
|
||||
/>
|
||||
</label>
|
||||
</VisuallyHidden>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Wrapper>
|
||||
</Portal>
|
||||
|
||||
Reference in New Issue
Block a user