Skip to content

Commit e2b9d67

Browse files
committed
Add Anchor component for internal and external links
1 parent 5f164f3 commit e2b9d67

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { ForwardedRef, forwardRef, ReactElement } from "react"
2+
import NextLink from "next/link"
3+
import type { LinkProps as NextLinkProps } from "next/link"
4+
5+
// eslint-disable-next-line @typescript-eslint/no-namespace
6+
export declare namespace AnchorProps {
7+
interface IntrinsicAnchorProps
8+
extends React.DetailedHTMLProps<
9+
React.AnchorHTMLAttributes<HTMLAnchorElement>,
10+
HTMLAnchorElement
11+
> {
12+
href: `#${string}` | `http${string}`
13+
}
14+
15+
interface InternalAnchorProps extends NextLinkProps {}
16+
}
17+
18+
export type AnchorProps =
19+
| AnchorProps.IntrinsicAnchorProps
20+
| AnchorProps.InternalAnchorProps
21+
22+
export const Anchor = forwardRef(function Anchor(
23+
props: AnchorProps,
24+
ref: ForwardedRef<HTMLAnchorElement>,
25+
) {
26+
return isInternal(props) ? (
27+
<NextLink {...props} ref={ref} />
28+
) : (
29+
<a ref={ref} rel="noopener noreferrer" target="_blank" {...props} />
30+
)
31+
}) as (props: AnchorProps) => ReactElement
32+
33+
function isInternal(
34+
props: AnchorProps,
35+
): props is AnchorProps.InternalAnchorProps {
36+
return (
37+
typeof props.href === "object" ||
38+
(typeof props.href === "string" &&
39+
!props.href.startsWith("http") &&
40+
!props.href.startsWith("#"))
41+
)
42+
}

0 commit comments

Comments
 (0)