@@ -23,15 +23,10 @@ import {
2323 useRouteLoaderData as useRouteLoaderDataRR ,
2424 useLocation ,
2525 useNavigation ,
26- useHref ,
2726} from "react-router" ;
2827
29- import type { FetcherWithComponents , LinkProps , NavLinkProps } from "../index" ;
30- import {
31- Link as RouterLink ,
32- NavLink as RouterNavLink ,
33- useFetcher as useFetcherRR ,
34- } from "../index" ;
28+ import type { FetcherWithComponents } from "../index" ;
29+ import { useFetcher as useFetcherRR } from "../index" ;
3530import type { AppData } from "./data" ;
3631import type { RemixContextObject } from "./entry" ;
3732import invariant from "./invariant" ;
@@ -100,15 +95,7 @@ export function useRemixContext(): RemixContextObject {
10095 * - "render": Fetched when the link is rendered
10196 * - "viewport": Fetched when the link is in the viewport
10297 */
103- type PrefetchBehavior = "intent" | "render" | "none" | "viewport" ;
104-
105- export interface RemixLinkProps extends LinkProps {
106- prefetch ?: PrefetchBehavior ;
107- }
108-
109- export interface RemixNavLinkProps extends NavLinkProps {
110- prefetch ?: PrefetchBehavior ;
111- }
98+ export type PrefetchBehavior = "intent" | "render" | "none" | "viewport" ;
11299
113100interface PrefetchHandlers {
114101 onFocus ?: FocusEventHandler ;
@@ -118,10 +105,11 @@ interface PrefetchHandlers {
118105 onTouchStart ?: TouchEventHandler ;
119106}
120107
121- function usePrefetchBehavior < T extends HTMLAnchorElement > (
108+ export function usePrefetchBehavior < T extends HTMLAnchorElement > (
122109 prefetch : PrefetchBehavior ,
123110 theirElementProps : PrefetchHandlers
124- ) : [ boolean , React . RefObject < T > , Required < PrefetchHandlers > ] {
111+ ) : [ boolean , React . RefObject < T > , PrefetchHandlers ] {
112+ let remixContext = React . useContext ( RemixContext ) ;
125113 let [ maybePrefetch , setMaybePrefetch ] = React . useState ( false ) ;
126114 let [ shouldPrefetch , setShouldPrefetch ] = React . useState ( false ) ;
127115 let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } =
@@ -149,19 +137,6 @@ function usePrefetchBehavior<T extends HTMLAnchorElement>(
149137 }
150138 } , [ prefetch ] ) ;
151139
152- let setIntent = ( ) => {
153- if ( prefetch === "intent" ) {
154- setMaybePrefetch ( true ) ;
155- }
156- } ;
157-
158- let cancelIntent = ( ) => {
159- if ( prefetch === "intent" ) {
160- setMaybePrefetch ( false ) ;
161- setShouldPrefetch ( false ) ;
162- }
163- } ;
164-
165140 React . useEffect ( ( ) => {
166141 if ( maybePrefetch ) {
167142 let id = setTimeout ( ( ) => {
@@ -173,6 +148,25 @@ function usePrefetchBehavior<T extends HTMLAnchorElement>(
173148 }
174149 } , [ maybePrefetch ] ) ;
175150
151+ let setIntent = ( ) => {
152+ setMaybePrefetch ( true ) ;
153+ } ;
154+
155+ let cancelIntent = ( ) => {
156+ setMaybePrefetch ( false ) ;
157+ setShouldPrefetch ( false ) ;
158+ } ;
159+
160+ // No prefetching if not using Remix-style SSR
161+ if ( ! remixContext ) {
162+ return [ false , ref , { } ] ;
163+ }
164+
165+ if ( prefetch !== "intent" ) {
166+ return [ shouldPrefetch , ref , { } ] ;
167+ }
168+
169+ // When using prefetch="intent" we need to attach focus/hover listeners
176170 return [
177171 shouldPrefetch ,
178172 ref ,
@@ -186,75 +180,6 @@ function usePrefetchBehavior<T extends HTMLAnchorElement>(
186180 ] ;
187181}
188182
189- const ABSOLUTE_URL_REGEX = / ^ (?: [ a - z ] [ a - z 0 - 9 + . - ] * : | \/ \/ ) / i;
190-
191- /**
192- * A special kind of `<Link>` that knows whether it is "active".
193- *
194- * @see https://remix.run/components/nav-link
195- */
196- let NavLink = React . forwardRef < HTMLAnchorElement , RemixNavLinkProps > (
197- ( { to, prefetch = "none" , ...props } , forwardedRef ) => {
198- let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX . test ( to ) ;
199-
200- let href = useHref ( to ) ;
201- let [ shouldPrefetch , ref , prefetchHandlers ] = usePrefetchBehavior (
202- prefetch ,
203- props
204- ) ;
205-
206- return (
207- < >
208- < RouterNavLink
209- { ...props }
210- { ...prefetchHandlers }
211- ref = { mergeRefs ( forwardedRef , ref ) }
212- to = { to }
213- />
214- { shouldPrefetch && ! isAbsolute ? (
215- < PrefetchPageLinks page = { href } />
216- ) : null }
217- </ >
218- ) ;
219- }
220- ) ;
221- NavLink . displayName = "NavLink" ;
222- export { NavLink } ;
223-
224- /**
225- * This component renders an anchor tag and is the primary way the user will
226- * navigate around your website.
227- *
228- * @see https://remix.run/components/link
229- */
230- let Link = React . forwardRef < HTMLAnchorElement , RemixLinkProps > (
231- ( { to, prefetch = "none" , ...props } , forwardedRef ) => {
232- let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX . test ( to ) ;
233-
234- let href = useHref ( to ) ;
235- let [ shouldPrefetch , ref , prefetchHandlers ] = usePrefetchBehavior (
236- prefetch ,
237- props
238- ) ;
239-
240- return (
241- < >
242- < RouterLink
243- { ...props }
244- { ...prefetchHandlers }
245- ref = { mergeRefs ( forwardedRef , ref ) }
246- to = { to }
247- />
248- { shouldPrefetch && ! isAbsolute ? (
249- < PrefetchPageLinks page = { href } />
250- ) : null }
251- </ >
252- ) ;
253- }
254- ) ;
255- Link . displayName = "Link" ;
256- export { Link } ;
257-
258183export function composeEventHandlers <
259184 EventType extends React . SyntheticEvent | Event
260185> (
@@ -1257,7 +1182,7 @@ export const LiveReload =
12571182 ) ;
12581183 } ;
12591184
1260- function mergeRefs < T = any > (
1185+ export function mergeRefs < T = any > (
12611186 ...refs : Array < React . MutableRefObject < T > | React . LegacyRef < T > >
12621187) : React . RefCallback < T > {
12631188 return ( value ) => {
0 commit comments