@tanstack/react-router 1.70.1 → 1.70.2

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
@@ -56,6 +56,15 @@ function useLinkProps(options, forwardedRef) {
56
56
  ignoreBlocker,
57
57
  ...rest
58
58
  } = options;
59
+ const {
60
+ // prevent these from being returned
61
+ params: _params,
62
+ search: _search,
63
+ hash: _hash,
64
+ state: _state,
65
+ mask: _mask,
66
+ ...propsSafeToSpread
67
+ } = rest;
59
68
  const type = React__namespace.useMemo(() => {
60
69
  try {
61
70
  new URL(`${to}`);
@@ -139,7 +148,7 @@ function useLinkProps(options, forwardedRef) {
139
148
  );
140
149
  if (type === "external") {
141
150
  return {
142
- ...rest,
151
+ ...propsSafeToSpread,
143
152
  ref: innerRef,
144
153
  type,
145
154
  href: to,
@@ -224,7 +233,7 @@ function useLinkProps(options, forwardedRef) {
224
233
  ...resolvedInactiveProps.style
225
234
  };
226
235
  return {
227
- ...rest,
236
+ ...propsSafeToSpread,
228
237
  ...resolvedActiveProps,
229
238
  ...resolvedInactiveProps,
230
239
  href: disabled ? void 0 : next.maskedLocation ? router.history.createHref(next.maskedLocation.href) : router.history.createHref(next.href),
@@ -254,7 +263,7 @@ function createLink(Comp) {
254
263
  const Link = React__namespace.forwardRef(
255
264
  (props, ref) => {
256
265
  const { _asChild, ...rest } = props;
257
- const { type, ref: innerRef, ...linkProps } = useLinkProps(rest, ref);
266
+ const { type: _type, ref: innerRef, ...linkProps } = useLinkProps(rest, ref);
258
267
  const children = typeof rest.children === "function" ? rest.children({
259
268
  isActive: linkProps["data-status"] === "active"
260
269
  }) : rest.children;
@@ -1 +1 @@
1
- {"version":3,"file":"link.cjs","sources":["../../src/link.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport {\n deepEqual,\n functionalUpdate,\n useForwardedRef,\n useIntersectionObserver,\n} from './utils'\nimport { exactPathTest, removeTrailingSlash } from './path'\nimport type { ParsedLocation } from './location'\nimport type { HistoryState } from '@tanstack/history'\nimport type {\n AllParams,\n CatchAllPaths,\n CurrentPath,\n FullSearchSchema,\n FullSearchSchemaInput,\n ParentPath,\n RouteByPath,\n RouteByToPath,\n RoutePaths,\n RouteToPath,\n TrailingSlashOptionByRouter,\n} from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type {\n Constrain,\n Expand,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\nimport type { ReactNode } from 'react'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<\n T extends string,\n TAcc = never,\n> = T extends `${string}$${string}`\n ? T extends `${string}$${infer TPossiblyParam}`\n ? TPossiblyParam extends `${string}/${string}`\n ? TPossiblyParam extends `${infer TParam}/${infer TRest}`\n ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>\n : never\n : TPossiblyParam extends ''\n ? TAcc\n : TPossiblyParam | TAcc\n : TAcc\n : TAcc\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type AddTrailingSlash<T> = T extends `${string}/` ? T : `${T & string}/`\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T\n\nexport type ResolvePaths<TRouter extends AnyRouter, TSearchPath> =\n RouteByPath<\n TRouter['routeTree'],\n RemoveTrailingSlashes<TSearchPath>\n > extends never\n ? RouteToPath<TRouter, TRouter['routeTree']>\n : RouteToPath<\n TRouter,\n RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>\n >\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouter, TSearchPath>,\n TPrefix extends string = `${RemoveTrailingSlashes<TSearchPath>}/`,\n TFilteredPaths = TPaths & `${TPrefix}${string}`,\n> = TFilteredPaths extends `${TPrefix}${infer TRest}` ? TRest : never\n\nexport type SearchRelativePathAutoComplete<\n TRouter extends AnyRouter,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouter, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | (TResolvedPath extends ''\n ? never\n : `${TTo}/${ParentPath<TrailingSlashOptionByRouter<TRouter>>}`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = ResolveRelativePath<TFrom, TTo>,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n\nexport type AbsolutePathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouter, TFrom> extends ''\n ? never\n : CurrentPath<TrailingSlashOptionByRouter<TRouter>>)\n | (string extends TFrom\n ? ParentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : ParentPath<TrailingSlashOptionByRouter<TRouter>>)\n | RouteToPath<TRouter, TRouter['routeTree']>\n | (TFrom extends '/'\n ? never\n : string extends TFrom\n ? never\n : RemoveLeadingSlashes<SearchPaths<TRouter, TFrom>>)\n\nexport type RelativeToPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n> = string extends TFrom\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `.${string}`\n ? RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : AbsolutePathAutoComplete<TRouter, TFrom>\n\nexport type NavigateOptions<\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> = ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & NavigateOptionProps\n\nexport interface NavigateOptionProps {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n ignoreBlocker?: boolean\n}\n\nexport type ToOptions<\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> = ToSubOptions<TRouter, TFrom, TTo> & MaskOptions<TRouter, TMaskFrom, TMaskTo>\n\nexport interface MaskOptions<\n in out TRouter extends AnyRouter,\n in out TMaskFrom extends string,\n in out TMaskTo extends string,\n> {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouter, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRouter = RegisteredRouter,\n TMaskFrom extends string = string,\n TMaskTo extends string = '.',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n SearchParamOptions<TRouter, TFrom, TTo> &\n PathParamOptions<TRouter, TFrom, TTo>\n\nexport interface ToSubOptionsProps<\n in out TRouter extends AnyRouter = RegisteredRouter,\n in out TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n in out TTo extends string | undefined = '.',\n> {\n to?: ToPathOption<TRouter, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: FromPathOption<TRouter, TFrom> & {}\n}\n\nexport type ParamsReducerFn<\n in out TRouter extends AnyRouter,\n in out TParamVariant extends ParamVariant,\n in out TFrom,\n in out TTo,\n> = (\n current: Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>,\n) => Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n\ntype ParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n | (ParamsReducerFn<TRouter, TParamVariant, TFrom, TTo> & {})\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\nexport type ResolveRoute<\n TRouter extends AnyRouter,\n TFrom,\n TTo,\n TPath = ResolveRelativePath<TFrom, TTo>,\n> = TPath extends string\n ? TFrom extends TPath\n ? RouteByPath<TRouter['routeTree'], TPath>\n : RouteByToPath<TRouter, TPath>\n : never\n\ntype ResolveFromParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'\n\ntype ResolveFromAllParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchema<TRouter['routeTree']>\n\ntype ResolveFromParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n> = string extends TFrom\n ? ResolveFromAllParams<TRouter, TParamVariant>\n : RouteByPath<\n TRouter['routeTree'],\n TFrom\n >['types'][ResolveFromParamType<TParamVariant>]\n\ntype ResolveToParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'\n\ntype ResolveAllToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchemaInput<TRouter['routeTree']>\n\nexport type ResolveToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : string extends TPath\n ? ResolveAllToParams<TRouter, TParamVariant>\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? ResolveAllToParams<TRouter, TParamVariant>\n : ResolveRoute<\n TRouter,\n TFrom,\n TTo\n >['types'][ResolveToParamType<TParamVariant>]\n : never\n\ntype ResolveRelativeToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouter, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouter, TParamVariant, TFrom>,\n TToParams\n >\n\nexport interface MakeOptionalSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search?: true | (ParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {})\n}\n\nexport interface MakeOptionalPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params?: true | (ParamsReducer<TRouter, 'PATH', TFrom, TTo> & {})\n}\n\ntype MakeRequiredParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | (string extends TFrom\n ? never\n : ResolveFromParams<TRouter, TParamVariant, TFrom> extends WithoutEmpty<\n PickRequired<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n >\n ? true\n : never)\n | (ParamsReducer<TRouter, TParamVariant, TFrom, TTo> & {})\n\nexport interface MakeRequiredPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params: MakeRequiredParamsReducer<TRouter, 'PATH', TFrom, TTo> & {}\n}\n\nexport interface MakeRequiredSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search: MakeRequiredParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {}\n}\n\nexport type IsRequiredParams<TParams> =\n Record<never, never> extends TParams ? never : true\n\nexport type IsRequired<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n : never\n\nexport type SearchParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'SEARCH', TFrom, TTo> extends never\n ? MakeOptionalSearchParams<TRouter, TFrom, TTo>\n : MakeRequiredSearchParams<TRouter, TFrom, TTo>\n\nexport type PathParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'PATH', TFrom, TTo> extends never\n ? MakeOptionalPathParams<TRouter, TFrom, TTo>\n : MakeRequiredPathParams<TRouter, TFrom, TTo>\n\nexport type ToPathOption<\n TRouter extends AnyRouter = AnyRouter,\n TFrom extends string = string,\n TTo extends string | undefined = string,\n> =\n | CheckPath<TRouter, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport type CheckFromPath<\n TRouter extends AnyRouter,\n TPass,\n TFail,\n TFrom,\n> = string extends TFrom\n ? TPass\n : RouteByPath<TRouter['routeTree'], TFrom> extends never\n ? TFail\n : TPass\n\nexport type FromPathOption<TRouter extends AnyRouter, TFrom> =\n | CheckFromPath<\n TRouter,\n string extends TFrom ? TFrom & {} : TFrom,\n never,\n TFrom\n >\n | RoutePaths<TRouter['routeTree']>\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\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> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & LinkOptionsProps\n\nexport interface LinkOptionsProps {\n /**\n * The standard anchor tag target attribute\n */\n target?: HTMLAnchorElement['target']\n /**\n * Configurable options to determine if the link should be considered active or not\n * @default {exact:true,includeHash:true}\n */\n activeOptions?: ActiveOptions\n /**\n * The preloading strategy for this link\n * - `false` - No preloading\n * - `'intent'` - Preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n * - `'viewport'` - Preload the linked route when it enters the viewport\n */\n preload?: false | 'intent' | 'viewport'\n /**\n * When a preload strategy is set, this delays the preload by this many milliseconds.\n * If the user exits the link before this delay, the preload will be cancelled.\n */\n preloadDelay?: number\n /**\n * Control whether the link should be disabled or not\n * If set to `true`, the link will be rendered without an `href` attribute\n * @default false\n */\n disabled?: boolean\n}\n\nexport type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> =\n string extends ResolveRelativePath<TFrom, TTo>\n ? TPass\n : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths<\n TrailingSlashOptionByRouter<TRouter>\n >\n ? TPass\n : ResolveRoute<TRouter, TFrom, TTo> extends never\n ? TFail\n : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : undefined extends TTo\n ? TFrom\n : TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n 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 innerRef = useForwardedRef(forwardedRef)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\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 ...rest\n } = options\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const type: 'internal' | 'external' = React.useMemo(() => {\n try {\n new URL(`${to}`)\n return 'external'\n } catch {}\n return 'internal'\n }, [to])\n\n // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({ select: (s) => s.location.search })\n\n const next = React.useMemo(\n () => router.buildLocation(options as any),\n [router, options, currentSearch],\n )\n const preload = React.useMemo(\n () => userPreload ?? router.options.defaultPreload,\n [router.options.defaultPreload, userPreload],\n )\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\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 ).split('/')\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n ).split('/')\n\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(\n s.location.search,\n next.search,\n !activeOptions?.exact,\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 }, [options, router])\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 { rootMargin: '100px' },\n { disabled: !!disabled || preload !== 'viewport' },\n )\n\n if (type === 'external') {\n return {\n ...rest,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n type,\n href: to,\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 handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_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.buildAndCommitLocation({\n ...options,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n // The click handler\n const handleFocus = (_: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? {})\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...rest,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.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 ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof JSX.IntrinsicElements\n ? JSX.IntrinsicElements[TComp]\n : React.PropsWithoutRef<\n TComp extends React.ComponentType<infer TProps> ? TProps : never\n > &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : never\n >\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<TComp> = <\n TRouter extends RegisteredRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\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 { type, ref: innerRef, ...linkProps } = useLinkProps(rest, 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 (typeof _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: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFn<TComp> = <\n const TProps,\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n options: Constrain<\n TProps,\n LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n >,\n) => TProps\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":["useIntersectionObserver","flushSync"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAgkBA;AAEgB;AAUd;AACA;AACM;AAEA;AAAA;AAAA;;AAGmB;AACvB;AACA;AACS;AACK;AACd;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AASC;AACA;AACE;AACG;AAAA;AACD;AACD;AAAA;AAIH;AAEN;AAAmB;AACwB;AACV;AAEjC;AAAsB;AACgB;AACO;AAE7C;AAGA;AAAgC;AAE5B;AACE;AAAkB;AACL;AACN;AACE;AAET;AACS;AAAA;AACT;AAEA;AAAyB;AACZ;AACJ;AAET;AAAsB;AACf;AACE;AAGT;AAAuC;AACH;AAEpC;AACS;AAAA;AACT;AAGE;AACF;AAAmB;AACN;AACN;AACW;AAElB;AACS;AAAA;AACT;AAGF;AACS;AAAyB;AAE3B;AAAA;AACT;AAGI;AACJ;AACE;AACA;AAA2B;AAC5B;AAGH;AAAwC;AAEpC;AACY;;AACZ;AACF;AACU;AAGZA;AAAA;AACE;AACA;AACsB;AAC2B;AAGnD;AACS;AAAA;AACF;AACE;AACL;AACM;AACqB;AACJ;AACI;AACN;AACQ;AACJ;AACA;AACU;AACA;AACA;AAAA;AAKjC;AACJ;AAOE;AAEAC;AACE;AAAuB;AAGzB;AACQ;AACN;AAAwB;AAK1B;AAA8B;AACzB;AACH;AACA;AACA;AACA;AACA;AACD;AACH;AAII;AACJ;AACA;AACY;;AACZ;AAGF;AAEM;AACJ;AACM;AAEN;AACE;AACE;AAAA;AAGU;AACV;AACU;;AACG;AACjB;AAGI;AACJ;AACM;AAEN;AACE;AACA;AAA6B;AAC/B;AAGF;;AAGI;AACA;AACE;AACA;AAAU;AACX;AAIC;AAKN;AAGA;AAA0B;AACxB;AACoB;AACE;AAKxB;AAAsB;AACjB;AACoB;AACE;AAGpB;AAAA;AACF;AACA;AACA;AAKsC;AACpC;AAC0C;AACA;AACU;AACA;AACK;AAClD;AACZ;AACgE;AACR;AACxC;AACR;AACW;AACnB;AACkE;AACH;AAEnE;AA2GO;AAGL;AACE;AAA2D;AAE/D;AAEO;AAAuC;AAE1C;AACM;AAEN;AAEoB;AACoC;AAIpD;AAGF;AAAiB;AAGnB;AAAa;AACW;AACtB;AACK;AACE;AACP;AACA;AAAA;AAGN;AAEA;AACS;AACT;AAgBa;AACJ;AACT;;;;;"}
1
+ {"version":3,"file":"link.cjs","sources":["../../src/link.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport {\n deepEqual,\n functionalUpdate,\n useForwardedRef,\n useIntersectionObserver,\n} from './utils'\nimport { exactPathTest, removeTrailingSlash } from './path'\nimport type { ParsedLocation } from './location'\nimport type { HistoryState } from '@tanstack/history'\nimport type {\n AllParams,\n CatchAllPaths,\n CurrentPath,\n FullSearchSchema,\n FullSearchSchemaInput,\n ParentPath,\n RouteByPath,\n RouteByToPath,\n RoutePaths,\n RouteToPath,\n TrailingSlashOptionByRouter,\n} from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type {\n Constrain,\n Expand,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\nimport type { ReactNode } from 'react'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<\n T extends string,\n TAcc = never,\n> = T extends `${string}$${string}`\n ? T extends `${string}$${infer TPossiblyParam}`\n ? TPossiblyParam extends `${string}/${string}`\n ? TPossiblyParam extends `${infer TParam}/${infer TRest}`\n ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>\n : never\n : TPossiblyParam extends ''\n ? TAcc\n : TPossiblyParam | TAcc\n : TAcc\n : TAcc\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type AddTrailingSlash<T> = T extends `${string}/` ? T : `${T & string}/`\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T\n\nexport type ResolvePaths<TRouter extends AnyRouter, TSearchPath> =\n RouteByPath<\n TRouter['routeTree'],\n RemoveTrailingSlashes<TSearchPath>\n > extends never\n ? RouteToPath<TRouter, TRouter['routeTree']>\n : RouteToPath<\n TRouter,\n RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>\n >\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouter, TSearchPath>,\n TPrefix extends string = `${RemoveTrailingSlashes<TSearchPath>}/`,\n TFilteredPaths = TPaths & `${TPrefix}${string}`,\n> = TFilteredPaths extends `${TPrefix}${infer TRest}` ? TRest : never\n\nexport type SearchRelativePathAutoComplete<\n TRouter extends AnyRouter,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouter, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | (TResolvedPath extends ''\n ? never\n : `${TTo}/${ParentPath<TrailingSlashOptionByRouter<TRouter>>}`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = ResolveRelativePath<TFrom, TTo>,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n\nexport type AbsolutePathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouter, TFrom> extends ''\n ? never\n : CurrentPath<TrailingSlashOptionByRouter<TRouter>>)\n | (string extends TFrom\n ? ParentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : ParentPath<TrailingSlashOptionByRouter<TRouter>>)\n | RouteToPath<TRouter, TRouter['routeTree']>\n | (TFrom extends '/'\n ? never\n : string extends TFrom\n ? never\n : RemoveLeadingSlashes<SearchPaths<TRouter, TFrom>>)\n\nexport type RelativeToPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n> = string extends TFrom\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `.${string}`\n ? RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : AbsolutePathAutoComplete<TRouter, TFrom>\n\nexport type NavigateOptions<\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> = ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & NavigateOptionProps\n\nexport interface NavigateOptionProps {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n ignoreBlocker?: boolean\n}\n\nexport type ToOptions<\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> = ToSubOptions<TRouter, TFrom, TTo> & MaskOptions<TRouter, TMaskFrom, TMaskTo>\n\nexport interface MaskOptions<\n in out TRouter extends AnyRouter,\n in out TMaskFrom extends string,\n in out TMaskTo extends string,\n> {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouter, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRouter = RegisteredRouter,\n TMaskFrom extends string = string,\n TMaskTo extends string = '.',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n SearchParamOptions<TRouter, TFrom, TTo> &\n PathParamOptions<TRouter, TFrom, TTo>\n\nexport interface ToSubOptionsProps<\n in out TRouter extends AnyRouter = RegisteredRouter,\n in out TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n in out TTo extends string | undefined = '.',\n> {\n to?: ToPathOption<TRouter, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: FromPathOption<TRouter, TFrom> & {}\n}\n\nexport type ParamsReducerFn<\n in out TRouter extends AnyRouter,\n in out TParamVariant extends ParamVariant,\n in out TFrom,\n in out TTo,\n> = (\n current: Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>,\n) => Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n\ntype ParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n | (ParamsReducerFn<TRouter, TParamVariant, TFrom, TTo> & {})\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\nexport type ResolveRoute<\n TRouter extends AnyRouter,\n TFrom,\n TTo,\n TPath = ResolveRelativePath<TFrom, TTo>,\n> = TPath extends string\n ? TFrom extends TPath\n ? RouteByPath<TRouter['routeTree'], TPath>\n : RouteByToPath<TRouter, TPath>\n : never\n\ntype ResolveFromParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'\n\ntype ResolveFromAllParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchema<TRouter['routeTree']>\n\ntype ResolveFromParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n> = string extends TFrom\n ? ResolveFromAllParams<TRouter, TParamVariant>\n : RouteByPath<\n TRouter['routeTree'],\n TFrom\n >['types'][ResolveFromParamType<TParamVariant>]\n\ntype ResolveToParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'\n\ntype ResolveAllToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchemaInput<TRouter['routeTree']>\n\nexport type ResolveToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : string extends TPath\n ? ResolveAllToParams<TRouter, TParamVariant>\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? ResolveAllToParams<TRouter, TParamVariant>\n : ResolveRoute<\n TRouter,\n TFrom,\n TTo\n >['types'][ResolveToParamType<TParamVariant>]\n : never\n\ntype ResolveRelativeToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouter, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouter, TParamVariant, TFrom>,\n TToParams\n >\n\nexport interface MakeOptionalSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search?: true | (ParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {})\n}\n\nexport interface MakeOptionalPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params?: true | (ParamsReducer<TRouter, 'PATH', TFrom, TTo> & {})\n}\n\ntype MakeRequiredParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | (string extends TFrom\n ? never\n : ResolveFromParams<TRouter, TParamVariant, TFrom> extends WithoutEmpty<\n PickRequired<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n >\n ? true\n : never)\n | (ParamsReducer<TRouter, TParamVariant, TFrom, TTo> & {})\n\nexport interface MakeRequiredPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params: MakeRequiredParamsReducer<TRouter, 'PATH', TFrom, TTo> & {}\n}\n\nexport interface MakeRequiredSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search: MakeRequiredParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {}\n}\n\nexport type IsRequiredParams<TParams> =\n Record<never, never> extends TParams ? never : true\n\nexport type IsRequired<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n : never\n\nexport type SearchParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'SEARCH', TFrom, TTo> extends never\n ? MakeOptionalSearchParams<TRouter, TFrom, TTo>\n : MakeRequiredSearchParams<TRouter, TFrom, TTo>\n\nexport type PathParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'PATH', TFrom, TTo> extends never\n ? MakeOptionalPathParams<TRouter, TFrom, TTo>\n : MakeRequiredPathParams<TRouter, TFrom, TTo>\n\nexport type ToPathOption<\n TRouter extends AnyRouter = AnyRouter,\n TFrom extends string = string,\n TTo extends string | undefined = string,\n> =\n | CheckPath<TRouter, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport type CheckFromPath<\n TRouter extends AnyRouter,\n TPass,\n TFail,\n TFrom,\n> = string extends TFrom\n ? TPass\n : RouteByPath<TRouter['routeTree'], TFrom> extends never\n ? TFail\n : TPass\n\nexport type FromPathOption<TRouter extends AnyRouter, TFrom> =\n | CheckFromPath<\n TRouter,\n string extends TFrom ? TFrom & {} : TFrom,\n never,\n TFrom\n >\n | RoutePaths<TRouter['routeTree']>\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\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> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & LinkOptionsProps\n\nexport interface LinkOptionsProps {\n /**\n * The standard anchor tag target attribute\n */\n target?: HTMLAnchorElement['target']\n /**\n * Configurable options to determine if the link should be considered active or not\n * @default {exact:true,includeHash:true}\n */\n activeOptions?: ActiveOptions\n /**\n * The preloading strategy for this link\n * - `false` - No preloading\n * - `'intent'` - Preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n * - `'viewport'` - Preload the linked route when it enters the viewport\n */\n preload?: false | 'intent' | 'viewport'\n /**\n * When a preload strategy is set, this delays the preload by this many milliseconds.\n * If the user exits the link before this delay, the preload will be cancelled.\n */\n preloadDelay?: number\n /**\n * Control whether the link should be disabled or not\n * If set to `true`, the link will be rendered without an `href` attribute\n * @default false\n */\n disabled?: boolean\n}\n\nexport type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> =\n string extends ResolveRelativePath<TFrom, TTo>\n ? TPass\n : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths<\n TrailingSlashOptionByRouter<TRouter>\n >\n ? TPass\n : ResolveRoute<TRouter, TFrom, TTo> extends never\n ? TFail\n : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : undefined extends TTo\n ? TFrom\n : TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n 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 innerRef = useForwardedRef(forwardedRef)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\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 ...rest\n } = options\n\n const {\n // prevent these from being returned\n params: _params,\n search: _search,\n hash: _hash,\n state: _state,\n mask: _mask,\n ...propsSafeToSpread\n } = rest\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const type: 'internal' | 'external' = React.useMemo(() => {\n try {\n new URL(`${to}`)\n return 'external'\n } catch {}\n return 'internal'\n }, [to])\n\n // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({ select: (s) => s.location.search })\n\n const next = React.useMemo(\n () => router.buildLocation(options as any),\n [router, options, currentSearch],\n )\n const preload = React.useMemo(\n () => userPreload ?? router.options.defaultPreload,\n [router.options.defaultPreload, userPreload],\n )\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\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 ).split('/')\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n ).split('/')\n\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(\n s.location.search,\n next.search,\n !activeOptions?.exact,\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 }, [options, router])\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 { rootMargin: '100px' },\n { disabled: !!disabled || preload !== 'viewport' },\n )\n\n if (type === 'external') {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n type,\n href: to,\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 handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_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.buildAndCommitLocation({\n ...options,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n // The click handler\n const handleFocus = (_: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? {})\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.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 ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof JSX.IntrinsicElements\n ? JSX.IntrinsicElements[TComp]\n : React.PropsWithoutRef<\n TComp extends React.ComponentType<infer TProps> ? TProps : never\n > &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : never\n >\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<TComp> = <\n TRouter extends RegisteredRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\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 { type: _type, ref: innerRef, ...linkProps } = useLinkProps(rest, 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 (typeof _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: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFn<TComp> = <\n const TProps,\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n options: Constrain<\n TProps,\n LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n >,\n) => TProps\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":["useIntersectionObserver","flushSync"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAgkBA;AAEgB;AAUd;AACA;AACM;AAEA;AAAA;AAAA;;AAGmB;AACvB;AACA;AACS;AACK;AACd;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAGC;AAAA;AAAA;AAEI;AACA;AACF;AACC;AACD;AACH;AASC;AACA;AACE;AACG;AAAA;AACD;AACD;AAAA;AAIH;AAEN;AAAmB;AACwB;AACV;AAEjC;AAAsB;AACgB;AACO;AAE7C;AAGA;AAAgC;AAE5B;AACE;AAAkB;AACL;AACN;AACE;AAET;AACS;AAAA;AACT;AAEA;AAAyB;AACZ;AACJ;AAET;AAAsB;AACf;AACE;AAGT;AAAuC;AACH;AAEpC;AACS;AAAA;AACT;AAGE;AACF;AAAmB;AACN;AACN;AACW;AAElB;AACS;AAAA;AACT;AAGF;AACS;AAAyB;AAE3B;AAAA;AACT;AAGI;AACJ;AACE;AACA;AAA2B;AAC5B;AAGH;AAAwC;AAEpC;AACY;;AACZ;AACF;AACU;AAGZA;AAAA;AACE;AACA;AACsB;AAC2B;AAGnD;AACS;AAAA;AACF;AACE;AACL;AACM;AACqB;AACJ;AACI;AACN;AACQ;AACJ;AACA;AACU;AACA;AACA;AAAA;AAKjC;AACJ;AAOE;AAEAC;AACE;AAAuB;AAGzB;AACQ;AACN;AAAwB;AAK1B;AAA8B;AACzB;AACH;AACA;AACA;AACA;AACA;AACD;AACH;AAII;AACJ;AACA;AACY;;AACZ;AAGF;AAEM;AACJ;AACM;AAEN;AACE;AACE;AAAA;AAGU;AACV;AACU;;AACG;AACjB;AAGI;AACJ;AACM;AAEN;AACE;AACA;AAA6B;AAC/B;AAGF;;AAGI;AACA;AACE;AACA;AAAU;AACX;AAIC;AAKN;AAGA;AAA0B;AACxB;AACoB;AACE;AAKxB;AAAsB;AACjB;AACoB;AACE;AAGpB;AAAA;AACF;AACA;AACA;AAKsC;AACpC;AAC0C;AACA;AACU;AACA;AACK;AAClD;AACZ;AACgE;AACR;AACxC;AACR;AACW;AACnB;AACkE;AACH;AAEnE;AA2GO;AAGL;AACE;AAA2D;AAE/D;AAEO;AAAuC;AAE1C;AACM;AAEN;AAEoB;AACoC;AAIpD;AAGF;AAAiB;AAGnB;AAAa;AACW;AACtB;AACK;AACE;AACP;AACA;AAAA;AAGN;AAEA;AACS;AACT;AAgBa;AACJ;AACT;;;;;"}
package/dist/esm/link.js CHANGED
@@ -37,6 +37,15 @@ function useLinkProps(options, forwardedRef) {
37
37
  ignoreBlocker,
38
38
  ...rest
39
39
  } = options;
40
+ const {
41
+ // prevent these from being returned
42
+ params: _params,
43
+ search: _search,
44
+ hash: _hash,
45
+ state: _state,
46
+ mask: _mask,
47
+ ...propsSafeToSpread
48
+ } = rest;
40
49
  const type = React.useMemo(() => {
41
50
  try {
42
51
  new URL(`${to}`);
@@ -120,7 +129,7 @@ function useLinkProps(options, forwardedRef) {
120
129
  );
121
130
  if (type === "external") {
122
131
  return {
123
- ...rest,
132
+ ...propsSafeToSpread,
124
133
  ref: innerRef,
125
134
  type,
126
135
  href: to,
@@ -205,7 +214,7 @@ function useLinkProps(options, forwardedRef) {
205
214
  ...resolvedInactiveProps.style
206
215
  };
207
216
  return {
208
- ...rest,
217
+ ...propsSafeToSpread,
209
218
  ...resolvedActiveProps,
210
219
  ...resolvedInactiveProps,
211
220
  href: disabled ? void 0 : next.maskedLocation ? router.history.createHref(next.maskedLocation.href) : router.history.createHref(next.href),
@@ -235,7 +244,7 @@ function createLink(Comp) {
235
244
  const Link = React.forwardRef(
236
245
  (props, ref) => {
237
246
  const { _asChild, ...rest } = props;
238
- const { type, ref: innerRef, ...linkProps } = useLinkProps(rest, ref);
247
+ const { type: _type, ref: innerRef, ...linkProps } = useLinkProps(rest, ref);
239
248
  const children = typeof rest.children === "function" ? rest.children({
240
249
  isActive: linkProps["data-status"] === "active"
241
250
  }) : rest.children;
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","sources":["../../src/link.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport {\n deepEqual,\n functionalUpdate,\n useForwardedRef,\n useIntersectionObserver,\n} from './utils'\nimport { exactPathTest, removeTrailingSlash } from './path'\nimport type { ParsedLocation } from './location'\nimport type { HistoryState } from '@tanstack/history'\nimport type {\n AllParams,\n CatchAllPaths,\n CurrentPath,\n FullSearchSchema,\n FullSearchSchemaInput,\n ParentPath,\n RouteByPath,\n RouteByToPath,\n RoutePaths,\n RouteToPath,\n TrailingSlashOptionByRouter,\n} from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type {\n Constrain,\n Expand,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\nimport type { ReactNode } from 'react'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<\n T extends string,\n TAcc = never,\n> = T extends `${string}$${string}`\n ? T extends `${string}$${infer TPossiblyParam}`\n ? TPossiblyParam extends `${string}/${string}`\n ? TPossiblyParam extends `${infer TParam}/${infer TRest}`\n ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>\n : never\n : TPossiblyParam extends ''\n ? TAcc\n : TPossiblyParam | TAcc\n : TAcc\n : TAcc\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type AddTrailingSlash<T> = T extends `${string}/` ? T : `${T & string}/`\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T\n\nexport type ResolvePaths<TRouter extends AnyRouter, TSearchPath> =\n RouteByPath<\n TRouter['routeTree'],\n RemoveTrailingSlashes<TSearchPath>\n > extends never\n ? RouteToPath<TRouter, TRouter['routeTree']>\n : RouteToPath<\n TRouter,\n RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>\n >\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouter, TSearchPath>,\n TPrefix extends string = `${RemoveTrailingSlashes<TSearchPath>}/`,\n TFilteredPaths = TPaths & `${TPrefix}${string}`,\n> = TFilteredPaths extends `${TPrefix}${infer TRest}` ? TRest : never\n\nexport type SearchRelativePathAutoComplete<\n TRouter extends AnyRouter,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouter, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | (TResolvedPath extends ''\n ? never\n : `${TTo}/${ParentPath<TrailingSlashOptionByRouter<TRouter>>}`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = ResolveRelativePath<TFrom, TTo>,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n\nexport type AbsolutePathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouter, TFrom> extends ''\n ? never\n : CurrentPath<TrailingSlashOptionByRouter<TRouter>>)\n | (string extends TFrom\n ? ParentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : ParentPath<TrailingSlashOptionByRouter<TRouter>>)\n | RouteToPath<TRouter, TRouter['routeTree']>\n | (TFrom extends '/'\n ? never\n : string extends TFrom\n ? never\n : RemoveLeadingSlashes<SearchPaths<TRouter, TFrom>>)\n\nexport type RelativeToPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n> = string extends TFrom\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `.${string}`\n ? RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : AbsolutePathAutoComplete<TRouter, TFrom>\n\nexport type NavigateOptions<\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> = ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & NavigateOptionProps\n\nexport interface NavigateOptionProps {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n ignoreBlocker?: boolean\n}\n\nexport type ToOptions<\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> = ToSubOptions<TRouter, TFrom, TTo> & MaskOptions<TRouter, TMaskFrom, TMaskTo>\n\nexport interface MaskOptions<\n in out TRouter extends AnyRouter,\n in out TMaskFrom extends string,\n in out TMaskTo extends string,\n> {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouter, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRouter = RegisteredRouter,\n TMaskFrom extends string = string,\n TMaskTo extends string = '.',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n SearchParamOptions<TRouter, TFrom, TTo> &\n PathParamOptions<TRouter, TFrom, TTo>\n\nexport interface ToSubOptionsProps<\n in out TRouter extends AnyRouter = RegisteredRouter,\n in out TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n in out TTo extends string | undefined = '.',\n> {\n to?: ToPathOption<TRouter, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: FromPathOption<TRouter, TFrom> & {}\n}\n\nexport type ParamsReducerFn<\n in out TRouter extends AnyRouter,\n in out TParamVariant extends ParamVariant,\n in out TFrom,\n in out TTo,\n> = (\n current: Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>,\n) => Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n\ntype ParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n | (ParamsReducerFn<TRouter, TParamVariant, TFrom, TTo> & {})\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\nexport type ResolveRoute<\n TRouter extends AnyRouter,\n TFrom,\n TTo,\n TPath = ResolveRelativePath<TFrom, TTo>,\n> = TPath extends string\n ? TFrom extends TPath\n ? RouteByPath<TRouter['routeTree'], TPath>\n : RouteByToPath<TRouter, TPath>\n : never\n\ntype ResolveFromParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'\n\ntype ResolveFromAllParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchema<TRouter['routeTree']>\n\ntype ResolveFromParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n> = string extends TFrom\n ? ResolveFromAllParams<TRouter, TParamVariant>\n : RouteByPath<\n TRouter['routeTree'],\n TFrom\n >['types'][ResolveFromParamType<TParamVariant>]\n\ntype ResolveToParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'\n\ntype ResolveAllToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchemaInput<TRouter['routeTree']>\n\nexport type ResolveToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : string extends TPath\n ? ResolveAllToParams<TRouter, TParamVariant>\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? ResolveAllToParams<TRouter, TParamVariant>\n : ResolveRoute<\n TRouter,\n TFrom,\n TTo\n >['types'][ResolveToParamType<TParamVariant>]\n : never\n\ntype ResolveRelativeToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouter, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouter, TParamVariant, TFrom>,\n TToParams\n >\n\nexport interface MakeOptionalSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search?: true | (ParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {})\n}\n\nexport interface MakeOptionalPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params?: true | (ParamsReducer<TRouter, 'PATH', TFrom, TTo> & {})\n}\n\ntype MakeRequiredParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | (string extends TFrom\n ? never\n : ResolveFromParams<TRouter, TParamVariant, TFrom> extends WithoutEmpty<\n PickRequired<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n >\n ? true\n : never)\n | (ParamsReducer<TRouter, TParamVariant, TFrom, TTo> & {})\n\nexport interface MakeRequiredPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params: MakeRequiredParamsReducer<TRouter, 'PATH', TFrom, TTo> & {}\n}\n\nexport interface MakeRequiredSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search: MakeRequiredParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {}\n}\n\nexport type IsRequiredParams<TParams> =\n Record<never, never> extends TParams ? never : true\n\nexport type IsRequired<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n : never\n\nexport type SearchParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'SEARCH', TFrom, TTo> extends never\n ? MakeOptionalSearchParams<TRouter, TFrom, TTo>\n : MakeRequiredSearchParams<TRouter, TFrom, TTo>\n\nexport type PathParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'PATH', TFrom, TTo> extends never\n ? MakeOptionalPathParams<TRouter, TFrom, TTo>\n : MakeRequiredPathParams<TRouter, TFrom, TTo>\n\nexport type ToPathOption<\n TRouter extends AnyRouter = AnyRouter,\n TFrom extends string = string,\n TTo extends string | undefined = string,\n> =\n | CheckPath<TRouter, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport type CheckFromPath<\n TRouter extends AnyRouter,\n TPass,\n TFail,\n TFrom,\n> = string extends TFrom\n ? TPass\n : RouteByPath<TRouter['routeTree'], TFrom> extends never\n ? TFail\n : TPass\n\nexport type FromPathOption<TRouter extends AnyRouter, TFrom> =\n | CheckFromPath<\n TRouter,\n string extends TFrom ? TFrom & {} : TFrom,\n never,\n TFrom\n >\n | RoutePaths<TRouter['routeTree']>\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\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> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & LinkOptionsProps\n\nexport interface LinkOptionsProps {\n /**\n * The standard anchor tag target attribute\n */\n target?: HTMLAnchorElement['target']\n /**\n * Configurable options to determine if the link should be considered active or not\n * @default {exact:true,includeHash:true}\n */\n activeOptions?: ActiveOptions\n /**\n * The preloading strategy for this link\n * - `false` - No preloading\n * - `'intent'` - Preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n * - `'viewport'` - Preload the linked route when it enters the viewport\n */\n preload?: false | 'intent' | 'viewport'\n /**\n * When a preload strategy is set, this delays the preload by this many milliseconds.\n * If the user exits the link before this delay, the preload will be cancelled.\n */\n preloadDelay?: number\n /**\n * Control whether the link should be disabled or not\n * If set to `true`, the link will be rendered without an `href` attribute\n * @default false\n */\n disabled?: boolean\n}\n\nexport type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> =\n string extends ResolveRelativePath<TFrom, TTo>\n ? TPass\n : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths<\n TrailingSlashOptionByRouter<TRouter>\n >\n ? TPass\n : ResolveRoute<TRouter, TFrom, TTo> extends never\n ? TFail\n : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : undefined extends TTo\n ? TFrom\n : TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n 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 innerRef = useForwardedRef(forwardedRef)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\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 ...rest\n } = options\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const type: 'internal' | 'external' = React.useMemo(() => {\n try {\n new URL(`${to}`)\n return 'external'\n } catch {}\n return 'internal'\n }, [to])\n\n // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({ select: (s) => s.location.search })\n\n const next = React.useMemo(\n () => router.buildLocation(options as any),\n [router, options, currentSearch],\n )\n const preload = React.useMemo(\n () => userPreload ?? router.options.defaultPreload,\n [router.options.defaultPreload, userPreload],\n )\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\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 ).split('/')\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n ).split('/')\n\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(\n s.location.search,\n next.search,\n !activeOptions?.exact,\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 }, [options, router])\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 { rootMargin: '100px' },\n { disabled: !!disabled || preload !== 'viewport' },\n )\n\n if (type === 'external') {\n return {\n ...rest,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n type,\n href: to,\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 handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_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.buildAndCommitLocation({\n ...options,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n // The click handler\n const handleFocus = (_: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? {})\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...rest,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.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 ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof JSX.IntrinsicElements\n ? JSX.IntrinsicElements[TComp]\n : React.PropsWithoutRef<\n TComp extends React.ComponentType<infer TProps> ? TProps : never\n > &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : never\n >\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<TComp> = <\n TRouter extends RegisteredRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\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 { type, ref: innerRef, ...linkProps } = useLinkProps(rest, 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 (typeof _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: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFn<TComp> = <\n const TProps,\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n options: Constrain<\n TProps,\n LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n >,\n) => TProps\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":[],"mappings":";;;;;;;;AAgkBA;AAEgB;AAUd;AACA;AACM;AAEA;AAAA;AAAA;;AAGmB;AACvB;AACA;AACS;AACK;AACd;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AASC;AACA;AACE;AACG;AAAA;AACD;AACD;AAAA;AAIH;AAEN;AAAmB;AACwB;AACV;AAEjC;AAAsB;AACgB;AACO;AAE7C;AAGA;AAAgC;AAE5B;AACE;AAAkB;AACL;AACN;AACE;AAET;AACS;AAAA;AACT;AAEA;AAAyB;AACZ;AACJ;AAET;AAAsB;AACf;AACE;AAGT;AAAuC;AACH;AAEpC;AACS;AAAA;AACT;AAGE;AACF;AAAmB;AACN;AACN;AACW;AAElB;AACS;AAAA;AACT;AAGF;AACS;AAAyB;AAE3B;AAAA;AACT;AAGI;AACJ;AACE;AACA;AAA2B;AAC5B;AAGH;AAAwC;AAEpC;AACY;;AACZ;AACF;AACU;AAGZ;AAAA;AACE;AACA;AACsB;AAC2B;AAGnD;AACS;AAAA;AACF;AACE;AACL;AACM;AACqB;AACJ;AACI;AACN;AACQ;AACJ;AACA;AACU;AACA;AACA;AAAA;AAKjC;AACJ;AAOE;AAEA;AACE;AAAuB;AAGzB;AACQ;AACN;AAAwB;AAK1B;AAA8B;AACzB;AACH;AACA;AACA;AACA;AACA;AACD;AACH;AAII;AACJ;AACA;AACY;;AACZ;AAGF;AAEM;AACJ;AACM;AAEN;AACE;AACE;AAAA;AAGU;AACV;AACU;;AACG;AACjB;AAGI;AACJ;AACM;AAEN;AACE;AACA;AAA6B;AAC/B;AAGF;;AAGI;AACA;AACE;AACA;AAAU;AACX;AAIC;AAKN;AAGA;AAA0B;AACxB;AACoB;AACE;AAKxB;AAAsB;AACjB;AACoB;AACE;AAGpB;AAAA;AACF;AACA;AACA;AAKsC;AACpC;AAC0C;AACA;AACU;AACA;AACK;AAClD;AACZ;AACgE;AACR;AACxC;AACR;AACW;AACnB;AACkE;AACH;AAEnE;AA2GO;AAGL;AACE;AAA2D;AAE/D;AAEO;AAAuC;AAE1C;AACM;AAEN;AAEoB;AACoC;AAIpD;AAGF;AAAiB;AAGnB;AAAa;AACW;AACtB;AACK;AACE;AACP;AACA;AAAA;AAGN;AAEA;AACS;AACT;AAgBa;AACJ;AACT;;;;;;;"}
1
+ {"version":3,"file":"link.js","sources":["../../src/link.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport {\n deepEqual,\n functionalUpdate,\n useForwardedRef,\n useIntersectionObserver,\n} from './utils'\nimport { exactPathTest, removeTrailingSlash } from './path'\nimport type { ParsedLocation } from './location'\nimport type { HistoryState } from '@tanstack/history'\nimport type {\n AllParams,\n CatchAllPaths,\n CurrentPath,\n FullSearchSchema,\n FullSearchSchemaInput,\n ParentPath,\n RouteByPath,\n RouteByToPath,\n RoutePaths,\n RouteToPath,\n TrailingSlashOptionByRouter,\n} from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type {\n Constrain,\n Expand,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\nimport type { ReactNode } from 'react'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<\n T extends string,\n TAcc = never,\n> = T extends `${string}$${string}`\n ? T extends `${string}$${infer TPossiblyParam}`\n ? TPossiblyParam extends `${string}/${string}`\n ? TPossiblyParam extends `${infer TParam}/${infer TRest}`\n ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>\n : never\n : TPossiblyParam extends ''\n ? TAcc\n : TPossiblyParam | TAcc\n : TAcc\n : TAcc\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type AddTrailingSlash<T> = T extends `${string}/` ? T : `${T & string}/`\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/` ? R : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}` ? R : T\n\nexport type ResolvePaths<TRouter extends AnyRouter, TSearchPath> =\n RouteByPath<\n TRouter['routeTree'],\n RemoveTrailingSlashes<TSearchPath>\n > extends never\n ? RouteToPath<TRouter, TRouter['routeTree']>\n : RouteToPath<\n TRouter,\n RouteByPath<TRouter['routeTree'], RemoveTrailingSlashes<TSearchPath>>\n >\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouter, TSearchPath>,\n TPrefix extends string = `${RemoveTrailingSlashes<TSearchPath>}/`,\n TFilteredPaths = TPaths & `${TPrefix}${string}`,\n> = TFilteredPaths extends `${TPrefix}${infer TRest}` ? TRest : never\n\nexport type SearchRelativePathAutoComplete<\n TRouter extends AnyRouter,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouter, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | (TResolvedPath extends ''\n ? never\n : `${TTo}/${ParentPath<TrailingSlashOptionByRouter<TRouter>>}`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = ResolveRelativePath<TFrom, TTo>,\n> =\n | SearchRelativePathAutoComplete<TRouter, TTo, TResolvedPath>\n | CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n\nexport type AbsolutePathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? CurrentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouter, TFrom> extends ''\n ? never\n : CurrentPath<TrailingSlashOptionByRouter<TRouter>>)\n | (string extends TFrom\n ? ParentPath<TrailingSlashOptionByRouter<TRouter>>\n : TFrom extends `/`\n ? never\n : ParentPath<TrailingSlashOptionByRouter<TRouter>>)\n | RouteToPath<TRouter, TRouter['routeTree']>\n | (TFrom extends '/'\n ? never\n : string extends TFrom\n ? never\n : RemoveLeadingSlashes<SearchPaths<TRouter, TFrom>>)\n\nexport type RelativeToPathAutoComplete<\n TRouter extends AnyRouter,\n TFrom extends string,\n TTo extends string,\n> = string extends TFrom\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `.${string}`\n ? RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : AbsolutePathAutoComplete<TRouter, TFrom>\n\nexport type NavigateOptions<\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> = ToOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & NavigateOptionProps\n\nexport interface NavigateOptionProps {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n ignoreBlocker?: boolean\n}\n\nexport type ToOptions<\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> = ToSubOptions<TRouter, TFrom, TTo> & MaskOptions<TRouter, TMaskFrom, TMaskTo>\n\nexport interface MaskOptions<\n in out TRouter extends AnyRouter,\n in out TMaskFrom extends string,\n in out TMaskTo extends string,\n> {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouter, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRouter = RegisteredRouter,\n TMaskFrom extends string = string,\n TMaskTo extends string = '.',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n SearchParamOptions<TRouter, TFrom, TTo> &\n PathParamOptions<TRouter, TFrom, TTo>\n\nexport interface ToSubOptionsProps<\n in out TRouter extends AnyRouter = RegisteredRouter,\n in out TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n in out TTo extends string | undefined = '.',\n> {\n to?: ToPathOption<TRouter, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: FromPathOption<TRouter, TFrom> & {}\n}\n\nexport type ParamsReducerFn<\n in out TRouter extends AnyRouter,\n in out TParamVariant extends ParamVariant,\n in out TFrom,\n in out TTo,\n> = (\n current: Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>,\n) => Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n\ntype ParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>\n | (ParamsReducerFn<TRouter, TParamVariant, TFrom, TTo> & {})\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\nexport type ResolveRoute<\n TRouter extends AnyRouter,\n TFrom,\n TTo,\n TPath = ResolveRelativePath<TFrom, TTo>,\n> = TPath extends string\n ? TFrom extends TPath\n ? RouteByPath<TRouter['routeTree'], TPath>\n : RouteByToPath<TRouter, TPath>\n : never\n\ntype ResolveFromParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'\n\ntype ResolveFromAllParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchema<TRouter['routeTree']>\n\ntype ResolveFromParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n> = string extends TFrom\n ? ResolveFromAllParams<TRouter, TParamVariant>\n : RouteByPath<\n TRouter['routeTree'],\n TFrom\n >['types'][ResolveFromParamType<TParamVariant>]\n\ntype ResolveToParamType<TParamVariant extends ParamVariant> =\n TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'\n\ntype ResolveAllToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'PATH'\n ? AllParams<TRouter['routeTree']>\n : FullSearchSchemaInput<TRouter['routeTree']>\n\nexport type ResolveToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : string extends TPath\n ? ResolveAllToParams<TRouter, TParamVariant>\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? ResolveAllToParams<TRouter, TParamVariant>\n : ResolveRoute<\n TRouter,\n TFrom,\n TTo\n >['types'][ResolveToParamType<TParamVariant>]\n : never\n\ntype ResolveRelativeToParams<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouter, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouter, TParamVariant, TFrom>,\n TToParams\n >\n\nexport interface MakeOptionalSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search?: true | (ParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {})\n}\n\nexport interface MakeOptionalPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params?: true | (ParamsReducer<TRouter, 'PATH', TFrom, TTo> & {})\n}\n\ntype MakeRequiredParamsReducer<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n | (string extends TFrom\n ? never\n : ResolveFromParams<TRouter, TParamVariant, TFrom> extends WithoutEmpty<\n PickRequired<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n >\n ? true\n : never)\n | (ParamsReducer<TRouter, TParamVariant, TFrom, TTo> & {})\n\nexport interface MakeRequiredPathParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n params: MakeRequiredParamsReducer<TRouter, 'PATH', TFrom, TTo> & {}\n}\n\nexport interface MakeRequiredSearchParams<\n in out TRouter extends AnyRouter,\n in out TFrom,\n in out TTo,\n> {\n search: MakeRequiredParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {}\n}\n\nexport type IsRequiredParams<TParams> =\n Record<never, never> extends TParams ? never : true\n\nexport type IsRequired<\n TRouter extends AnyRouter,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> =\n ResolveRelativePath<TFrom, TTo> extends infer TPath\n ? undefined extends TPath\n ? never\n : TPath extends CatchAllPaths<TrailingSlashOptionByRouter<TRouter>>\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>\n >\n : never\n\nexport type SearchParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'SEARCH', TFrom, TTo> extends never\n ? MakeOptionalSearchParams<TRouter, TFrom, TTo>\n : MakeRequiredSearchParams<TRouter, TFrom, TTo>\n\nexport type PathParamOptions<TRouter extends AnyRouter, TFrom, TTo> =\n IsRequired<TRouter, 'PATH', TFrom, TTo> extends never\n ? MakeOptionalPathParams<TRouter, TFrom, TTo>\n : MakeRequiredPathParams<TRouter, TFrom, TTo>\n\nexport type ToPathOption<\n TRouter extends AnyRouter = AnyRouter,\n TFrom extends string = string,\n TTo extends string | undefined = string,\n> =\n | CheckPath<TRouter, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport type CheckFromPath<\n TRouter extends AnyRouter,\n TPass,\n TFail,\n TFrom,\n> = string extends TFrom\n ? TPass\n : RouteByPath<TRouter['routeTree'], TFrom> extends never\n ? TFail\n : TPass\n\nexport type FromPathOption<TRouter extends AnyRouter, TFrom> =\n | CheckFromPath<\n TRouter,\n string extends TFrom ? TFrom & {} : TFrom,\n never,\n TFrom\n >\n | RoutePaths<TRouter['routeTree']>\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\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> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & LinkOptionsProps\n\nexport interface LinkOptionsProps {\n /**\n * The standard anchor tag target attribute\n */\n target?: HTMLAnchorElement['target']\n /**\n * Configurable options to determine if the link should be considered active or not\n * @default {exact:true,includeHash:true}\n */\n activeOptions?: ActiveOptions\n /**\n * The preloading strategy for this link\n * - `false` - No preloading\n * - `'intent'` - Preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n * - `'viewport'` - Preload the linked route when it enters the viewport\n */\n preload?: false | 'intent' | 'viewport'\n /**\n * When a preload strategy is set, this delays the preload by this many milliseconds.\n * If the user exits the link before this delay, the preload will be cancelled.\n */\n preloadDelay?: number\n /**\n * Control whether the link should be disabled or not\n * If set to `true`, the link will be rendered without an `href` attribute\n * @default false\n */\n disabled?: boolean\n}\n\nexport type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> =\n string extends ResolveRelativePath<TFrom, TTo>\n ? TPass\n : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths<\n TrailingSlashOptionByRouter<TRouter>\n >\n ? TPass\n : ResolveRoute<TRouter, TFrom, TTo> extends never\n ? TFail\n : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : undefined extends TTo\n ? TFrom\n : TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n 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 innerRef = useForwardedRef(forwardedRef)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n to,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\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 ...rest\n } = options\n\n const {\n // prevent these from being returned\n params: _params,\n search: _search,\n hash: _hash,\n state: _state,\n mask: _mask,\n ...propsSafeToSpread\n } = rest\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const type: 'internal' | 'external' = React.useMemo(() => {\n try {\n new URL(`${to}`)\n return 'external'\n } catch {}\n return 'internal'\n }, [to])\n\n // subscribe to search params to re-build location if it changes\n const currentSearch = useRouterState({ select: (s) => s.location.search })\n\n const next = React.useMemo(\n () => router.buildLocation(options as any),\n [router, options, currentSearch],\n )\n const preload = React.useMemo(\n () => userPreload ?? router.options.defaultPreload,\n [router.options.defaultPreload, userPreload],\n )\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\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 ).split('/')\n const nextPathSplit = removeTrailingSlash(\n next.pathname,\n router.basepath,\n ).split('/')\n\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(\n s.location.search,\n next.search,\n !activeOptions?.exact,\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 }, [options, router])\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 { rootMargin: '100px' },\n { disabled: !!disabled || preload !== 'viewport' },\n )\n\n if (type === 'external') {\n return {\n ...propsSafeToSpread,\n ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],\n type,\n href: to,\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 handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_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.buildAndCommitLocation({\n ...options,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n ignoreBlocker,\n })\n }\n }\n\n // The click handler\n const handleFocus = (_: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? (functionalUpdate(activeProps as any, {}) ?? {})\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...propsSafeToSpread,\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.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 ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof JSX.IntrinsicElements\n ? JSX.IntrinsicElements[TComp]\n : React.PropsWithoutRef<\n TComp extends React.ComponentType<infer TProps> ? TProps : never\n > &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : never\n >\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<TComp> = <\n TRouter extends RegisteredRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\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 { type: _type, ref: innerRef, ...linkProps } = useLinkProps(rest, 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 (typeof _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: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFn<TComp> = <\n const TProps,\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n>(\n options: Constrain<\n TProps,\n LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n >,\n) => TProps\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"names":[],"mappings":";;;;;;;;AAgkBA;AAEgB;AAUd;AACA;AACM;AAEA;AAAA;AAAA;;AAGmB;AACvB;AACA;AACS;AACK;AACd;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAGC;AAAA;AAAA;AAEI;AACA;AACF;AACC;AACD;AACH;AASC;AACA;AACE;AACG;AAAA;AACD;AACD;AAAA;AAIH;AAEN;AAAmB;AACwB;AACV;AAEjC;AAAsB;AACgB;AACO;AAE7C;AAGA;AAAgC;AAE5B;AACE;AAAkB;AACL;AACN;AACE;AAET;AACS;AAAA;AACT;AAEA;AAAyB;AACZ;AACJ;AAET;AAAsB;AACf;AACE;AAGT;AAAuC;AACH;AAEpC;AACS;AAAA;AACT;AAGE;AACF;AAAmB;AACN;AACN;AACW;AAElB;AACS;AAAA;AACT;AAGF;AACS;AAAyB;AAE3B;AAAA;AACT;AAGI;AACJ;AACE;AACA;AAA2B;AAC5B;AAGH;AAAwC;AAEpC;AACY;;AACZ;AACF;AACU;AAGZ;AAAA;AACE;AACA;AACsB;AAC2B;AAGnD;AACS;AAAA;AACF;AACE;AACL;AACM;AACqB;AACJ;AACI;AACN;AACQ;AACJ;AACA;AACU;AACA;AACA;AAAA;AAKjC;AACJ;AAOE;AAEA;AACE;AAAuB;AAGzB;AACQ;AACN;AAAwB;AAK1B;AAA8B;AACzB;AACH;AACA;AACA;AACA;AACA;AACD;AACH;AAII;AACJ;AACA;AACY;;AACZ;AAGF;AAEM;AACJ;AACM;AAEN;AACE;AACE;AAAA;AAGU;AACV;AACU;;AACG;AACjB;AAGI;AACJ;AACM;AAEN;AACE;AACA;AAA6B;AAC/B;AAGF;;AAGI;AACA;AACE;AACA;AAAU;AACX;AAIC;AAKN;AAGA;AAA0B;AACxB;AACoB;AACE;AAKxB;AAAsB;AACjB;AACoB;AACE;AAGpB;AAAA;AACF;AACA;AACA;AAKsC;AACpC;AAC0C;AACA;AACU;AACA;AACK;AAClD;AACZ;AACgE;AACR;AACxC;AACR;AACW;AACnB;AACkE;AACH;AAEnE;AA2GO;AAGL;AACE;AAA2D;AAE/D;AAEO;AAAuC;AAE1C;AACM;AAEN;AAEoB;AACoC;AAIpD;AAGF;AAAiB;AAGnB;AAAa;AACW;AACtB;AACK;AACE;AACP;AACA;AAAA;AAGN;AAEA;AACS;AACT;AAgBa;AACJ;AACT;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.70.1",
3
+ "version": "1.70.2",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/link.tsx CHANGED
@@ -617,6 +617,16 @@ export function useLinkProps<
617
617
  ...rest
618
618
  } = options
619
619
 
620
+ const {
621
+ // prevent these from being returned
622
+ params: _params,
623
+ search: _search,
624
+ hash: _hash,
625
+ state: _state,
626
+ mask: _mask,
627
+ ...propsSafeToSpread
628
+ } = rest
629
+
620
630
  // If this link simply reloads the current route,
621
631
  // make sure it has a new key so it will trigger a data refresh
622
632
 
@@ -717,7 +727,7 @@ export function useLinkProps<
717
727
 
718
728
  if (type === 'external') {
719
729
  return {
720
- ...rest,
730
+ ...propsSafeToSpread,
721
731
  ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],
722
732
  type,
723
733
  href: to,
@@ -837,7 +847,7 @@ export function useLinkProps<
837
847
  }
838
848
 
839
849
  return {
840
- ...rest,
850
+ ...propsSafeToSpread,
841
851
  ...resolvedActiveProps,
842
852
  ...resolvedInactiveProps,
843
853
  href: disabled
@@ -980,7 +990,7 @@ export function createLink<const TComp>(
980
990
  export const Link: LinkComponent<'a'> = React.forwardRef<Element, any>(
981
991
  (props, ref) => {
982
992
  const { _asChild, ...rest } = props
983
- const { type, ref: innerRef, ...linkProps } = useLinkProps(rest, ref)
993
+ const { type: _type, ref: innerRef, ...linkProps } = useLinkProps(rest, ref)
984
994
 
985
995
  const children =
986
996
  typeof rest.children === 'function'