Skip to content

Commit d236b2a

Browse files
mr-winterUberMouse
authored andcommitted
feat(routing): forwards refs for Link component
Moving preventDefault down to just before the navigation event In the onClick event Radix is checking whether the default event was prevented and bails out of doing its things. Since this should just be for preventing the browser from following the link's url, it should be fine to run it just before the navigate call.
1 parent be1b7c9 commit d236b2a

File tree

2 files changed

+501
-482
lines changed

2 files changed

+501
-482
lines changed

src/routing/Link.tsx

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { forwardRef } from "react";
22

33
import { AnyRoute, Route, RouteArguments } from "./createRoute";
44
import { useHref } from "./useHref";
@@ -38,25 +38,20 @@ export type LinkProps<
3838
} & RouteArguments<TRouteParams, TRouteQuery, TRouteMeta> &
3939
Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "onClick">;
4040

41-
/**
42-
* @public
43-
*
44-
* Renders an anchor tag pointing at the provided Route
45-
*
46-
* The query/params/meta props are conditionally required based on the
47-
* route passed as the To parameter
48-
*/
49-
export function Link<TRoute extends AnyRoute>({
50-
to,
51-
children,
52-
testId,
53-
preloadOnHoverMs,
54-
preloadOnInteraction,
55-
onMouseDown: _onMouseDown,
56-
onMouseEnter: _onMouseEnter,
57-
onMouseLeave: _onMouseLeave,
58-
...rest
59-
}: LinkProps<TRoute>) {
41+
function LinkInner<TRoute extends AnyRoute>(
42+
{
43+
to,
44+
children,
45+
testId,
46+
preloadOnHoverMs,
47+
preloadOnInteraction,
48+
onMouseDown: _onMouseDown,
49+
onMouseEnter: _onMouseEnter,
50+
onMouseLeave: _onMouseLeave,
51+
...rest
52+
}: LinkProps<TRoute>,
53+
ref: React.ForwardedRef<HTMLAnchorElement>
54+
) {
6055
// @ts-ignore, these fields _might_ exist, so typechecking doesn't believe they exist
6156
// and everything that consumes params/query already checks for undefined
6257
const { params, query, meta, ...props } = rest;
@@ -95,13 +90,13 @@ export function Link<TRoute extends AnyRoute>({
9590
return (
9691
<a
9792
{...props}
93+
ref={ref}
9894
href={href}
9995
data-testid={testId}
10096
onMouseDown={onMouseDown ?? _onMouseDown}
10197
onMouseEnter={onMouseEnter ?? _onMouseEnter}
10298
onMouseLeave={onMouseLeave ?? _onMouseLeave}
10399
onClick={(e) => {
104-
e.preventDefault();
105100
if (props.onClick?.(e) === false) {
106101
return;
107102
}
@@ -112,10 +107,23 @@ export function Link<TRoute extends AnyRoute>({
112107
return;
113108
}
114109

110+
e.preventDefault();
115111
to.navigate({ params, query, meta });
116112
}}
117113
>
118114
{children}
119115
</a>
120116
);
121117
}
118+
119+
/**
120+
* @public
121+
*
122+
* Renders an anchor tag pointing at the provided Route
123+
*
124+
* The query/params/meta props are conditionally required based on the
125+
* route passed as the To parameter
126+
*/
127+
export const Link = forwardRef(LinkInner) as <TRoute extends AnyRoute>(
128+
props: LinkProps<TRoute> & { ref?: React.ForwardedRef<HTMLAnchorElement> }
129+
) => ReturnType<typeof LinkInner>;

0 commit comments

Comments
 (0)