diff --git a/.dumi/theme/common/Link.tsx b/.dumi/theme/common/Link.tsx index bccbbc1547..44ae98b722 100644 --- a/.dumi/theme/common/Link.tsx +++ b/.dumi/theme/common/Link.tsx @@ -1,6 +1,6 @@ -import type { MouseEventHandler } from 'react'; -import React from 'react'; -import { Link as DumiLink } from 'dumi'; +import type { MouseEvent, MouseEventHandler } from 'react'; +import React, { useMemo, forwardRef } from 'react'; +import { Link as DumiLink, useLocation, useAppData, useNavigate } from 'dumi'; export interface LinkProps { to: string | { pathname?: string; search?: string; hash?: string }; @@ -11,6 +11,46 @@ export interface LinkProps { children?: React.ReactNode; } -const Link: React.FC = (props) => ; +const Link = forwardRef>( + ({ component, children, to, ...rest }, ref) => { + const { pathname } = useLocation(); + const { preloadRoute } = useAppData(); + const navigate = useNavigate(); + const href = useMemo(() => { + if (typeof to === 'object') { + return `${to.pathname || pathname}${to.search || ''}${to.hash || ''}`; + } + return to; + }, [to]); + const onClick = (e: MouseEvent) => { + rest.onClick?.(e); + if (!href?.startsWith('http')) { + // Should support open in new tab + if (!e.metaKey && !e.ctrlKey && !e.shiftKey) { + e.preventDefault(); + navigate(href); + } + } + }; + if (component) { + return React.createElement( + component, + { + ...rest, + ref, + href, + onClick, + onMouseEnter: () => preloadRoute?.(href), + }, + children, + ); + } + return ( + + {children} + + ); + }, +); export default Link;