Skip to content

Commit 3994de4

Browse files
authored
Merge pull request #11196 from TylerAPfledderer/fix/BaseLink-forward-ref
fix: add forward ref to `BaseLink`
2 parents 0fff786 + 7e5cd81 commit 3994de4

File tree

1 file changed

+120
-112
lines changed

1 file changed

+120
-112
lines changed

src/components/Link.tsx

Lines changed: 120 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react"
22
import {
3-
Box,
3+
forwardRef,
44
Icon,
55
Link as ChakraLink,
66
LinkProps,
@@ -47,125 +47,133 @@ export interface IProps extends IBaseProps, LinkProps {
4747
* - Intl links
4848
* e.g. <Link href="/page-2/" language="de">
4949
*/
50-
export const BaseLink: React.FC<IProps> = ({
51-
to: toProp,
52-
href,
53-
language,
54-
dir = "ltr",
55-
children,
56-
hideArrow = false,
57-
isPartiallyActive = true,
58-
customEventOptions,
59-
activeStyle = null,
60-
...restProps
61-
}) => {
62-
const theme = useTheme()
63-
64-
// TODO: in the next PR we are going to deprecate the `to` prop and just use `href`
65-
// this is to support the ButtonLink component which uses the `to` prop
66-
let to = (toProp ?? href)!
67-
68-
const isDiscordInvite = url.isDiscordInvite(to)
69-
if (isDiscordInvite) to = new URL(DISCORD_PATH, SITE_URL).href
70-
const isExternal = url.isExternal(to)
71-
const isHash = url.isHash(to)
72-
const isStatic = url.isStatic(to)
73-
const isPdf = url.isPdf(to)
74-
75-
const externalLinkEvent: MatomoEventOptions = {
76-
eventCategory: `External link`,
77-
eventAction: `Clicked`,
78-
eventName: to,
79-
}
80-
81-
const hashLinkEvent: MatomoEventOptions = {
82-
eventCategory: `Hash link`,
83-
eventAction: `Clicked`,
84-
eventName: to,
85-
}
86-
87-
const commonProps = {
88-
dir,
89-
...restProps,
90-
}
91-
92-
// Must use Chakra's native <Link> for anchor links
93-
// Otherwise the Gatsby <Link> functionality will navigate to homepage
94-
// See https://github.com/gatsbyjs/gatsby/issues/21909
95-
if (isHash) {
50+
export const BaseLink = forwardRef<IProps, "a">(
51+
(
52+
{
53+
to: toProp,
54+
href,
55+
language,
56+
dir = "ltr",
57+
children,
58+
hideArrow = false,
59+
isPartiallyActive = true,
60+
customEventOptions,
61+
activeStyle = null,
62+
...restProps
63+
},
64+
ref
65+
) => {
66+
const theme = useTheme()
67+
68+
// TODO: in the next PR we are going to deprecate the `to` prop and just use `href`
69+
// this is to support the ButtonLink component which uses the `to` prop
70+
let to = (toProp ?? href)!
71+
72+
const isDiscordInvite = url.isDiscordInvite(to)
73+
if (isDiscordInvite) to = new URL(DISCORD_PATH, SITE_URL).href
74+
const isExternal = url.isExternal(to)
75+
const isHash = url.isHash(to)
76+
const isStatic = url.isStatic(to)
77+
const isPdf = url.isPdf(to)
78+
79+
const externalLinkEvent: MatomoEventOptions = {
80+
eventCategory: `External link`,
81+
eventAction: `Clicked`,
82+
eventName: to,
83+
}
84+
85+
const hashLinkEvent: MatomoEventOptions = {
86+
eventCategory: `Hash link`,
87+
eventAction: `Clicked`,
88+
eventName: to,
89+
}
90+
91+
const commonProps: LinkProps & { ref: React.ForwardedRef<any> } = {
92+
ref,
93+
dir,
94+
...restProps,
95+
}
96+
97+
// Must use Chakra's native <Link> for anchor links
98+
// Otherwise the Gatsby <Link> functionality will navigate to homepage
99+
// See https://github.com/gatsbyjs/gatsby/issues/21909
100+
if (isHash) {
101+
return (
102+
<ChakraLink
103+
href={to}
104+
onClick={(e) => {
105+
// only track events on external links and hash links
106+
if (!isHash) {
107+
return
108+
}
109+
110+
e.stopPropagation()
111+
trackCustomEvent(
112+
customEventOptions ? customEventOptions : hashLinkEvent
113+
)
114+
}}
115+
{...commonProps}
116+
>
117+
{children}
118+
</ChakraLink>
119+
)
120+
}
121+
122+
// Download link for internally hosted PDF's & static files (ex: whitepaper)
123+
// Opens in separate window.
124+
if (isExternal || isPdf || isStatic) {
125+
return (
126+
<ChakraLink
127+
href={to}
128+
isExternal
129+
onClick={(e) => {
130+
// only track events on external links and hash links
131+
if (!isExternal) {
132+
return
133+
}
134+
135+
e.stopPropagation()
136+
trackCustomEvent(
137+
customEventOptions ? customEventOptions : externalLinkEvent
138+
)
139+
}}
140+
{...commonProps}
141+
>
142+
<>
143+
{children}
144+
<VisuallyHidden>(opens in a new tab)</VisuallyHidden>
145+
{!hideArrow && (
146+
<Icon
147+
as={RxExternalLink}
148+
boxSize="6"
149+
p="1"
150+
verticalAlign="middle"
151+
me="-1"
152+
/>
153+
)}
154+
</>
155+
</ChakraLink>
156+
)
157+
}
158+
159+
// Use `gatsby-theme-i18n` Link (which prepends lang path)
96160
return (
97161
<ChakraLink
98-
href={to}
99-
onClick={(e) => {
100-
// only track events on external links and hash links
101-
if (!isHash) {
102-
return
103-
}
104-
105-
e.stopPropagation()
106-
trackCustomEvent(
107-
customEventOptions ? customEventOptions : hashLinkEvent
108-
)
109-
}}
162+
as={IntlLink}
163+
to={to}
164+
language={language}
165+
partiallyActive={isPartiallyActive}
166+
activeStyle={
167+
activeStyle ? activeStyle : { color: theme.colors.primary }
168+
}
169+
whiteSpace={"normal"}
110170
{...commonProps}
111171
>
112172
{children}
113173
</ChakraLink>
114174
)
115175
}
116-
117-
// Download link for internally hosted PDF's & static files (ex: whitepaper)
118-
// Opens in separate window.
119-
if (isExternal || isPdf || isStatic) {
120-
return (
121-
<ChakraLink
122-
href={to}
123-
isExternal
124-
onClick={(e) => {
125-
// only track events on external links and hash links
126-
if (!isExternal) {
127-
return
128-
}
129-
130-
e.stopPropagation()
131-
trackCustomEvent(
132-
customEventOptions ? customEventOptions : externalLinkEvent
133-
)
134-
}}
135-
{...commonProps}
136-
>
137-
<>
138-
{children}
139-
<VisuallyHidden>(opens in a new tab)</VisuallyHidden>
140-
{!hideArrow && (
141-
<Icon
142-
as={RxExternalLink}
143-
boxSize="6"
144-
p="1"
145-
verticalAlign="middle"
146-
me="-1"
147-
/>
148-
)}
149-
</>
150-
</ChakraLink>
151-
)
152-
}
153-
154-
// Use `gatsby-theme-i18n` Link (which prepends lang path)
155-
return (
156-
<ChakraLink
157-
to={to}
158-
as={IntlLink}
159-
language={language}
160-
partiallyActive={isPartiallyActive}
161-
activeStyle={activeStyle ? activeStyle : { color: theme.colors.primary }}
162-
whiteSpace={"normal"}
163-
{...commonProps}
164-
>
165-
{children}
166-
</ChakraLink>
167-
)
168-
}
176+
)
169177

170178
export function navigate(
171179
to: string,

0 commit comments

Comments
 (0)