diff --git a/app/components/Sidebar/components/CollectionLink.tsx b/app/components/Sidebar/components/CollectionLink.tsx index 7890351db..acfe7e321 100644 --- a/app/components/Sidebar/components/CollectionLink.tsx +++ b/app/components/Sidebar/components/CollectionLink.tsx @@ -118,7 +118,7 @@ const CollectionLink: React.FC = ({ setIsEditing(isEditing); }, []); - const handleMouseEnter = React.useCallback(() => { + const handlePrefetch = React.useCallback(() => { void collection.fetchDocuments(); }, [collection]); @@ -138,7 +138,7 @@ const CollectionLink: React.FC = ({ }} expanded={expanded} onDisclosureClick={onDisclosureClick} - onMouseEnter={handleMouseEnter} + onClickIntent={handlePrefetch} icon={ } diff --git a/app/components/Sidebar/components/DocumentLink.tsx b/app/components/Sidebar/components/DocumentLink.tsx index 2374d0dae..937332382 100644 --- a/app/components/Sidebar/components/DocumentLink.tsx +++ b/app/components/Sidebar/components/DocumentLink.tsx @@ -114,7 +114,7 @@ function InnerDocumentLink( [expanded] ); - const handleMouseEnter = React.useCallback(() => { + const handlePrefetch = React.useCallback(() => { prefetchDocument?.(node.id); }, [prefetchDocument, node]); @@ -317,7 +317,7 @@ function InnerDocumentLink( & { to?: LocationDescriptor; innerRef?: (ref: HTMLElement | null | undefined) => void; onClick?: React.MouseEventHandler; - onMouseEnter?: React.MouseEventHandler; + /* Callback when we expect the user to click on the link. Used for prefetching data. */ + onClickIntent?: () => void; onDisclosureClick?: React.MouseEventHandler; icon?: React.ReactNode; label?: React.ReactNode; @@ -44,7 +46,7 @@ function SidebarLink( { icon, onClick, - onMouseEnter, + onClickIntent, to, label, active, @@ -63,6 +65,7 @@ function SidebarLink( }: Props, ref: React.RefObject ) { + const timer = React.useRef(); const theme = useTheme(); const style = React.useMemo( () => ({ @@ -81,6 +84,28 @@ function SidebarLink( [theme.text, theme.sidebarActiveBackground, style] ); + const handleMouseEnter = React.useCallback(() => { + if (timer.current) { + clearTimeout(timer.current); + } + + if (onClickIntent) { + timer.current = window.setTimeout(onClickIntent, 100); + } + }, [onClickIntent]); + + const handleMouseLeave = React.useCallback(() => { + if (timer.current) { + clearTimeout(timer.current); + } + }, []); + + useUnmount(() => { + if (timer.current) { + clearTimeout(timer.current); + } + }); + return ( <>