@tanstack/react-router 1.132.23 → 1.132.26

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
@@ -102,13 +102,13 @@ function useLinkProps(options, forwardedRef) {
102
102
  let external = false;
103
103
  if (router.origin) {
104
104
  if (href.startsWith(router.origin)) {
105
- href = href.replace(router.origin, "") || "/";
105
+ href = router.history.createHref(href.replace(router.origin, "")) || "/";
106
106
  } else {
107
107
  external = true;
108
108
  }
109
109
  }
110
110
  return { href, external };
111
- }, [disabled, next.maskedLocation, next.url, router.origin]);
111
+ }, [disabled, next.maskedLocation, next.url, router.origin, router.history]);
112
112
  const externalLink = React__namespace.useMemo(() => {
113
113
  if (hrefOption?.external) {
114
114
  return hrefOption.href;
@@ -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 preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\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\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 [isTransitioning, setIsTransitioning] = React.useState(false)\n const hasRenderFetched = React.useRef(false)\n const innerRef = useForwardedRef(forwardedRef)\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 // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({\n select: (s) => s.location.search,\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentSearch,\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 const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n const hrefOption = React.useMemo(() => {\n if (disabled) {\n return undefined\n }\n let href = next.maskedLocation ? next.maskedLocation.url : next.url\n\n let external = false\n if (router.origin) {\n if (href.startsWith(router.origin)) {\n href = href.replace(router.origin, '') || '/'\n } else {\n external = true\n }\n }\n return { href, external }\n }, [disabled, next.maskedLocation, next.url, router.origin])\n\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n return hrefOption.href\n }\n try {\n new URL(to as any)\n return to\n } catch {}\n return undefined\n }, [to, hrefOption])\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 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 s.location.hash === next.hash\n }\n return true\n },\n })\n\n const doPreload = React.useCallback(() => {\n router.preloadRoute({ ..._options } as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options])\n\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\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 = (e.currentTarget as HTMLAnchorElement).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 // The click handler\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 // 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 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 ...(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\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\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\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const {\n type: _type,\n ref: innerRef,\n ...linkProps\n } = 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 === undefined) {\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 delete linkProps.disabled\n }\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref: innerRef,\n },\n children,\n )\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\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":["useRouter","React","useForwardedRef","useRouterState","exactPathTest","removeTrailingSlash","deepEqual","preloadWarning","useIntersectionObserver","flushSync","functionalUpdate"],"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 preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\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\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 [isTransitioning, setIsTransitioning] = React.useState(false)\n const hasRenderFetched = React.useRef(false)\n const innerRef = useForwardedRef(forwardedRef)\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 // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({\n select: (s) => s.location.search,\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentSearch,\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 const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n const hrefOption = React.useMemo(() => {\n if (disabled) {\n return undefined\n }\n let href = next.maskedLocation ? next.maskedLocation.url : next.url\n\n let external = false\n if (router.origin) {\n if (href.startsWith(router.origin)) {\n href = router.history.createHref(href.replace(router.origin, '')) || '/'\n } else {\n external = true\n }\n }\n return { href, external }\n }, [disabled, next.maskedLocation, next.url, router.origin, router.history])\n\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n return hrefOption.href\n }\n try {\n new URL(to as any)\n return to\n } catch {}\n return undefined\n }, [to, hrefOption])\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 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 s.location.hash === next.hash\n }\n return true\n },\n })\n\n const doPreload = React.useCallback(() => {\n router.preloadRoute({ ..._options } as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options])\n\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\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 = (e.currentTarget as HTMLAnchorElement).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 // The click handler\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 // 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 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 ...(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\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\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\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const {\n type: _type,\n ref: innerRef,\n ...linkProps\n } = 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 === undefined) {\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 delete linkProps.disabled\n }\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref: innerRef,\n },\n children,\n )\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\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":["useRouter","React","useForwardedRef","useRouterState","exactPathTest","removeTrailingSlash","deepEqual","preloadWarning","useIntersectionObserver","flushSync","functionalUpdate"],"mappings":"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"}
package/dist/esm/link.js CHANGED
@@ -83,13 +83,13 @@ function useLinkProps(options, forwardedRef) {
83
83
  let external = false;
84
84
  if (router.origin) {
85
85
  if (href.startsWith(router.origin)) {
86
- href = href.replace(router.origin, "") || "/";
86
+ href = router.history.createHref(href.replace(router.origin, "")) || "/";
87
87
  } else {
88
88
  external = true;
89
89
  }
90
90
  }
91
91
  return { href, external };
92
- }, [disabled, next.maskedLocation, next.url, router.origin]);
92
+ }, [disabled, next.maskedLocation, next.url, router.origin, router.history]);
93
93
  const externalLink = React.useMemo(() => {
94
94
  if (hrefOption?.external) {
95
95
  return hrefOption.href;
@@ -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 preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\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\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 [isTransitioning, setIsTransitioning] = React.useState(false)\n const hasRenderFetched = React.useRef(false)\n const innerRef = useForwardedRef(forwardedRef)\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 // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({\n select: (s) => s.location.search,\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentSearch,\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 const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n const hrefOption = React.useMemo(() => {\n if (disabled) {\n return undefined\n }\n let href = next.maskedLocation ? next.maskedLocation.url : next.url\n\n let external = false\n if (router.origin) {\n if (href.startsWith(router.origin)) {\n href = href.replace(router.origin, '') || '/'\n } else {\n external = true\n }\n }\n return { href, external }\n }, [disabled, next.maskedLocation, next.url, router.origin])\n\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n return hrefOption.href\n }\n try {\n new URL(to as any)\n return to\n } catch {}\n return undefined\n }, [to, hrefOption])\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 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 s.location.hash === next.hash\n }\n return true\n },\n })\n\n const doPreload = React.useCallback(() => {\n router.preloadRoute({ ..._options } as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options])\n\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\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 = (e.currentTarget as HTMLAnchorElement).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 // The click handler\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 // 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 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 ...(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\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\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\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const {\n type: _type,\n ref: innerRef,\n ...linkProps\n } = 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 === undefined) {\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 delete linkProps.disabled\n }\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref: innerRef,\n },\n children,\n )\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\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":[],"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 preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useForwardedRef, useIntersectionObserver } from './utils'\n\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\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 [isTransitioning, setIsTransitioning] = React.useState(false)\n const hasRenderFetched = React.useRef(false)\n const innerRef = useForwardedRef(forwardedRef)\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 // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({\n select: (s) => s.location.search,\n structuralSharing: true as any,\n })\n\n const from = options.from\n\n const _options = React.useMemo(\n () => {\n return { ...options, from }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n router,\n currentSearch,\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 const next = React.useMemo(\n () => router.buildLocation({ ..._options } as any),\n [router, _options],\n )\n\n const hrefOption = React.useMemo(() => {\n if (disabled) {\n return undefined\n }\n let href = next.maskedLocation ? next.maskedLocation.url : next.url\n\n let external = false\n if (router.origin) {\n if (href.startsWith(router.origin)) {\n href = router.history.createHref(href.replace(router.origin, '')) || '/'\n } else {\n external = true\n }\n }\n return { href, external }\n }, [disabled, next.maskedLocation, next.url, router.origin, router.history])\n\n const externalLink = React.useMemo(() => {\n if (hrefOption?.external) {\n return hrefOption.href\n }\n try {\n new URL(to as any)\n return to\n } catch {}\n return undefined\n }, [to, hrefOption])\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 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 s.location.hash === next.hash\n }\n return true\n },\n })\n\n const doPreload = React.useCallback(() => {\n router.preloadRoute({ ..._options } as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [router, _options])\n\n const preloadViewportIoCallback = React.useCallback(\n (entry: IntersectionObserverEntry | undefined) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n },\n [doPreload],\n )\n\n useIntersectionObserver(\n innerRef,\n preloadViewportIoCallback,\n intersectionObserverOptions,\n { disabled: !!disabled || !(preload === 'viewport') },\n )\n\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 = (e.currentTarget as HTMLAnchorElement).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 // The click handler\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 // 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 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 ...(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\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\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\nexport const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(\n (props, ref) => {\n const { _asChild, ...rest } = props\n const {\n type: _type,\n ref: innerRef,\n ...linkProps\n } = 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 === undefined) {\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 delete linkProps.disabled\n }\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref: innerRef,\n },\n children,\n )\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\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.132.23",
3
+ "version": "1.132.26",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -80,7 +80,7 @@
80
80
  "tiny-invariant": "^1.3.3",
81
81
  "tiny-warning": "^1.0.3",
82
82
  "@tanstack/history": "1.132.21",
83
- "@tanstack/router-core": "1.132.21"
83
+ "@tanstack/router-core": "1.132.26"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@testing-library/jest-dom": "^6.6.3",
package/src/link.tsx CHANGED
@@ -120,13 +120,13 @@ export function useLinkProps<
120
120
  let external = false
121
121
  if (router.origin) {
122
122
  if (href.startsWith(router.origin)) {
123
- href = href.replace(router.origin, '') || '/'
123
+ href = router.history.createHref(href.replace(router.origin, '')) || '/'
124
124
  } else {
125
125
  external = true
126
126
  }
127
127
  }
128
128
  return { href, external }
129
- }, [disabled, next.maskedLocation, next.url, router.origin])
129
+ }, [disabled, next.maskedLocation, next.url, router.origin, router.history])
130
130
 
131
131
  const externalLink = React.useMemo(() => {
132
132
  if (hrefOption?.external) {