Zeta: Forward ref to Link component

This commit is contained in:
SonMooSans
2023-12-18 21:08:23 +08:00
parent a20900081e
commit f39ae40bc1
3 changed files with 64 additions and 42 deletions
+12
View File
@@ -0,0 +1,12 @@
---
'next-docs-zeta': minor
---
**Forward ref to `Link` and `DynamicLink` component**
**Legacy import name `SafeLink` is now removed**
```diff
- import { SafeLink } from "next-docs-zeta/link"
+ import Link from "next-docs-zeta/link"
```
+19 -15
View File
@@ -1,7 +1,7 @@
'use client';
import { useParams } from 'next/navigation';
import { useMemo } from 'react';
import { forwardRef, useMemo } from 'react';
import Link, { type LinkProps } from './link';
export type DynamicLinkProps = LinkProps;
@@ -11,20 +11,24 @@ export type DynamicLinkProps = LinkProps;
*
* It supports dynamic hrefs, which means you can use `/[lang]/my-page` with `dynamicHrefs` enabled
*/
export function DynamicLink({
href = '/',
...props
}: DynamicLinkProps): JSX.Element {
const params = useParams();
const url = useMemo(() => {
return href.replace(/\[.*\]/, (key) => {
const mappedKey = key.slice(1, -1);
const value = mappedKey in params ? params[mappedKey] : 'undefined';
export const DynamicLink = forwardRef<HTMLAnchorElement, DynamicLinkProps>(
({ href, ...props }, ref) => {
const params = useParams();
return typeof value === 'string' ? value : value.join('/');
});
}, [params, href]);
const url = useMemo(() => {
return href?.replace(/\[.*\]/, (key) => {
const mappedKey = key.slice(1, -1);
const value = mappedKey in params ? params[mappedKey] : 'undefined';
return <Link href={url} {...props} />;
}
return typeof value === 'string' ? value : value.join('/');
});
}, [params, href]);
return <Link ref={ref} href={url} {...props} />;
},
);
DynamicLink.displayName = 'DynamicLink';
export default DynamicLink;
+33 -27
View File
@@ -1,5 +1,5 @@
import Original from 'next/link';
import type { AnchorHTMLAttributes } from 'react';
import { forwardRef, type AnchorHTMLAttributes } from 'react';
export type LinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
/**
@@ -13,31 +13,37 @@ export type LinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
/**
* Wraps `next/link` and safe to use in mdx documents
*/
function Link({
href = '/',
external = !(
href.startsWith('/') ||
href.startsWith('#') ||
href.startsWith('.')
),
...props
}: LinkProps): JSX.Element {
if (external) {
return (
<a href={href} rel="noreferrer noopener" target="_blank" {...props}>
{props.children}
</a>
);
}
const Link = forwardRef<HTMLAnchorElement, LinkProps>(
(
{
href = '#',
external = !(
href.startsWith('/') ||
href.startsWith('#') ||
href.startsWith('.')
),
...props
},
ref,
) => {
if (external) {
return (
<a
ref={ref}
href={href}
rel="noreferrer noopener"
target="_blank"
{...props}
>
{props.children}
</a>
);
}
return <Original href={href} {...props} />;
}
return <Original ref={ref} href={href} {...props} />;
},
);
export {
Link as default,
/**
* Legacy exports
*/
Link as SafeLink,
type LinkProps as SafeLinkProps,
};
Link.displayName = 'Link';
export { Link as default };