mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-31 23:40:39 +02:00
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:
parent
1cd4757828
commit
916e4f1a26
3 changed files with 60 additions and 12 deletions
|
@ -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);
|
||||
|
|
|
@ -21,6 +21,7 @@ import Readme from "../README.md"
|
|||
### Other tests
|
||||
|
||||
- [Code block tests](/tests/pages/code-block-tests)
|
||||
- [Link tests](/tests/pages/link-tests)
|
||||
- [Error boundary tests](/tests/pages/error-boundary-tests)
|
||||
- [Hydration tests](/tests/pages/hydration-tests)
|
||||
- [Asset linking tests](/tests/pages/markdown-tests)
|
||||
|
|
30
website/_dogfooding/_pages tests/link-tests.tsx
Normal file
30
website/_dogfooding/_pages tests/link-tests.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
import Link from '@docusaurus/Link';
|
||||
|
||||
export default function LinkTest(): JSX.Element {
|
||||
const anchorRef = React.useRef<HTMLAnchorElement>(null);
|
||||
return (
|
||||
<Layout>
|
||||
<main className="container margin-vert--xl">
|
||||
<Link ref={anchorRef} to="/">
|
||||
A little link
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
anchorRef.current!.style.backgroundColor = 'red';
|
||||
}}>
|
||||
Change the link
|
||||
</button>
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue