@tanstack/react-router 1.162.6 → 1.162.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/link.cjs CHANGED
@@ -50,6 +50,7 @@ function useLinkProps(options, forwardedRef) {
50
50
  style,
51
51
  className,
52
52
  onClick,
53
+ onBlur,
53
54
  onFocus,
54
55
  onMouseEnter,
55
56
  onMouseLeave,
@@ -451,38 +452,36 @@ function useLinkProps(options, forwardedRef) {
451
452
  ...style && { style },
452
453
  ...className && { className },
453
454
  ...onClick && { onClick },
455
+ ...onBlur && { onBlur },
454
456
  ...onFocus && { onFocus },
455
457
  ...onMouseEnter && { onMouseEnter },
456
458
  ...onMouseLeave && { onMouseLeave },
457
459
  ...onTouchStart && { onTouchStart }
458
460
  };
459
461
  }
460
- const handleFocus = (_) => {
461
- if (disabled) return;
462
- if (preload) {
463
- doPreload();
464
- }
465
- };
466
- const handleTouchStart = handleFocus;
467
- const handleEnter = (e) => {
468
- if (disabled || !preload) return;
462
+ const enqueueIntentPreload = (e) => {
463
+ if (disabled || preload !== "intent") return;
469
464
  if (!preloadDelay) {
470
465
  doPreload();
471
- } else {
472
- const eventTarget = e.target;
473
- if (timeoutMap.has(eventTarget)) {
474
- return;
475
- }
476
- const id = setTimeout(() => {
477
- timeoutMap.delete(eventTarget);
478
- doPreload();
479
- }, preloadDelay);
480
- timeoutMap.set(eventTarget, id);
466
+ return;
481
467
  }
468
+ const eventTarget = e.currentTarget;
469
+ if (timeoutMap.has(eventTarget)) {
470
+ return;
471
+ }
472
+ const id = setTimeout(() => {
473
+ timeoutMap.delete(eventTarget);
474
+ doPreload();
475
+ }, preloadDelay);
476
+ timeoutMap.set(eventTarget, id);
477
+ };
478
+ const handleTouchStart = (_) => {
479
+ if (disabled || preload !== "intent") return;
480
+ doPreload();
482
481
  };
483
482
  const handleLeave = (e) => {
484
483
  if (disabled || !preload || !preloadDelay) return;
485
- const eventTarget = e.target;
484
+ const eventTarget = e.currentTarget;
486
485
  const id = timeoutMap.get(eventTarget);
487
486
  if (id) {
488
487
  clearTimeout(id);
@@ -496,8 +495,9 @@ function useLinkProps(options, forwardedRef) {
496
495
  href: hrefOption?.href,
497
496
  ref: innerRef,
498
497
  onClick: composeHandlers([onClick, handleClick]),
499
- onFocus: composeHandlers([onFocus, handleFocus]),
500
- onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
498
+ onBlur: composeHandlers([onBlur, handleLeave]),
499
+ onFocus: composeHandlers([onFocus, enqueueIntentPreload]),
500
+ onMouseEnter: composeHandlers([onMouseEnter, enqueueIntentPreload]),
501
501
  onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),
502
502
  onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),
503
503
  disabled: !!disabled,
@@ -1 +1 @@
1
- {"version":3,"file":"link.cjs","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type { ReactNode } from 'react'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\n/**\n * Build anchor-like props for declarative navigation and preloading.\n *\n * Returns stable `href`, event handlers and accessibility props derived from\n * router options and active state. Used internally by `Link` and custom links.\n *\n * Options cover `to`, `params`, `search`, `hash`, `state`, `preload`,\n * `activeProps`, `inactiveProps`, and more.\n *\n * @returns React anchor props suitable for `<a>` or custom components.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useLinkPropsHook\n */\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = string,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n forwardedRef?: React.ForwardedRef<Element>,\n): React.ComponentPropsWithRef<'a'> {\n const router = useRouter()\n const innerRef = useForwardedRef(forwardedRef)\n\n // Determine if we're on the server - used for tree-shaking client-only code\n const _isServer = isServer ?? router.isServer\n\n const {\n // custom props\n activeProps,\n inactiveProps,\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n hashScrollIntoView,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ignoreBlocker,\n // prevent these from being returned\n params: _params,\n search: _search,\n hash: _hash,\n state: _state,\n mask: _mask,\n reloadDocument: _reloadDocument,\n unsafeRelative: _unsafeRelative,\n from: _from,\n _fromLocation,\n ...propsSafeToSpread\n } = options\n\n // ==========================================================================\n // SERVER EARLY RETURN\n // On the server, we return static props without any event handlers,\n // effects, or client-side interactivity.\n //\n // For SSR parity (to avoid hydration errors), we still compute the link's\n // active status on the server, but we avoid creating any router-state\n // subscriptions by reading from `router.state` directly.\n //\n // Note: `location.hash` is not available on the server.\n // ==========================================================================\n if (_isServer) {\n const safeInternal = isSafeInternal(to)\n\n // If `to` is obviously an absolute URL, treat as external and avoid\n // computing the internal location via `buildLocation`.\n if (\n typeof to === 'string' &&\n !safeInternal &&\n // Quick checks to avoid `new URL` in common internal-like cases\n to.indexOf(':') > -1\n ) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: undefined,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n } catch {\n // Not an absolute URL\n }\n }\n\n const next = router.buildLocation({ ...options, from: options.from } as any)\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n const hrefOption = getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n )\n\n const externalLink = (() => {\n if (hrefOption?.external) {\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n\n if (safeInternal) return undefined\n\n // Only attempt URL parsing when it looks like an absolute URL.\n if (typeof to === 'string' && to.indexOf(':') > -1) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n }\n\n return undefined\n })()\n\n const isActive = (() => {\n if (externalLink) return false\n\n const currentLocation = router.state.location\n\n const exact = activeOptions?.exact ?? false\n\n if (exact) {\n const testExact = exactPathTest(\n currentLocation.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n currentLocation.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n const includeSearch = activeOptions?.includeSearch ?? true\n if (includeSearch) {\n if (currentLocation.search !== next.search) {\n const currentSearchEmpty =\n !currentLocation.search ||\n (typeof currentLocation.search === 'object' &&\n Object.keys(currentLocation.search).length === 0)\n const nextSearchEmpty =\n !next.search ||\n (typeof next.search === 'object' &&\n Object.keys(next.search).length === 0)\n\n if (!(currentSearchEmpty && nextSearchEmpty)) {\n const searchTest = deepEqual(currentLocation.search, next.search, {\n partial: !exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n }\n }\n\n // Hash is not available on the server\n if (activeOptions?.includeHash) {\n return false\n }\n\n return true\n })()\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedStyle = (() => {\n const baseStyle = style\n const activeStyle = resolvedActiveProps.style\n const inactiveStyle = resolvedInactiveProps.style\n\n if (!baseStyle && !activeStyle && !inactiveStyle) {\n return undefined\n }\n\n if (baseStyle && !activeStyle && !inactiveStyle) {\n return baseStyle\n }\n\n if (!baseStyle && activeStyle && !inactiveStyle) {\n return activeStyle\n }\n\n if (!baseStyle && !activeStyle && inactiveStyle) {\n return inactiveStyle\n }\n\n return {\n ...baseStyle,\n ...activeStyle,\n ...inactiveStyle,\n }\n })()\n\n const resolvedClassName = (() => {\n const baseClassName = className\n const activeClassName = resolvedActiveProps.className\n const inactiveClassName = resolvedInactiveProps.className\n\n if (!baseClassName && !activeClassName && !inactiveClassName) {\n return ''\n }\n\n let out = ''\n\n if (baseClassName) {\n out = baseClassName\n }\n\n if (activeClassName) {\n out = out ? `${out} ${activeClassName}` : activeClassName\n }\n\n if (inactiveClassName) {\n out = out ? `${out} ${inactiveClassName}` : inactiveClassName\n }\n\n return out\n })()\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n }\n }\n\n // ==========================================================================\n // CLIENT-ONLY CODE\n // Everything below this point only runs on the client. The `isServer` check\n // above is a compile-time constant that bundlers use for dead code elimination,\n // so this entire section is removed from server bundles.\n //\n // We disable the rules-of-hooks lint rule because these hooks appear after\n // an early return. This is safe because:\n // 1. `isServer` is a compile-time constant from conditional exports\n // 2. In server bundles, this code is completely eliminated by the bundler\n // 3. In client bundles, `isServer` is `false`, so the early return never executes\n // ==========================================================================\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isHydrated = useHydrated()\n\n // subscribe to path/search/hash/params to re-build location when they change\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const currentLocationState = useRouterState({\n select: (s) => {\n const leaf = s.matches[s.matches.length - 1]\n return {\n search: leaf?.search,\n hash: s.location.hash,\n path: leaf?.pathname, // path + params\n }\n },\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentLocationState,\n from,\n options._fromLocation,\n options.hash,\n options.to,\n options.search,\n options.params,\n options.state,\n options.mask,\n options.unsafeRelative,\n ],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hrefOption = React.useMemo(\n () =>\n getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n ),\n [disabled, hrefOptionExternal, hrefOptionPublicHref, router.history],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n const safeInternal = isSafeInternal(to)\n if (safeInternal) return undefined\n if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n }, [to, hrefOption, router.protocolAllowlist])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isActive = useRouterState({\n select: (s) => {\n if (externalLink) return false\n if (activeOptions?.exact) {\n const testExact = exactPathTest(\n s.location.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n s.location.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(s.location.search, next.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n return isHydrated && s.location.hash === next.hash\n }\n return true\n },\n })\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = (style ||\n resolvedActiveProps.style ||\n resolvedInactiveProps.style) && {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hasRenderFetched = React.useRef(false)\n\n const preload =\n options.reloadDocument || externalLink\n ? false\n : (userPreload ?? router.options.defaultPreload)\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const doPreload = React.useCallback(() => {\n router\n .preloadRoute({ ..._options, _builtLocation: next } as any)\n .catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options, next])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (hasRenderFetched.current) {\n return\n }\n if (!disabled && preload === 'render') {\n doPreload()\n hasRenderFetched.current = true\n }\n }, [disabled, doPreload, preload])\n\n // The click handler\n const handleClick = (e: React.MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget = target !== undefined ? target : elementTarget\n\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options,\n replace,\n resetScroll,\n hashScrollIntoView,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n const handleFocus = (_: React.MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: React.MouseEvent) => {\n if (disabled || !preload) return\n\n if (!preloadDelay) {\n doPreload()\n } else {\n const eventTarget = e.target\n if (timeoutMap.has(eventTarget)) {\n return\n }\n const id = setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay)\n timeoutMap.set(eventTarget, id)\n }\n }\n\n const handleLeave = (e: React.MouseEvent) => {\n if (disabled || !preload || !preloadDelay) return\n const eventTarget = e.target\n const id = timeoutMap.get(eventTarget)\n if (id) {\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n onClick: composeHandlers([onClick, handleClick]),\n onFocus: composeHandlers([onFocus, handleFocus]),\n onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n ...(isHydrated && isTransitioning && STATIC_TRANSITIONING_PROPS),\n }\n}\n\nconst STATIC_EMPTY_OBJECT = {}\nconst STATIC_ACTIVE_OBJECT = { className: 'active' }\nconst STATIC_DISABLED_PROPS = { role: 'link', 'aria-disabled': true }\nconst STATIC_ACTIVE_PROPS = { 'data-status': 'active', 'aria-current': 'page' }\nconst STATIC_TRANSITIONING_PROPS = { 'data-transitioning': 'transitioning' }\n\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nconst intersectionObserverOptions: IntersectionObserverInit = {\n rootMargin: '100px',\n}\n\nconst composeHandlers =\n (handlers: Array<undefined | React.EventHandler<any>>) =>\n (e: React.SyntheticEvent) => {\n for (const handler of handlers) {\n if (!handler) continue\n if (e.defaultPrevented) return\n handler(e)\n }\n }\n\nfunction getHrefOption(\n publicHref: string,\n external: boolean,\n history: AnyRouter['history'],\n disabled: boolean | undefined,\n) {\n if (disabled) return undefined\n // Full URL means rewrite changed the origin - treat as external-like\n if (external) {\n return { href: publicHref, external: true }\n }\n return {\n href: history.createHref(publicHref) || '/',\n external: false,\n }\n}\n\nfunction isSafeInternal(to: unknown) {\n if (typeof to !== 'string') return false\n const zero = to.charCodeAt(0)\n if (zero === 47) return to.charCodeAt(1) !== 47 // '/' but not '//'\n return zero === 46 // '.', '..', './', '../'\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof React.JSX.IntrinsicElements\n ? React.JSX.IntrinsicElements[TComp]\n : TComp extends React.ComponentType<any>\n ? React.ComponentPropsWithoutRef<TComp> &\n React.RefAttributes<React.ComponentRef<TComp>>\n : never\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n UseLinkReactProps<'a'>\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentReactProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentReactProps<TComp> = Omit<\n UseLinkReactProps<TComp>,\n keyof CreateLinkProps\n>\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentReactProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): React.ReactElement\n}\n\n/**\n * Creates a typed Link-like component that preserves TanStack Router's\n * navigation semantics and type-safety while delegating rendering to the\n * provided host component.\n *\n * Useful for integrating design system anchors/buttons while keeping\n * router-aware props (eg. `to`, `params`, `search`, `preload`).\n *\n * @param Comp The host component to render (eg. a design-system Link/Button)\n * @returns A router-aware component with the same API as `Link`.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-link\n */\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => ReactNode>,\n): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\n/**\n * A strongly-typed anchor component for declarative navigation.\n * Handles path, search, hash and state updates with optional route preloading\n * and active-state styling.\n *\n * Props:\n * - `preload`: Controls route preloading (eg. 'intent', 'render', 'viewport', true/false)\n * - `preloadDelay`: Delay in ms before preloading on hover\n * - `activeProps`/`inactiveProps`: Additional props merged when link is active/inactive\n * - `resetScroll`/`hashScrollIntoView`: Control scroll behavior on navigation\n * - `viewTransition`/`startTransition`: Use View Transitions/React transitions for navigation\n * - `ignoreBlocker`: Bypass registered blockers\n *\n * @returns An anchor-like element that navigates without full page reloads.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkComponent\n */\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const { type: _type, ...linkProps } = useLinkProps(rest as any, ref)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n if (!_asChild) {\n // the ReturnType of useLinkProps returns the correct type for a <a> element, not a general component that has a disabled prop\n // @ts-expect-error\n const { disabled: _, ...rest } = linkProps\n return React.createElement('a', rest, children)\n }\n return React.createElement(_asChild, linkProps, children)\n },\n) as any\n\nfunction isCtrlEvent(e: React.MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\n/**\n * Validate and reuse navigation options for `Link`, `navigate` or `redirect`.\n * Accepts a literal options object and returns it typed for later spreading.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n\n/**\n * Type-check a literal object for use with `Link`, `navigate` or `redirect`.\n * Use to validate and reuse navigation options across your app.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\n"],"names":["useRouter","useForwardedRef","isServer","isDangerousProtocol","next","hrefOptionPublicHref","hrefOptionExternal","hrefOption","externalLink","isActive","exactPathTest","removeTrailingSlash","deepEqual","resolvedActiveProps","functionalUpdate","resolvedInactiveProps","resolvedStyle","resolvedClassName","useHydrated","useRouterState","React","preloadWarning","useIntersectionObserver","flushSync","rest"],"mappings":"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"}
1
+ {"version":3,"file":"link.cjs","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type { ReactNode } from 'react'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\n/**\n * Build anchor-like props for declarative navigation and preloading.\n *\n * Returns stable `href`, event handlers and accessibility props derived from\n * router options and active state. Used internally by `Link` and custom links.\n *\n * Options cover `to`, `params`, `search`, `hash`, `state`, `preload`,\n * `activeProps`, `inactiveProps`, and more.\n *\n * @returns React anchor props suitable for `<a>` or custom components.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useLinkPropsHook\n */\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = string,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n forwardedRef?: React.ForwardedRef<Element>,\n): React.ComponentPropsWithRef<'a'> {\n const router = useRouter()\n const innerRef = useForwardedRef(forwardedRef)\n\n // Determine if we're on the server - used for tree-shaking client-only code\n const _isServer = isServer ?? router.isServer\n\n const {\n // custom props\n activeProps,\n inactiveProps,\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n hashScrollIntoView,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onBlur,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ignoreBlocker,\n // prevent these from being returned\n params: _params,\n search: _search,\n hash: _hash,\n state: _state,\n mask: _mask,\n reloadDocument: _reloadDocument,\n unsafeRelative: _unsafeRelative,\n from: _from,\n _fromLocation,\n ...propsSafeToSpread\n } = options\n\n // ==========================================================================\n // SERVER EARLY RETURN\n // On the server, we return static props without any event handlers,\n // effects, or client-side interactivity.\n //\n // For SSR parity (to avoid hydration errors), we still compute the link's\n // active status on the server, but we avoid creating any router-state\n // subscriptions by reading from `router.state` directly.\n //\n // Note: `location.hash` is not available on the server.\n // ==========================================================================\n if (_isServer) {\n const safeInternal = isSafeInternal(to)\n\n // If `to` is obviously an absolute URL, treat as external and avoid\n // computing the internal location via `buildLocation`.\n if (\n typeof to === 'string' &&\n !safeInternal &&\n // Quick checks to avoid `new URL` in common internal-like cases\n to.indexOf(':') > -1\n ) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: undefined,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n } catch {\n // Not an absolute URL\n }\n }\n\n const next = router.buildLocation({ ...options, from: options.from } as any)\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n const hrefOption = getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n )\n\n const externalLink = (() => {\n if (hrefOption?.external) {\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n\n if (safeInternal) return undefined\n\n // Only attempt URL parsing when it looks like an absolute URL.\n if (typeof to === 'string' && to.indexOf(':') > -1) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n }\n\n return undefined\n })()\n\n const isActive = (() => {\n if (externalLink) return false\n\n const currentLocation = router.state.location\n\n const exact = activeOptions?.exact ?? false\n\n if (exact) {\n const testExact = exactPathTest(\n currentLocation.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n currentLocation.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n const includeSearch = activeOptions?.includeSearch ?? true\n if (includeSearch) {\n if (currentLocation.search !== next.search) {\n const currentSearchEmpty =\n !currentLocation.search ||\n (typeof currentLocation.search === 'object' &&\n Object.keys(currentLocation.search).length === 0)\n const nextSearchEmpty =\n !next.search ||\n (typeof next.search === 'object' &&\n Object.keys(next.search).length === 0)\n\n if (!(currentSearchEmpty && nextSearchEmpty)) {\n const searchTest = deepEqual(currentLocation.search, next.search, {\n partial: !exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n }\n }\n\n // Hash is not available on the server\n if (activeOptions?.includeHash) {\n return false\n }\n\n return true\n })()\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedStyle = (() => {\n const baseStyle = style\n const activeStyle = resolvedActiveProps.style\n const inactiveStyle = resolvedInactiveProps.style\n\n if (!baseStyle && !activeStyle && !inactiveStyle) {\n return undefined\n }\n\n if (baseStyle && !activeStyle && !inactiveStyle) {\n return baseStyle\n }\n\n if (!baseStyle && activeStyle && !inactiveStyle) {\n return activeStyle\n }\n\n if (!baseStyle && !activeStyle && inactiveStyle) {\n return inactiveStyle\n }\n\n return {\n ...baseStyle,\n ...activeStyle,\n ...inactiveStyle,\n }\n })()\n\n const resolvedClassName = (() => {\n const baseClassName = className\n const activeClassName = resolvedActiveProps.className\n const inactiveClassName = resolvedInactiveProps.className\n\n if (!baseClassName && !activeClassName && !inactiveClassName) {\n return ''\n }\n\n let out = ''\n\n if (baseClassName) {\n out = baseClassName\n }\n\n if (activeClassName) {\n out = out ? `${out} ${activeClassName}` : activeClassName\n }\n\n if (inactiveClassName) {\n out = out ? `${out} ${inactiveClassName}` : inactiveClassName\n }\n\n return out\n })()\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n }\n }\n\n // ==========================================================================\n // CLIENT-ONLY CODE\n // Everything below this point only runs on the client. The `isServer` check\n // above is a compile-time constant that bundlers use for dead code elimination,\n // so this entire section is removed from server bundles.\n //\n // We disable the rules-of-hooks lint rule because these hooks appear after\n // an early return. This is safe because:\n // 1. `isServer` is a compile-time constant from conditional exports\n // 2. In server bundles, this code is completely eliminated by the bundler\n // 3. In client bundles, `isServer` is `false`, so the early return never executes\n // ==========================================================================\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isHydrated = useHydrated()\n\n // subscribe to path/search/hash/params to re-build location when they change\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const currentLocationState = useRouterState({\n select: (s) => {\n const leaf = s.matches[s.matches.length - 1]\n return {\n search: leaf?.search,\n hash: s.location.hash,\n path: leaf?.pathname, // path + params\n }\n },\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentLocationState,\n from,\n options._fromLocation,\n options.hash,\n options.to,\n options.search,\n options.params,\n options.state,\n options.mask,\n options.unsafeRelative,\n ],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hrefOption = React.useMemo(\n () =>\n getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n ),\n [disabled, hrefOptionExternal, hrefOptionPublicHref, router.history],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n const safeInternal = isSafeInternal(to)\n if (safeInternal) return undefined\n if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n }, [to, hrefOption, router.protocolAllowlist])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isActive = useRouterState({\n select: (s) => {\n if (externalLink) return false\n if (activeOptions?.exact) {\n const testExact = exactPathTest(\n s.location.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n s.location.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(s.location.search, next.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n return isHydrated && s.location.hash === next.hash\n }\n return true\n },\n })\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = (style ||\n resolvedActiveProps.style ||\n resolvedInactiveProps.style) && {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hasRenderFetched = React.useRef(false)\n\n const preload =\n options.reloadDocument || externalLink\n ? false\n : (userPreload ?? router.options.defaultPreload)\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const doPreload = React.useCallback(() => {\n router\n .preloadRoute({ ..._options, _builtLocation: next } as any)\n .catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options, next])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (hasRenderFetched.current) {\n return\n }\n if (!disabled && preload === 'render') {\n doPreload()\n hasRenderFetched.current = true\n }\n }, [disabled, doPreload, preload])\n\n // The click handler\n const handleClick = (e: React.MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget = target !== undefined ? target : elementTarget\n\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options,\n replace,\n resetScroll,\n hashScrollIntoView,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onBlur && { onBlur }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n const enqueueIntentPreload = (e: React.MouseEvent | React.FocusEvent) => {\n if (disabled || preload !== 'intent') return\n\n if (!preloadDelay) {\n doPreload()\n return\n }\n\n const eventTarget = e.currentTarget\n\n if (timeoutMap.has(eventTarget)) {\n return\n }\n\n const id = setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay)\n timeoutMap.set(eventTarget, id)\n }\n\n const handleTouchStart = (_: React.TouchEvent) => {\n if (disabled || preload !== 'intent') return\n doPreload()\n }\n\n const handleLeave = (e: React.MouseEvent | React.FocusEvent) => {\n if (disabled || !preload || !preloadDelay) return\n const eventTarget = e.currentTarget\n const id = timeoutMap.get(eventTarget)\n if (id) {\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n onClick: composeHandlers([onClick, handleClick]),\n onBlur: composeHandlers([onBlur, handleLeave]),\n onFocus: composeHandlers([onFocus, enqueueIntentPreload]),\n onMouseEnter: composeHandlers([onMouseEnter, enqueueIntentPreload]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n ...(isHydrated && isTransitioning && STATIC_TRANSITIONING_PROPS),\n }\n}\n\nconst STATIC_EMPTY_OBJECT = {}\nconst STATIC_ACTIVE_OBJECT = { className: 'active' }\nconst STATIC_DISABLED_PROPS = { role: 'link', 'aria-disabled': true }\nconst STATIC_ACTIVE_PROPS = { 'data-status': 'active', 'aria-current': 'page' }\nconst STATIC_TRANSITIONING_PROPS = { 'data-transitioning': 'transitioning' }\n\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nconst intersectionObserverOptions: IntersectionObserverInit = {\n rootMargin: '100px',\n}\n\nconst composeHandlers =\n (handlers: Array<undefined | React.EventHandler<any>>) =>\n (e: React.SyntheticEvent) => {\n for (const handler of handlers) {\n if (!handler) continue\n if (e.defaultPrevented) return\n handler(e)\n }\n }\n\nfunction getHrefOption(\n publicHref: string,\n external: boolean,\n history: AnyRouter['history'],\n disabled: boolean | undefined,\n) {\n if (disabled) return undefined\n // Full URL means rewrite changed the origin - treat as external-like\n if (external) {\n return { href: publicHref, external: true }\n }\n return {\n href: history.createHref(publicHref) || '/',\n external: false,\n }\n}\n\nfunction isSafeInternal(to: unknown) {\n if (typeof to !== 'string') return false\n const zero = to.charCodeAt(0)\n if (zero === 47) return to.charCodeAt(1) !== 47 // '/' but not '//'\n return zero === 46 // '.', '..', './', '../'\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof React.JSX.IntrinsicElements\n ? React.JSX.IntrinsicElements[TComp]\n : TComp extends React.ComponentType<any>\n ? React.ComponentPropsWithoutRef<TComp> &\n React.RefAttributes<React.ComponentRef<TComp>>\n : never\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n UseLinkReactProps<'a'>\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentReactProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentReactProps<TComp> = Omit<\n UseLinkReactProps<TComp>,\n keyof CreateLinkProps\n>\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentReactProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): React.ReactElement\n}\n\n/**\n * Creates a typed Link-like component that preserves TanStack Router's\n * navigation semantics and type-safety while delegating rendering to the\n * provided host component.\n *\n * Useful for integrating design system anchors/buttons while keeping\n * router-aware props (eg. `to`, `params`, `search`, `preload`).\n *\n * @param Comp The host component to render (eg. a design-system Link/Button)\n * @returns A router-aware component with the same API as `Link`.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-link\n */\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => ReactNode>,\n): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\n/**\n * A strongly-typed anchor component for declarative navigation.\n * Handles path, search, hash and state updates with optional route preloading\n * and active-state styling.\n *\n * Props:\n * - `preload`: Controls route preloading (eg. 'intent', 'render', 'viewport', true/false)\n * - `preloadDelay`: Delay in ms before preloading on hover\n * - `activeProps`/`inactiveProps`: Additional props merged when link is active/inactive\n * - `resetScroll`/`hashScrollIntoView`: Control scroll behavior on navigation\n * - `viewTransition`/`startTransition`: Use View Transitions/React transitions for navigation\n * - `ignoreBlocker`: Bypass registered blockers\n *\n * @returns An anchor-like element that navigates without full page reloads.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkComponent\n */\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const { type: _type, ...linkProps } = useLinkProps(rest as any, ref)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n if (!_asChild) {\n // the ReturnType of useLinkProps returns the correct type for a <a> element, not a general component that has a disabled prop\n // @ts-expect-error\n const { disabled: _, ...rest } = linkProps\n return React.createElement('a', rest, children)\n }\n return React.createElement(_asChild, linkProps, children)\n },\n) as any\n\nfunction isCtrlEvent(e: React.MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\n/**\n * Validate and reuse navigation options for `Link`, `navigate` or `redirect`.\n * Accepts a literal options object and returns it typed for later spreading.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n\n/**\n * Type-check a literal object for use with `Link`, `navigate` or `redirect`.\n * Use to validate and reuse navigation options across your app.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\n"],"names":["useRouter","useForwardedRef","isServer","isDangerousProtocol","next","hrefOptionPublicHref","hrefOptionExternal","hrefOption","externalLink","isActive","exactPathTest","removeTrailingSlash","deepEqual","resolvedActiveProps","functionalUpdate","resolvedInactiveProps","resolvedStyle","resolvedClassName","useHydrated","useRouterState","React","preloadWarning","useIntersectionObserver","flushSync","rest"],"mappings":"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"}
package/dist/esm/link.js CHANGED
@@ -31,6 +31,7 @@ function useLinkProps(options, forwardedRef) {
31
31
  style,
32
32
  className,
33
33
  onClick,
34
+ onBlur,
34
35
  onFocus,
35
36
  onMouseEnter,
36
37
  onMouseLeave,
@@ -432,38 +433,36 @@ function useLinkProps(options, forwardedRef) {
432
433
  ...style && { style },
433
434
  ...className && { className },
434
435
  ...onClick && { onClick },
436
+ ...onBlur && { onBlur },
435
437
  ...onFocus && { onFocus },
436
438
  ...onMouseEnter && { onMouseEnter },
437
439
  ...onMouseLeave && { onMouseLeave },
438
440
  ...onTouchStart && { onTouchStart }
439
441
  };
440
442
  }
441
- const handleFocus = (_) => {
442
- if (disabled) return;
443
- if (preload) {
444
- doPreload();
445
- }
446
- };
447
- const handleTouchStart = handleFocus;
448
- const handleEnter = (e) => {
449
- if (disabled || !preload) return;
443
+ const enqueueIntentPreload = (e) => {
444
+ if (disabled || preload !== "intent") return;
450
445
  if (!preloadDelay) {
451
446
  doPreload();
452
- } else {
453
- const eventTarget = e.target;
454
- if (timeoutMap.has(eventTarget)) {
455
- return;
456
- }
457
- const id = setTimeout(() => {
458
- timeoutMap.delete(eventTarget);
459
- doPreload();
460
- }, preloadDelay);
461
- timeoutMap.set(eventTarget, id);
447
+ return;
462
448
  }
449
+ const eventTarget = e.currentTarget;
450
+ if (timeoutMap.has(eventTarget)) {
451
+ return;
452
+ }
453
+ const id = setTimeout(() => {
454
+ timeoutMap.delete(eventTarget);
455
+ doPreload();
456
+ }, preloadDelay);
457
+ timeoutMap.set(eventTarget, id);
458
+ };
459
+ const handleTouchStart = (_) => {
460
+ if (disabled || preload !== "intent") return;
461
+ doPreload();
463
462
  };
464
463
  const handleLeave = (e) => {
465
464
  if (disabled || !preload || !preloadDelay) return;
466
- const eventTarget = e.target;
465
+ const eventTarget = e.currentTarget;
467
466
  const id = timeoutMap.get(eventTarget);
468
467
  if (id) {
469
468
  clearTimeout(id);
@@ -477,8 +476,9 @@ function useLinkProps(options, forwardedRef) {
477
476
  href: hrefOption?.href,
478
477
  ref: innerRef,
479
478
  onClick: composeHandlers([onClick, handleClick]),
480
- onFocus: composeHandlers([onFocus, handleFocus]),
481
- onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
479
+ onBlur: composeHandlers([onBlur, handleLeave]),
480
+ onFocus: composeHandlers([onFocus, enqueueIntentPreload]),
481
+ onMouseEnter: composeHandlers([onMouseEnter, enqueueIntentPreload]),
482
482
  onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),
483
483
  onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),
484
484
  disabled: !!disabled,
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type { ReactNode } from 'react'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\n/**\n * Build anchor-like props for declarative navigation and preloading.\n *\n * Returns stable `href`, event handlers and accessibility props derived from\n * router options and active state. Used internally by `Link` and custom links.\n *\n * Options cover `to`, `params`, `search`, `hash`, `state`, `preload`,\n * `activeProps`, `inactiveProps`, and more.\n *\n * @returns React anchor props suitable for `<a>` or custom components.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useLinkPropsHook\n */\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = string,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n forwardedRef?: React.ForwardedRef<Element>,\n): React.ComponentPropsWithRef<'a'> {\n const router = useRouter()\n const innerRef = useForwardedRef(forwardedRef)\n\n // Determine if we're on the server - used for tree-shaking client-only code\n const _isServer = isServer ?? router.isServer\n\n const {\n // custom props\n activeProps,\n inactiveProps,\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n hashScrollIntoView,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ignoreBlocker,\n // prevent these from being returned\n params: _params,\n search: _search,\n hash: _hash,\n state: _state,\n mask: _mask,\n reloadDocument: _reloadDocument,\n unsafeRelative: _unsafeRelative,\n from: _from,\n _fromLocation,\n ...propsSafeToSpread\n } = options\n\n // ==========================================================================\n // SERVER EARLY RETURN\n // On the server, we return static props without any event handlers,\n // effects, or client-side interactivity.\n //\n // For SSR parity (to avoid hydration errors), we still compute the link's\n // active status on the server, but we avoid creating any router-state\n // subscriptions by reading from `router.state` directly.\n //\n // Note: `location.hash` is not available on the server.\n // ==========================================================================\n if (_isServer) {\n const safeInternal = isSafeInternal(to)\n\n // If `to` is obviously an absolute URL, treat as external and avoid\n // computing the internal location via `buildLocation`.\n if (\n typeof to === 'string' &&\n !safeInternal &&\n // Quick checks to avoid `new URL` in common internal-like cases\n to.indexOf(':') > -1\n ) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: undefined,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n } catch {\n // Not an absolute URL\n }\n }\n\n const next = router.buildLocation({ ...options, from: options.from } as any)\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n const hrefOption = getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n )\n\n const externalLink = (() => {\n if (hrefOption?.external) {\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n\n if (safeInternal) return undefined\n\n // Only attempt URL parsing when it looks like an absolute URL.\n if (typeof to === 'string' && to.indexOf(':') > -1) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n }\n\n return undefined\n })()\n\n const isActive = (() => {\n if (externalLink) return false\n\n const currentLocation = router.state.location\n\n const exact = activeOptions?.exact ?? false\n\n if (exact) {\n const testExact = exactPathTest(\n currentLocation.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n currentLocation.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n const includeSearch = activeOptions?.includeSearch ?? true\n if (includeSearch) {\n if (currentLocation.search !== next.search) {\n const currentSearchEmpty =\n !currentLocation.search ||\n (typeof currentLocation.search === 'object' &&\n Object.keys(currentLocation.search).length === 0)\n const nextSearchEmpty =\n !next.search ||\n (typeof next.search === 'object' &&\n Object.keys(next.search).length === 0)\n\n if (!(currentSearchEmpty && nextSearchEmpty)) {\n const searchTest = deepEqual(currentLocation.search, next.search, {\n partial: !exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n }\n }\n\n // Hash is not available on the server\n if (activeOptions?.includeHash) {\n return false\n }\n\n return true\n })()\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedStyle = (() => {\n const baseStyle = style\n const activeStyle = resolvedActiveProps.style\n const inactiveStyle = resolvedInactiveProps.style\n\n if (!baseStyle && !activeStyle && !inactiveStyle) {\n return undefined\n }\n\n if (baseStyle && !activeStyle && !inactiveStyle) {\n return baseStyle\n }\n\n if (!baseStyle && activeStyle && !inactiveStyle) {\n return activeStyle\n }\n\n if (!baseStyle && !activeStyle && inactiveStyle) {\n return inactiveStyle\n }\n\n return {\n ...baseStyle,\n ...activeStyle,\n ...inactiveStyle,\n }\n })()\n\n const resolvedClassName = (() => {\n const baseClassName = className\n const activeClassName = resolvedActiveProps.className\n const inactiveClassName = resolvedInactiveProps.className\n\n if (!baseClassName && !activeClassName && !inactiveClassName) {\n return ''\n }\n\n let out = ''\n\n if (baseClassName) {\n out = baseClassName\n }\n\n if (activeClassName) {\n out = out ? `${out} ${activeClassName}` : activeClassName\n }\n\n if (inactiveClassName) {\n out = out ? `${out} ${inactiveClassName}` : inactiveClassName\n }\n\n return out\n })()\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n }\n }\n\n // ==========================================================================\n // CLIENT-ONLY CODE\n // Everything below this point only runs on the client. The `isServer` check\n // above is a compile-time constant that bundlers use for dead code elimination,\n // so this entire section is removed from server bundles.\n //\n // We disable the rules-of-hooks lint rule because these hooks appear after\n // an early return. This is safe because:\n // 1. `isServer` is a compile-time constant from conditional exports\n // 2. In server bundles, this code is completely eliminated by the bundler\n // 3. In client bundles, `isServer` is `false`, so the early return never executes\n // ==========================================================================\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isHydrated = useHydrated()\n\n // subscribe to path/search/hash/params to re-build location when they change\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const currentLocationState = useRouterState({\n select: (s) => {\n const leaf = s.matches[s.matches.length - 1]\n return {\n search: leaf?.search,\n hash: s.location.hash,\n path: leaf?.pathname, // path + params\n }\n },\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentLocationState,\n from,\n options._fromLocation,\n options.hash,\n options.to,\n options.search,\n options.params,\n options.state,\n options.mask,\n options.unsafeRelative,\n ],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hrefOption = React.useMemo(\n () =>\n getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n ),\n [disabled, hrefOptionExternal, hrefOptionPublicHref, router.history],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n const safeInternal = isSafeInternal(to)\n if (safeInternal) return undefined\n if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n }, [to, hrefOption, router.protocolAllowlist])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isActive = useRouterState({\n select: (s) => {\n if (externalLink) return false\n if (activeOptions?.exact) {\n const testExact = exactPathTest(\n s.location.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n s.location.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(s.location.search, next.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n return isHydrated && s.location.hash === next.hash\n }\n return true\n },\n })\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = (style ||\n resolvedActiveProps.style ||\n resolvedInactiveProps.style) && {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hasRenderFetched = React.useRef(false)\n\n const preload =\n options.reloadDocument || externalLink\n ? false\n : (userPreload ?? router.options.defaultPreload)\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const doPreload = React.useCallback(() => {\n router\n .preloadRoute({ ..._options, _builtLocation: next } as any)\n .catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options, next])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (hasRenderFetched.current) {\n return\n }\n if (!disabled && preload === 'render') {\n doPreload()\n hasRenderFetched.current = true\n }\n }, [disabled, doPreload, preload])\n\n // The click handler\n const handleClick = (e: React.MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget = target !== undefined ? target : elementTarget\n\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options,\n replace,\n resetScroll,\n hashScrollIntoView,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n const handleFocus = (_: React.MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: React.MouseEvent) => {\n if (disabled || !preload) return\n\n if (!preloadDelay) {\n doPreload()\n } else {\n const eventTarget = e.target\n if (timeoutMap.has(eventTarget)) {\n return\n }\n const id = setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay)\n timeoutMap.set(eventTarget, id)\n }\n }\n\n const handleLeave = (e: React.MouseEvent) => {\n if (disabled || !preload || !preloadDelay) return\n const eventTarget = e.target\n const id = timeoutMap.get(eventTarget)\n if (id) {\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n onClick: composeHandlers([onClick, handleClick]),\n onFocus: composeHandlers([onFocus, handleFocus]),\n onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n ...(isHydrated && isTransitioning && STATIC_TRANSITIONING_PROPS),\n }\n}\n\nconst STATIC_EMPTY_OBJECT = {}\nconst STATIC_ACTIVE_OBJECT = { className: 'active' }\nconst STATIC_DISABLED_PROPS = { role: 'link', 'aria-disabled': true }\nconst STATIC_ACTIVE_PROPS = { 'data-status': 'active', 'aria-current': 'page' }\nconst STATIC_TRANSITIONING_PROPS = { 'data-transitioning': 'transitioning' }\n\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nconst intersectionObserverOptions: IntersectionObserverInit = {\n rootMargin: '100px',\n}\n\nconst composeHandlers =\n (handlers: Array<undefined | React.EventHandler<any>>) =>\n (e: React.SyntheticEvent) => {\n for (const handler of handlers) {\n if (!handler) continue\n if (e.defaultPrevented) return\n handler(e)\n }\n }\n\nfunction getHrefOption(\n publicHref: string,\n external: boolean,\n history: AnyRouter['history'],\n disabled: boolean | undefined,\n) {\n if (disabled) return undefined\n // Full URL means rewrite changed the origin - treat as external-like\n if (external) {\n return { href: publicHref, external: true }\n }\n return {\n href: history.createHref(publicHref) || '/',\n external: false,\n }\n}\n\nfunction isSafeInternal(to: unknown) {\n if (typeof to !== 'string') return false\n const zero = to.charCodeAt(0)\n if (zero === 47) return to.charCodeAt(1) !== 47 // '/' but not '//'\n return zero === 46 // '.', '..', './', '../'\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof React.JSX.IntrinsicElements\n ? React.JSX.IntrinsicElements[TComp]\n : TComp extends React.ComponentType<any>\n ? React.ComponentPropsWithoutRef<TComp> &\n React.RefAttributes<React.ComponentRef<TComp>>\n : never\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n UseLinkReactProps<'a'>\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentReactProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentReactProps<TComp> = Omit<\n UseLinkReactProps<TComp>,\n keyof CreateLinkProps\n>\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentReactProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): React.ReactElement\n}\n\n/**\n * Creates a typed Link-like component that preserves TanStack Router's\n * navigation semantics and type-safety while delegating rendering to the\n * provided host component.\n *\n * Useful for integrating design system anchors/buttons while keeping\n * router-aware props (eg. `to`, `params`, `search`, `preload`).\n *\n * @param Comp The host component to render (eg. a design-system Link/Button)\n * @returns A router-aware component with the same API as `Link`.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-link\n */\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => ReactNode>,\n): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\n/**\n * A strongly-typed anchor component for declarative navigation.\n * Handles path, search, hash and state updates with optional route preloading\n * and active-state styling.\n *\n * Props:\n * - `preload`: Controls route preloading (eg. 'intent', 'render', 'viewport', true/false)\n * - `preloadDelay`: Delay in ms before preloading on hover\n * - `activeProps`/`inactiveProps`: Additional props merged when link is active/inactive\n * - `resetScroll`/`hashScrollIntoView`: Control scroll behavior on navigation\n * - `viewTransition`/`startTransition`: Use View Transitions/React transitions for navigation\n * - `ignoreBlocker`: Bypass registered blockers\n *\n * @returns An anchor-like element that navigates without full page reloads.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkComponent\n */\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const { type: _type, ...linkProps } = useLinkProps(rest as any, ref)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n if (!_asChild) {\n // the ReturnType of useLinkProps returns the correct type for a <a> element, not a general component that has a disabled prop\n // @ts-expect-error\n const { disabled: _, ...rest } = linkProps\n return React.createElement('a', rest, children)\n }\n return React.createElement(_asChild, linkProps, children)\n },\n) as any\n\nfunction isCtrlEvent(e: React.MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\n/**\n * Validate and reuse navigation options for `Link`, `navigate` or `redirect`.\n * Accepts a literal options object and returns it typed for later spreading.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n\n/**\n * Type-check a literal object for use with `Link`, `navigate` or `redirect`.\n * Use to validate and reuse navigation options across your app.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\n"],"names":["next","hrefOptionPublicHref","hrefOptionExternal","hrefOption","externalLink","isActive","resolvedActiveProps","resolvedInactiveProps","resolvedStyle","resolvedClassName","rest"],"mappings":"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"}
1
+ {"version":3,"file":"link.js","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type { ReactNode } from 'react'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\n/**\n * Build anchor-like props for declarative navigation and preloading.\n *\n * Returns stable `href`, event handlers and accessibility props derived from\n * router options and active state. Used internally by `Link` and custom links.\n *\n * Options cover `to`, `params`, `search`, `hash`, `state`, `preload`,\n * `activeProps`, `inactiveProps`, and more.\n *\n * @returns React anchor props suitable for `<a>` or custom components.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useLinkPropsHook\n */\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = string,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n forwardedRef?: React.ForwardedRef<Element>,\n): React.ComponentPropsWithRef<'a'> {\n const router = useRouter()\n const innerRef = useForwardedRef(forwardedRef)\n\n // Determine if we're on the server - used for tree-shaking client-only code\n const _isServer = isServer ?? router.isServer\n\n const {\n // custom props\n activeProps,\n inactiveProps,\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n hashScrollIntoView,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onBlur,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ignoreBlocker,\n // prevent these from being returned\n params: _params,\n search: _search,\n hash: _hash,\n state: _state,\n mask: _mask,\n reloadDocument: _reloadDocument,\n unsafeRelative: _unsafeRelative,\n from: _from,\n _fromLocation,\n ...propsSafeToSpread\n } = options\n\n // ==========================================================================\n // SERVER EARLY RETURN\n // On the server, we return static props without any event handlers,\n // effects, or client-side interactivity.\n //\n // For SSR parity (to avoid hydration errors), we still compute the link's\n // active status on the server, but we avoid creating any router-state\n // subscriptions by reading from `router.state` directly.\n //\n // Note: `location.hash` is not available on the server.\n // ==========================================================================\n if (_isServer) {\n const safeInternal = isSafeInternal(to)\n\n // If `to` is obviously an absolute URL, treat as external and avoid\n // computing the internal location via `buildLocation`.\n if (\n typeof to === 'string' &&\n !safeInternal &&\n // Quick checks to avoid `new URL` in common internal-like cases\n to.indexOf(':') > -1\n ) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: undefined,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n } catch {\n // Not an absolute URL\n }\n }\n\n const next = router.buildLocation({ ...options, from: options.from } as any)\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n const hrefOption = getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n )\n\n const externalLink = (() => {\n if (hrefOption?.external) {\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n\n if (safeInternal) return undefined\n\n // Only attempt URL parsing when it looks like an absolute URL.\n if (typeof to === 'string' && to.indexOf(':') > -1) {\n try {\n new URL(to)\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n }\n\n return undefined\n })()\n\n const isActive = (() => {\n if (externalLink) return false\n\n const currentLocation = router.state.location\n\n const exact = activeOptions?.exact ?? false\n\n if (exact) {\n const testExact = exactPathTest(\n currentLocation.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n currentLocation.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n const includeSearch = activeOptions?.includeSearch ?? true\n if (includeSearch) {\n if (currentLocation.search !== next.search) {\n const currentSearchEmpty =\n !currentLocation.search ||\n (typeof currentLocation.search === 'object' &&\n Object.keys(currentLocation.search).length === 0)\n const nextSearchEmpty =\n !next.search ||\n (typeof next.search === 'object' &&\n Object.keys(next.search).length === 0)\n\n if (!(currentSearchEmpty && nextSearchEmpty)) {\n const searchTest = deepEqual(currentLocation.search, next.search, {\n partial: !exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n }\n }\n\n // Hash is not available on the server\n if (activeOptions?.includeHash) {\n return false\n }\n\n return true\n })()\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n }\n }\n\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedStyle = (() => {\n const baseStyle = style\n const activeStyle = resolvedActiveProps.style\n const inactiveStyle = resolvedInactiveProps.style\n\n if (!baseStyle && !activeStyle && !inactiveStyle) {\n return undefined\n }\n\n if (baseStyle && !activeStyle && !inactiveStyle) {\n return baseStyle\n }\n\n if (!baseStyle && activeStyle && !inactiveStyle) {\n return activeStyle\n }\n\n if (!baseStyle && !activeStyle && inactiveStyle) {\n return inactiveStyle\n }\n\n return {\n ...baseStyle,\n ...activeStyle,\n ...inactiveStyle,\n }\n })()\n\n const resolvedClassName = (() => {\n const baseClassName = className\n const activeClassName = resolvedActiveProps.className\n const inactiveClassName = resolvedInactiveProps.className\n\n if (!baseClassName && !activeClassName && !inactiveClassName) {\n return ''\n }\n\n let out = ''\n\n if (baseClassName) {\n out = baseClassName\n }\n\n if (activeClassName) {\n out = out ? `${out} ${activeClassName}` : activeClassName\n }\n\n if (inactiveClassName) {\n out = out ? `${out} ${inactiveClassName}` : inactiveClassName\n }\n\n return out\n })()\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n }\n }\n\n // ==========================================================================\n // CLIENT-ONLY CODE\n // Everything below this point only runs on the client. The `isServer` check\n // above is a compile-time constant that bundlers use for dead code elimination,\n // so this entire section is removed from server bundles.\n //\n // We disable the rules-of-hooks lint rule because these hooks appear after\n // an early return. This is safe because:\n // 1. `isServer` is a compile-time constant from conditional exports\n // 2. In server bundles, this code is completely eliminated by the bundler\n // 3. In client bundles, `isServer` is `false`, so the early return never executes\n // ==========================================================================\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isHydrated = useHydrated()\n\n // subscribe to path/search/hash/params to re-build location when they change\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const currentLocationState = useRouterState({\n select: (s) => {\n const leaf = s.matches[s.matches.length - 1]\n return {\n search: leaf?.search,\n hash: s.location.hash,\n path: leaf?.pathname, // path + params\n }\n },\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentLocationState,\n from,\n options._fromLocation,\n options.hash,\n options.to,\n options.search,\n options.params,\n options.state,\n options.mask,\n options.unsafeRelative,\n ],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const hrefOptionPublicHref = next.maskedLocation\n ? next.maskedLocation.publicHref\n : next.publicHref\n const hrefOptionExternal = next.maskedLocation\n ? next.maskedLocation.external\n : next.external\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hrefOption = React.useMemo(\n () =>\n getHrefOption(\n hrefOptionPublicHref,\n hrefOptionExternal,\n router.history,\n disabled,\n ),\n [disabled, hrefOptionExternal, hrefOptionPublicHref, router.history],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked Link with dangerous protocol: ${hrefOption.href}`,\n )\n }\n return undefined\n }\n return hrefOption.href\n }\n const safeInternal = isSafeInternal(to)\n if (safeInternal) return undefined\n if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n }, [to, hrefOption, router.protocolAllowlist])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const isActive = useRouterState({\n select: (s) => {\n if (externalLink) return false\n if (activeOptions?.exact) {\n const testExact = exactPathTest(\n s.location.pathname,\n next.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n s.location.pathname,\n router.basepath,\n )\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPathSplit.startsWith(nextPathSplit) &&\n (currentPathSplit.length === nextPathSplit.length ||\n currentPathSplit[nextPathSplit.length] === '/')\n\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(s.location.search, next.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n return isHydrated && s.location.hash === next.hash\n }\n return true\n },\n })\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? STATIC_ACTIVE_OBJECT)\n : STATIC_EMPTY_OBJECT\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive\n ? STATIC_EMPTY_OBJECT\n : (functionalUpdate(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT)\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = (style ||\n resolvedActiveProps.style ||\n resolvedInactiveProps.style) && {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const hasRenderFetched = React.useRef(false)\n\n const preload =\n options.reloadDocument || externalLink\n ? false\n : (userPreload ?? router.options.defaultPreload)\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const doPreload = React.useCallback(() => {\n router\n .preloadRoute({ ..._options, _builtLocation: next } as any)\n .catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options, next])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (hasRenderFetched.current) {\n return\n }\n if (!disabled && preload === 'render') {\n doPreload()\n hasRenderFetched.current = true\n }\n }, [disabled, doPreload, preload])\n\n // The click handler\n const handleClick = (e: React.MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget = target !== undefined ? target : elementTarget\n\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options,\n replace,\n resetScroll,\n hashScrollIntoView,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n if (externalLink) {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n href: externalLink,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onBlur && { onBlur }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n const enqueueIntentPreload = (e: React.MouseEvent | React.FocusEvent) => {\n if (disabled || preload !== 'intent') return\n\n if (!preloadDelay) {\n doPreload()\n return\n }\n\n const eventTarget = e.currentTarget\n\n if (timeoutMap.has(eventTarget)) {\n return\n }\n\n const id = setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay)\n timeoutMap.set(eventTarget, id)\n }\n\n const handleTouchStart = (_: React.TouchEvent) => {\n if (disabled || preload !== 'intent') return\n doPreload()\n }\n\n const handleLeave = (e: React.MouseEvent | React.FocusEvent) => {\n if (disabled || !preload || !preloadDelay) return\n const eventTarget = e.currentTarget\n const id = timeoutMap.get(eventTarget)\n if (id) {\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: hrefOption?.href,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n onClick: composeHandlers([onClick, handleClick]),\n onBlur: composeHandlers([onBlur, handleLeave]),\n onFocus: composeHandlers([onFocus, enqueueIntentPreload]),\n onMouseEnter: composeHandlers([onMouseEnter, enqueueIntentPreload]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n disabled: !!disabled,\n target,\n ...(resolvedStyle && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && STATIC_DISABLED_PROPS),\n ...(isActive && STATIC_ACTIVE_PROPS),\n ...(isHydrated && isTransitioning && STATIC_TRANSITIONING_PROPS),\n }\n}\n\nconst STATIC_EMPTY_OBJECT = {}\nconst STATIC_ACTIVE_OBJECT = { className: 'active' }\nconst STATIC_DISABLED_PROPS = { role: 'link', 'aria-disabled': true }\nconst STATIC_ACTIVE_PROPS = { 'data-status': 'active', 'aria-current': 'page' }\nconst STATIC_TRANSITIONING_PROPS = { 'data-transitioning': 'transitioning' }\n\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nconst intersectionObserverOptions: IntersectionObserverInit = {\n rootMargin: '100px',\n}\n\nconst composeHandlers =\n (handlers: Array<undefined | React.EventHandler<any>>) =>\n (e: React.SyntheticEvent) => {\n for (const handler of handlers) {\n if (!handler) continue\n if (e.defaultPrevented) return\n handler(e)\n }\n }\n\nfunction getHrefOption(\n publicHref: string,\n external: boolean,\n history: AnyRouter['history'],\n disabled: boolean | undefined,\n) {\n if (disabled) return undefined\n // Full URL means rewrite changed the origin - treat as external-like\n if (external) {\n return { href: publicHref, external: true }\n }\n return {\n href: history.createHref(publicHref) || '/',\n external: false,\n }\n}\n\nfunction isSafeInternal(to: unknown) {\n if (typeof to !== 'string') return false\n const zero = to.charCodeAt(0)\n if (zero === 47) return to.charCodeAt(1) !== 47 // '/' but not '//'\n return zero === 46 // '.', '..', './', '../'\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof React.JSX.IntrinsicElements\n ? React.JSX.IntrinsicElements[TComp]\n : TComp extends React.ComponentType<any>\n ? React.ComponentPropsWithoutRef<TComp> &\n React.RefAttributes<React.ComponentRef<TComp>>\n : never\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n UseLinkReactProps<'a'>\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentReactProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentReactProps<TComp> = Omit<\n UseLinkReactProps<TComp>,\n keyof CreateLinkProps\n>\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentReactProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): React.ReactElement\n}\n\n/**\n * Creates a typed Link-like component that preserves TanStack Router's\n * navigation semantics and type-safety while delegating rendering to the\n * provided host component.\n *\n * Useful for integrating design system anchors/buttons while keeping\n * router-aware props (eg. `to`, `params`, `search`, `preload`).\n *\n * @param Comp The host component to render (eg. a design-system Link/Button)\n * @returns A router-aware component with the same API as `Link`.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-link\n */\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => ReactNode>,\n): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\n/**\n * A strongly-typed anchor component for declarative navigation.\n * Handles path, search, hash and state updates with optional route preloading\n * and active-state styling.\n *\n * Props:\n * - `preload`: Controls route preloading (eg. 'intent', 'render', 'viewport', true/false)\n * - `preloadDelay`: Delay in ms before preloading on hover\n * - `activeProps`/`inactiveProps`: Additional props merged when link is active/inactive\n * - `resetScroll`/`hashScrollIntoView`: Control scroll behavior on navigation\n * - `viewTransition`/`startTransition`: Use View Transitions/React transitions for navigation\n * - `ignoreBlocker`: Bypass registered blockers\n *\n * @returns An anchor-like element that navigates without full page reloads.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkComponent\n */\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const { type: _type, ...linkProps } = useLinkProps(rest as any, ref)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n if (!_asChild) {\n // the ReturnType of useLinkProps returns the correct type for a <a> element, not a general component that has a disabled prop\n // @ts-expect-error\n const { disabled: _, ...rest } = linkProps\n return React.createElement('a', rest, children)\n }\n return React.createElement(_asChild, linkProps, children)\n },\n) as any\n\nfunction isCtrlEvent(e: React.MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\n/**\n * Validate and reuse navigation options for `Link`, `navigate` or `redirect`.\n * Accepts a literal options object and returns it typed for later spreading.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n\n/**\n * Type-check a literal object for use with `Link`, `navigate` or `redirect`.\n * Use to validate and reuse navigation options across your app.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\n"],"names":["next","hrefOptionPublicHref","hrefOptionExternal","hrefOption","externalLink","isActive","resolvedActiveProps","resolvedInactiveProps","resolvedStyle","resolvedClassName","rest"],"mappings":";;;;;;;;;AA0CO,SAAS,aAOd,SACA,cACkC;AAClC,QAAM,SAAS,UAAA;AACf,QAAM,WAAW,gBAAgB,YAAY;AAG7C,QAAM,YAAY,YAAY,OAAO;AAErC,QAAM;AAAA;AAAA,IAEJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EAAA,IACD;AAaJ,MAAI,WAAW;AACb,UAAM,eAAe,eAAe,EAAE;AAItC,QACE,OAAO,OAAO,YACd,CAAC;AAAA,IAED,GAAG,QAAQ,GAAG,IAAI,IAClB;AACA,UAAI;AACF,YAAI,IAAI,EAAE;AACV,YAAI,oBAAoB,IAAI,OAAO,iBAAiB,GAAG;AACrD,cAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,oBAAQ,KAAK,yCAAyC,EAAE,EAAE;AAAA,UAC5D;AACA,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,KAAK;AAAA,YACL,MAAM;AAAA,YACN,GAAI,YAAY,EAAE,SAAA;AAAA,YAClB,GAAI,UAAU,EAAE,OAAA;AAAA,YAChB,GAAI,YAAY,EAAE,SAAA;AAAA,YAClB,GAAI,SAAS,EAAE,MAAA;AAAA,YACf,GAAI,aAAa,EAAE,UAAA;AAAA,UAAU;AAAA,QAEjC;AAEA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,KAAK;AAAA,UACL,MAAM;AAAA,UACN,GAAI,YAAY,EAAE,SAAA;AAAA,UAClB,GAAI,UAAU,EAAE,OAAA;AAAA,UAChB,GAAI,YAAY,EAAE,SAAA;AAAA,UAClB,GAAI,SAAS,EAAE,MAAA;AAAA,UACf,GAAI,aAAa,EAAE,UAAA;AAAA,QAAU;AAAA,MAEjC,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAMA,QAAO,OAAO,cAAc,EAAE,GAAG,SAAS,MAAM,QAAQ,MAAa;AAM3E,UAAMC,wBAAuBD,MAAK,iBAC9BA,MAAK,eAAe,aACpBA,MAAK;AACT,UAAME,sBAAqBF,MAAK,iBAC5BA,MAAK,eAAe,WACpBA,MAAK;AACT,UAAMG,cAAa;AAAA,MACjBF;AAAAA,MACAC;AAAAA,MACA,OAAO;AAAA,MACP;AAAA,IAAA;AAGF,UAAME,iBAAgB,MAAM;AAC1B,UAAID,aAAY,UAAU;AACxB,YAAI,oBAAoBA,YAAW,MAAM,OAAO,iBAAiB,GAAG;AAClE,cAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,oBAAQ;AAAA,cACN,yCAAyCA,YAAW,IAAI;AAAA,YAAA;AAAA,UAE5D;AACA,iBAAO;AAAA,QACT;AACA,eAAOA,YAAW;AAAA,MACpB;AAEA,UAAI,aAAc,QAAO;AAGzB,UAAI,OAAO,OAAO,YAAY,GAAG,QAAQ,GAAG,IAAI,IAAI;AAClD,YAAI;AACF,cAAI,IAAI,EAAE;AACV,cAAI,oBAAoB,IAAI,OAAO,iBAAiB,GAAG;AACrD,gBAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,sBAAQ,KAAK,yCAAyC,EAAE,EAAE;AAAA,YAC5D;AACA,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT,QAAQ;AAAA,QAAC;AAAA,MACX;AAEA,aAAO;AAAA,IACT,GAAA;AAEA,UAAME,aAAY,MAAM;AACtB,UAAID,cAAc,QAAO;AAEzB,YAAM,kBAAkB,OAAO,MAAM;AAErC,YAAM,QAAQ,eAAe,SAAS;AAEtC,UAAI,OAAO;AACT,cAAM,YAAY;AAAA,UAChB,gBAAgB;AAAA,UAChBJ,MAAK;AAAA,UACL,OAAO;AAAA,QAAA;AAET,YAAI,CAAC,WAAW;AACd,iBAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL,cAAM,mBAAmB;AAAA,UACvB,gBAAgB;AAAA,UAChB,OAAO;AAAA,QAAA;AAET,cAAM,gBAAgB;AAAA,UACpBA,MAAK;AAAA,UACL,OAAO;AAAA,QAAA;AAGT,cAAM,mBACJ,iBAAiB,WAAW,aAAa,MACxC,iBAAiB,WAAW,cAAc,UACzC,iBAAiB,cAAc,MAAM,MAAM;AAE/C,YAAI,CAAC,kBAAkB;AACrB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,YAAM,gBAAgB,eAAe,iBAAiB;AACtD,UAAI,eAAe;AACjB,YAAI,gBAAgB,WAAWA,MAAK,QAAQ;AAC1C,gBAAM,qBACJ,CAAC,gBAAgB,UAChB,OAAO,gBAAgB,WAAW,YACjC,OAAO,KAAK,gBAAgB,MAAM,EAAE,WAAW;AACnD,gBAAM,kBACJ,CAACA,MAAK,UACL,OAAOA,MAAK,WAAW,YACtB,OAAO,KAAKA,MAAK,MAAM,EAAE,WAAW;AAExC,cAAI,EAAE,sBAAsB,kBAAkB;AAC5C,kBAAM,aAAa,UAAU,gBAAgB,QAAQA,MAAK,QAAQ;AAAA,cAChE,SAAS,CAAC;AAAA,cACV,iBAAiB,CAAC,eAAe;AAAA,YAAA,CAClC;AACD,gBAAI,CAAC,YAAY;AACf,qBAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,UAAI,eAAe,aAAa;AAC9B,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,GAAA;AAEA,QAAII,eAAc;AAChB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,KAAK;AAAA,QACL,MAAMA;AAAAA,QACN,GAAI,YAAY,EAAE,SAAA;AAAA,QAClB,GAAI,UAAU,EAAE,OAAA;AAAA,QAChB,GAAI,YAAY,EAAE,SAAA;AAAA,QAClB,GAAI,SAAS,EAAE,MAAA;AAAA,QACf,GAAI,aAAa,EAAE,UAAA;AAAA,MAAU;AAAA,IAEjC;AAEA,UAAME,uBACJD,YACK,iBAAiB,aAAoB,CAAA,CAAE,KAAK,uBAC7C;AAEN,UAAME,yBACJF,YACI,sBACC,iBAAiB,eAAe,CAAA,CAAE,KAAK;AAE9C,UAAMG,kBAAiB,MAAM;AAC3B,YAAM,YAAY;AAClB,YAAM,cAAcF,qBAAoB;AACxC,YAAM,gBAAgBC,uBAAsB;AAE5C,UAAI,CAAC,aAAa,CAAC,eAAe,CAAC,eAAe;AAChD,eAAO;AAAA,MACT;AAEA,UAAI,aAAa,CAAC,eAAe,CAAC,eAAe;AAC/C,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,aAAa,eAAe,CAAC,eAAe;AAC/C,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,aAAa,CAAC,eAAe,eAAe;AAC/C,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,MAAA;AAAA,IAEP,GAAA;AAEA,UAAME,sBAAqB,MAAM;AAC/B,YAAM,gBAAgB;AACtB,YAAM,kBAAkBH,qBAAoB;AAC5C,YAAM,oBAAoBC,uBAAsB;AAEhD,UAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,mBAAmB;AAC5D,eAAO;AAAA,MACT;AAEA,UAAI,MAAM;AAEV,UAAI,eAAe;AACjB,cAAM;AAAA,MACR;AAEA,UAAI,iBAAiB;AACnB,cAAM,MAAM,GAAG,GAAG,IAAI,eAAe,KAAK;AAAA,MAC5C;AAEA,UAAI,mBAAmB;AACrB,cAAM,MAAM,GAAG,GAAG,IAAI,iBAAiB,KAAK;AAAA,MAC9C;AAEA,aAAO;AAAA,IACT,GAAA;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAGD;AAAAA,MACH,GAAGC;AAAAA,MACH,MAAMJ,aAAY;AAAA,MAClB,KAAK;AAAA,MACL,UAAU,CAAC,CAAC;AAAA,MACZ;AAAA,MACA,GAAIK,kBAAiB,EAAE,OAAOA,eAAAA;AAAAA,MAC9B,GAAIC,sBAAqB,EAAE,WAAWA,mBAAAA;AAAAA,MACtC,GAAI,YAAY;AAAA,MAChB,GAAIJ,aAAY;AAAA,IAAA;AAAA,EAEpB;AAgBA,QAAM,aAAa,YAAA;AAInB,QAAM,uBAAuB,eAAe;AAAA,IAC1C,QAAQ,CAAC,MAAM;AACb,YAAM,OAAO,EAAE,QAAQ,EAAE,QAAQ,SAAS,CAAC;AAC3C,aAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,MAAM,EAAE,SAAS;AAAA,QACjB,MAAM,MAAM;AAAA;AAAA,MAAA;AAAA,IAEhB;AAAA,IACA,mBAAmB;AAAA,EAAA,CACpB;AAED,QAAM,OAAO,QAAQ;AAGrB,QAAM,WAAW,MAAM;AAAA,IACrB,MAAM;AACJ,aAAO,EAAE,GAAG,SAAS,KAAA;AAAA,IACvB;AAAA;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAAA,EACV;AAIF,QAAM,OAAO,MAAM;AAAA,IACjB,MAAM,OAAO,cAAc,EAAE,GAAG,UAAiB;AAAA,IACjD,CAAC,QAAQ,QAAQ;AAAA,EAAA;AAOnB,QAAM,uBAAuB,KAAK,iBAC9B,KAAK,eAAe,aACpB,KAAK;AACT,QAAM,qBAAqB,KAAK,iBAC5B,KAAK,eAAe,WACpB,KAAK;AAET,QAAM,aAAa,MAAM;AAAA,IACvB,MACE;AAAA,MACE;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IAAA;AAAA,IAEJ,CAAC,UAAU,oBAAoB,sBAAsB,OAAO,OAAO;AAAA,EAAA;AAIrE,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,QAAI,YAAY,UAAU;AAExB,UAAI,oBAAoB,WAAW,MAAM,OAAO,iBAAiB,GAAG;AAClE,YAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,kBAAQ;AAAA,YACN,yCAAyC,WAAW,IAAI;AAAA,UAAA;AAAA,QAE5D;AACA,eAAO;AAAA,MACT;AACA,aAAO,WAAW;AAAA,IACpB;AACA,UAAM,eAAe,eAAe,EAAE;AACtC,QAAI,aAAc,QAAO;AACzB,QAAI,OAAO,OAAO,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAI,QAAO;AAC7D,QAAI;AACF,UAAI,IAAI,EAAS;AAEjB,UAAI,oBAAoB,IAAI,OAAO,iBAAiB,GAAG;AACrD,YAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,kBAAQ,KAAK,yCAAyC,EAAE,EAAE;AAAA,QAC5D;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,QAAQ;AAAA,IAAC;AACT,WAAO;AAAA,EACT,GAAG,CAAC,IAAI,YAAY,OAAO,iBAAiB,CAAC;AAG7C,QAAM,WAAW,eAAe;AAAA,IAC9B,QAAQ,CAAC,MAAM;AACb,UAAI,aAAc,QAAO;AACzB,UAAI,eAAe,OAAO;AACxB,cAAM,YAAY;AAAA,UAChB,EAAE,SAAS;AAAA,UACX,KAAK;AAAA,UACL,OAAO;AAAA,QAAA;AAET,YAAI,CAAC,WAAW;AACd,iBAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL,cAAM,mBAAmB;AAAA,UACvB,EAAE,SAAS;AAAA,UACX,OAAO;AAAA,QAAA;AAET,cAAM,gBAAgB;AAAA,UACpB,KAAK;AAAA,UACL,OAAO;AAAA,QAAA;AAGT,cAAM,mBACJ,iBAAiB,WAAW,aAAa,MACxC,iBAAiB,WAAW,cAAc,UACzC,iBAAiB,cAAc,MAAM,MAAM;AAE/C,YAAI,CAAC,kBAAkB;AACrB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,UAAI,eAAe,iBAAiB,MAAM;AACxC,cAAM,aAAa,UAAU,EAAE,SAAS,QAAQ,KAAK,QAAQ;AAAA,UAC3D,SAAS,CAAC,eAAe;AAAA,UACzB,iBAAiB,CAAC,eAAe;AAAA,QAAA,CAClC;AACD,YAAI,CAAC,YAAY;AACf,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,UAAI,eAAe,aAAa;AAC9B,eAAO,cAAc,EAAE,SAAS,SAAS,KAAK;AAAA,MAChD;AACA,aAAO;AAAA,IACT;AAAA,EAAA,CACD;AAGD,QAAM,sBAA+D,WAChE,iBAAiB,aAAoB,CAAA,CAAE,KAAK,uBAC7C;AAGJ,QAAM,wBACJ,WACI,sBACC,iBAAiB,eAAe,CAAA,CAAE,KAAK;AAE9C,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,EAAA,EAErB,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,QAAM,iBAAiB,SACrB,oBAAoB,SACpB,sBAAsB,UAAU;AAAA,IAChC,GAAG;AAAA,IACH,GAAG,oBAAoB;AAAA,IACvB,GAAG,sBAAsB;AAAA,EAAA;AAI3B,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAS,KAAK;AAElE,QAAM,mBAAmB,MAAM,OAAO,KAAK;AAE3C,QAAM,UACJ,QAAQ,kBAAkB,eACtB,QACC,eAAe,OAAO,QAAQ;AACrC,QAAM,eACJ,oBAAoB,OAAO,QAAQ,uBAAuB;AAG5D,QAAM,YAAY,MAAM,YAAY,MAAM;AACxC,WACG,aAAa,EAAE,GAAG,UAAU,gBAAgB,MAAa,EACzD,MAAM,CAAC,QAAQ;AACd,cAAQ,KAAK,GAAG;AAChB,cAAQ,KAAK,cAAc;AAAA,IAC7B,CAAC;AAAA,EACL,GAAG,CAAC,QAAQ,UAAU,IAAI,CAAC;AAG3B,QAAM,4BAA4B,MAAM;AAAA,IACtC,CAAC,UAAiD;AAChD,UAAI,OAAO,gBAAgB;AACzB,kBAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EAAA;AAIZ;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,UAAU,CAAC,CAAC,YAAY,EAAE,YAAY,YAAA;AAAA,EAAY;AAItD,QAAM,UAAU,MAAM;AACpB,QAAI,iBAAiB,SAAS;AAC5B;AAAA,IACF;AACA,QAAI,CAAC,YAAY,YAAY,UAAU;AACrC,gBAAA;AACA,uBAAiB,UAAU;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,UAAU,WAAW,OAAO,CAAC;AAGjC,QAAM,cAAc,CAAC,MAAwB;AAE3C,UAAM,gBACJ,EAAE,cACF,aAAa,QAAQ;AACvB,UAAM,kBAAkB,WAAW,SAAY,SAAS;AAExD,QACE,CAAC,YACD,CAAC,YAAY,CAAC,KACd,CAAC,EAAE,qBACF,CAAC,mBAAmB,oBAAoB,YACzC,EAAE,WAAW,GACb;AACA,QAAE,eAAA;AAEF,gBAAU,MAAM;AACd,2BAAmB,IAAI;AAAA,MACzB,CAAC;AAED,YAAM,QAAQ,OAAO,UAAU,cAAc,MAAM;AACjD,cAAA;AACA,2BAAmB,KAAK;AAAA,MAC1B,CAAC;AAID,aAAO,SAAS;AAAA,QACd,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,IACH;AAAA,EACF;AAEA,MAAI,cAAc;AAChB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,KAAK;AAAA,MACL,MAAM;AAAA,MACN,GAAI,YAAY,EAAE,SAAA;AAAA,MAClB,GAAI,UAAU,EAAE,OAAA;AAAA,MAChB,GAAI,YAAY,EAAE,SAAA;AAAA,MAClB,GAAI,SAAS,EAAE,MAAA;AAAA,MACf,GAAI,aAAa,EAAE,UAAA;AAAA,MACnB,GAAI,WAAW,EAAE,QAAA;AAAA,MACjB,GAAI,UAAU,EAAE,OAAA;AAAA,MAChB,GAAI,WAAW,EAAE,QAAA;AAAA,MACjB,GAAI,gBAAgB,EAAE,aAAA;AAAA,MACtB,GAAI,gBAAgB,EAAE,aAAA;AAAA,MACtB,GAAI,gBAAgB,EAAE,aAAA;AAAA,IAAa;AAAA,EAEvC;AAEA,QAAM,uBAAuB,CAAC,MAA2C;AACvE,QAAI,YAAY,YAAY,SAAU;AAEtC,QAAI,CAAC,cAAc;AACjB,gBAAA;AACA;AAAA,IACF;AAEA,UAAM,cAAc,EAAE;AAEtB,QAAI,WAAW,IAAI,WAAW,GAAG;AAC/B;AAAA,IACF;AAEA,UAAM,KAAK,WAAW,MAAM;AAC1B,iBAAW,OAAO,WAAW;AAC7B,gBAAA;AAAA,IACF,GAAG,YAAY;AACf,eAAW,IAAI,aAAa,EAAE;AAAA,EAChC;AAEA,QAAM,mBAAmB,CAAC,MAAwB;AAChD,QAAI,YAAY,YAAY,SAAU;AACtC,cAAA;AAAA,EACF;AAEA,QAAM,cAAc,CAAC,MAA2C;AAC9D,QAAI,YAAY,CAAC,WAAW,CAAC,aAAc;AAC3C,UAAM,cAAc,EAAE;AACtB,UAAM,KAAK,WAAW,IAAI,WAAW;AACrC,QAAI,IAAI;AACN,mBAAa,EAAE;AACf,iBAAW,OAAO,WAAW;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,MAAM,YAAY;AAAA,IAClB,KAAK;AAAA,IACL,SAAS,gBAAgB,CAAC,SAAS,WAAW,CAAC;AAAA,IAC/C,QAAQ,gBAAgB,CAAC,QAAQ,WAAW,CAAC;AAAA,IAC7C,SAAS,gBAAgB,CAAC,SAAS,oBAAoB,CAAC;AAAA,IACxD,cAAc,gBAAgB,CAAC,cAAc,oBAAoB,CAAC;AAAA,IAClE,cAAc,gBAAgB,CAAC,cAAc,WAAW,CAAC;AAAA,IACzD,cAAc,gBAAgB,CAAC,cAAc,gBAAgB,CAAC;AAAA,IAC9D,UAAU,CAAC,CAAC;AAAA,IACZ;AAAA,IACA,GAAI,iBAAiB,EAAE,OAAO,cAAA;AAAA,IAC9B,GAAI,qBAAqB,EAAE,WAAW,kBAAA;AAAA,IACtC,GAAI,YAAY;AAAA,IAChB,GAAI,YAAY;AAAA,IAChB,GAAI,cAAc,mBAAmB;AAAA,EAAA;AAEzC;AAEA,MAAM,sBAAsB,CAAA;AAC5B,MAAM,uBAAuB,EAAE,WAAW,SAAA;AAC1C,MAAM,wBAAwB,EAAE,MAAM,QAAQ,iBAAiB,KAAA;AAC/D,MAAM,sBAAsB,EAAE,eAAe,UAAU,gBAAgB,OAAA;AACvE,MAAM,6BAA6B,EAAE,sBAAsB,gBAAA;AAE3D,MAAM,iCAAiB,QAAA;AAEvB,MAAM,8BAAwD;AAAA,EAC5D,YAAY;AACd;AAEA,MAAM,kBACJ,CAAC,aACD,CAAC,MAA4B;AAC3B,aAAW,WAAW,UAAU;AAC9B,QAAI,CAAC,QAAS;AACd,QAAI,EAAE,iBAAkB;AACxB,YAAQ,CAAC;AAAA,EACX;AACF;AAEF,SAAS,cACP,YACA,UACA,SACA,UACA;AACA,MAAI,SAAU,QAAO;AAErB,MAAI,UAAU;AACZ,WAAO,EAAE,MAAM,YAAY,UAAU,KAAA;AAAA,EACvC;AACA,SAAO;AAAA,IACL,MAAM,QAAQ,WAAW,UAAU,KAAK;AAAA,IACxC,UAAU;AAAA,EAAA;AAEd;AAEA,SAAS,eAAe,IAAa;AACnC,MAAI,OAAO,OAAO,SAAU,QAAO;AACnC,QAAM,OAAO,GAAG,WAAW,CAAC;AAC5B,MAAI,SAAS,GAAI,QAAO,GAAG,WAAW,CAAC,MAAM;AAC7C,SAAO,SAAS;AAClB;AAwIO,SAAS,WACd,MACsB;AACtB,SAAO,MAAM,WAAW,SAAS,YAAY,OAAO,KAAK;AACvD,+BAAQ,MAAA,EAAM,GAAI,OAAe,UAAU,MAAM,KAAU;AAAA,EAC7D,CAAC;AACH;AAkBO,MAAM,OAA2B,MAAM;AAAA,EAC5C,CAAC,OAAO,QAAQ;AACd,UAAM,EAAE,UAAU,GAAG,KAAA,IAAS;AAC9B,UAAM,EAAE,MAAM,OAAO,GAAG,cAAc,aAAa,MAAa,GAAG;AAEnE,UAAM,WACJ,OAAO,KAAK,aAAa,aACrB,KAAK,SAAS;AAAA,MACZ,UAAW,UAAkB,aAAa,MAAM;AAAA,IAAA,CACjD,IACD,KAAK;AAEX,QAAI,CAAC,UAAU;AAGb,YAAM,EAAE,UAAU,GAAG,GAAGK,UAAS;AACjC,aAAO,MAAM,cAAc,KAAKA,OAAM,QAAQ;AAAA,IAChD;AACA,WAAO,MAAM,cAAc,UAAU,WAAW,QAAQ;AAAA,EAC1D;AACF;AAEA,SAAS,YAAY,GAAqB;AACxC,SAAO,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE;AACpD;AAyBO,MAAM,cAAkC,CAAC,YAAY;AAC1D,SAAO;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.162.6",
3
+ "version": "1.162.9",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -82,7 +82,7 @@
82
82
  "tiny-invariant": "^1.3.3",
83
83
  "tiny-warning": "^1.0.3",
84
84
  "@tanstack/history": "1.161.4",
85
- "@tanstack/router-core": "1.162.6"
85
+ "@tanstack/router-core": "1.162.9"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@testing-library/jest-dom": "^6.6.3",
package/src/link.tsx CHANGED
@@ -76,6 +76,7 @@ export function useLinkProps<
76
76
  style,
77
77
  className,
78
78
  onClick,
79
+ onBlur,
79
80
  onFocus,
80
81
  onMouseEnter,
81
82
  onMouseLeave,
@@ -651,6 +652,7 @@ export function useLinkProps<
651
652
  ...(style && { style }),
652
653
  ...(className && { className }),
653
654
  ...(onClick && { onClick }),
655
+ ...(onBlur && { onBlur }),
654
656
  ...(onFocus && { onFocus }),
655
657
  ...(onMouseEnter && { onMouseEnter }),
656
658
  ...(onMouseLeave && { onMouseLeave }),
@@ -658,36 +660,35 @@ export function useLinkProps<
658
660
  }
659
661
  }
