fix(core): forward ref to Link's anchor element (#6644)

* feat(core): allow to pass ref into the Link component

* refactor

* add dogfood

Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Konstantin Tarkus 2022-02-11 07:34:13 +03:00 committed by GitHub
parent 1cd4757828
commit 916e4f1a26
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 12 deletions

View file

@ -5,7 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {useEffect, useRef, type ComponentType} from 'react';
import React, {
useEffect,
useImperativeHandle,
useRef,
type ComponentType,
} from 'react';
import {NavLink, Link as RRLink} from 'react-router-dom';
import useDocusaurusContext from './useDocusaurusContext';
@ -31,21 +36,30 @@ declare global {
// like "introduction" to "/baseUrl/introduction" => bad behavior to fix
const shouldAddBaseUrlAutomatically = (to: string) => to.startsWith('/');
function Link({
isNavLink,
to,
href,
activeClassName,
isActive,
'data-noBrokenLinkCheck': noBrokenLinkCheck,
autoAddBaseUrl = true,
...props
}: LinkProps): JSX.Element {
function Link(
{
isNavLink,
to,
href,
activeClassName,
isActive,
'data-noBrokenLinkCheck': noBrokenLinkCheck,
autoAddBaseUrl = true,
...props
}: LinkProps,
forwardedRef: React.ForwardedRef<HTMLAnchorElement>,
): JSX.Element {
const {
siteConfig: {trailingSlash, baseUrl},
} = useDocusaurusContext();
const {withBaseUrl} = useBaseUrlUtils();
const linksCollector = useLinksCollector();
const innerRef = useRef<HTMLAnchorElement | null>(null);
useImperativeHandle(
forwardedRef,
() => innerRef.current as HTMLAnchorElement,
);
// IMPORTANT: using to or href should not change anything
// For example, MDX links will ALWAYS give us the href props
@ -111,6 +125,8 @@ function Link({
};
const handleRef = (ref: HTMLAnchorElement | null) => {
innerRef.current = ref;
if (IOSupported && ref && isInternal) {
// If IO supported and element reference found, set up Observer.
handleIntersection(ref, () => {
@ -154,6 +170,7 @@ function Link({
return isRegularHtmlLink ? (
// eslint-disable-next-line jsx-a11y/anchor-has-content
<a
ref={innerRef}
href={targetLink}
{...(targetLinkUnprefixed &&
!isInternal && {target: '_blank', rel: 'noopener noreferrer'})}
@ -172,4 +189,4 @@ function Link({
);
}
export default Link;
export default React.forwardRef(Link);