660
662
 
661
- const handleFocus = (_: React.MouseEvent) => {
662
- if (disabled) return
663
- if (preload) {
663
+ const enqueueIntentPreload = (e: React.MouseEvent | React.FocusEvent) => {
664
+ if (disabled || preload !== 'intent') return
665
+
666
+ if (!preloadDelay) {
664
667
  doPreload()
668
+ return
665
669
  }
666
- }
667
670
 
668
- const handleTouchStart = handleFocus
671
+ const eventTarget = e.currentTarget
669
672
 
670
- const handleEnter = (e: React.MouseEvent) => {
671
- if (disabled || !preload) return
673
+ if (timeoutMap.has(eventTarget)) {
674
+ return
675
+ }
672
676
 
673
- if (!preloadDelay) {
677
+ const id = setTimeout(() => {
678
+ timeoutMap.delete(eventTarget)
674
679
  doPreload()
675
- } else {
676
- const eventTarget = e.target
677
- if (timeoutMap.has(eventTarget)) {
678
- return
679
- }
680
- const id = setTimeout(() => {
681
- timeoutMap.delete(eventTarget)
682
- doPreload()
683
- }, preloadDelay)
684
- timeoutMap.set(eventTarget, id)
685
- }
680
+ }, preloadDelay)
681
+ timeoutMap.set(eventTarget, id)
682
+ }
683
+
684
+ const handleTouchStart = (_: React.TouchEvent) => {
685
+ if (disabled || preload !== 'intent') return
686
+ doPreload()
686
687
  }
687
688
 
688
- const handleLeave = (e: React.MouseEvent) => {
689
+ const handleLeave = (e: React.MouseEvent | React.FocusEvent) => {
689
690
  if (disabled || !preload || !preloadDelay) return
690
- const eventTarget = e.target
691
+ const eventTarget = e.currentTarget
691
692
  const id = timeoutMap.get(eventTarget)
692
693
  if (id) {
693
694
  clearTimeout(id)
@@ -702,8 +703,9 @@ export function useLinkProps<
702
703
  href: hrefOption?.href,
703
704
  ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],
704
705
  onClick: composeHandlers([onClick, handleClick]),
705
- onFocus: composeHandlers([onFocus, handleFocus]),
706
- onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
706
+ onBlur: composeHandlers([onBlur, handleLeave]),
707
+ onFocus: composeHandlers([onFocus, enqueueIntentPreload]),
708
+ onMouseEnter: composeHandlers([onMouseEnter, enqueueIntentPreload]),
707
709
  onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),
708
710
  onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),
709
711
  disabled: !!disabled,