@tanstack/react-router 1.91.1 → 1.91.3
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 +7 -5
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/router.cjs +28 -17
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/esm/link.js +7 -5
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/router.js +28 -17
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/link.tsx +8 -6
- package/src/router.ts +34 -20
package/dist/cjs/link.cjs
CHANGED
|
@@ -90,10 +90,12 @@ function useLinkProps(options, forwardedRef) {
|
|
|
90
90
|
() => router.buildLocation(options),
|
|
91
91
|
[router, options, currentSearch]
|
|
92
92
|
);
|
|
93
|
-
const preload = React__namespace.useMemo(
|
|
94
|
-
()
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
const preload = React__namespace.useMemo(() => {
|
|
94
|
+
if (options.reloadDocument) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
return userPreload ?? router.options.defaultPreload;
|
|
98
|
+
}, [router.options.defaultPreload, userPreload, options.reloadDocument]);
|
|
97
99
|
const preloadDelay = userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0;
|
|
98
100
|
const isActive = useRouterState.useRouterState({
|
|
99
101
|
select: (s) => {
|
|
@@ -194,7 +196,7 @@ function useLinkProps(options, forwardedRef) {
|
|
|
194
196
|
unsub();
|
|
195
197
|
setIsTransitioning(false);
|
|
196
198
|
});
|
|
197
|
-
router.
|
|
199
|
+
return router.navigate({
|
|
198
200
|
...options,
|
|
199
201
|
replace,
|
|
200
202
|
resetScroll,
|
package/dist/cjs/link.cjs.map
CHANGED
|
@@ -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 useLayoutEffect,\n} from './utils'\nimport { exactPathTest, removeTrailingSlash } from './path'\nimport { useMatch } from './useMatch'\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 {\n AnyRouter,\n RegisteredRouter,\n ViewTransitionOptions,\n} from './router'\nimport type {\n Constrain,\n ConstrainLiteral,\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 ParsePathParams<T extends string, TAcc = never> = T &\n `${string}$${string}` extends never\n ? TAcc\n : T extends `${string}$${infer TPossiblyParam}`\n ? TPossiblyParam extends ''\n ? TAcc\n : TPossiblyParam & `${string}/${string}` extends never\n ? TPossiblyParam | TAcc\n : TPossiblyParam extends `${infer TParam}/${infer TRest}`\n ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>\n : never\n : TAcc\n\nexport type AddTrailingSlash<T> = T & `${string}/` extends never\n ? `${T & string}/`\n : T\n\nexport type RemoveTrailingSlashes<T> = T & `${string}/` extends never\n ? T\n : T extends `${infer R}/`\n ? R\n : T\n\nexport type AddLeadingSlash<T> = T & `/${string}` extends never\n ? `/${T & string}`\n : T\n\nexport type RemoveLeadingSlashes<T> = T & `/${string}` extends never\n ? T\n : T extends `/${infer R}`\n ? R\n : T\n\nexport type FindDescendantPaths<\n TRouter extends AnyRouter,\n TPrefix extends string,\n> = `${TPrefix}${string}` & RouteToPath<TRouter>\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TPrefix extends string,\n TPaths = FindDescendantPaths<TRouter, TPrefix>,\n> = TPaths 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 = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\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 : FindDescendantPaths<TRouter, TFrom> extends never\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>\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 TTo\n ? string\n : string extends TFrom\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : TTo & `..${string}` extends never\n ? TTo & `.${string}` extends never\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : RelativeToParentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\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 // if set to `true`, the router will scroll the element with an id matching the hash into view with default ScrollIntoViewOptions.\n // if set to `false`, the router will not scroll the element with an id matching the hash into view.\n // if set to `ScrollIntoViewOptions`, the router will scroll the element with an id matching the hash into view with the provided options.\n hashScrollIntoView?: boolean | ScrollIntoViewOptions\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 // if set to `ViewTransitionOptions`, the router will pass the `types` field to document.startViewTransition({update: fn, types: viewTransition.types}) call\n viewTransition?: boolean | ViewTransitionOptions\n ignoreBlocker?: boolean\n reloadDocument?: boolean\n href?: string\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 TRouter extends AnyRouter = RegisteredRouter,\n TMaskFrom extends string = string,\n TMaskTo extends string = '.',\n> = ToSubOptions<TRouter, 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> = ConstrainLiteral<\n TTo,\n RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n>\n\nexport type FromPathOption<TRouter extends AnyRouter, TFrom> = ConstrainLiteral<\n TFrom,\n RoutePaths<TRouter['routeTree']>\n>\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n explicitUndefined?: 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' | 'render'\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\ntype JoinPath<TLeft extends string, TRight extends string> = TRight extends ''\n ? TLeft\n : TLeft extends ''\n ? TRight\n : `${RemoveTrailingSlashes<TLeft>}/${RemoveLeadingSlashes<TRight>}`\n\ntype RemoveLastSegment<\n T extends string,\n TAcc extends string = '',\n> = T extends `${infer TSegment}/${infer TRest}`\n ? TRest & `${string}/${string}` extends never\n ? `${TAcc}${TSegment}`\n : RemoveLastSegment<TRest, `${TAcc}${TSegment}/`>\n : TAcc\n\nexport type ResolveCurrentPath<TFrom, TTo> = TTo extends '.'\n ? TFrom\n : TTo extends './'\n ? AddTrailingSlash<TFrom>\n : TTo & `./${string}` extends never\n ? never\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : never\n\nexport type ResolveParentPath<TFrom extends string, TTo> = TTo extends '../'\n ? RemoveLastSegment<TFrom>\n : TTo & `..${string}` extends never\n ? never\n : TTo extends `..${infer ToRest}`\n ? ResolveRelativePath<\n RemoveLastSegment<TFrom>,\n RemoveLeadingSlashes<ToRest>\n >\n : never\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 & `..${string}` extends never\n ? TTo & `.${string}` extends never\n ? TTo & `/${string}` extends never\n ? AddLeadingSlash<JoinPath<TFrom, TTo>>\n : TTo\n : ResolveCurrentPath<TFrom, TTo>\n : ResolveParentPath<TFrom, 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 hasRenderFetched = React.useRef(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 hashScrollIntoView,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ignoreBlocker,\n ...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 reloadDocument: _reloadDocument,\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({\n select: (s) => s.location.search,\n structuralSharing: true as any,\n })\n\n // In the rare event that the user bypasses type-safety and doesn't supply a `from`\n // we'll use the current route as the `from` location so relative routing works as expected\n const parentRouteId = useMatch({ strict: false, select: (s) => s.pathname })\n\n // Use it as the default `from` location\n options = {\n from: parentRouteId,\n ...options,\n }\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(s.location.search, next.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n return s.location.hash === next.hash\n }\n return true\n },\n })\n\n const doPreload = React.useCallback(() => {\n router.preloadRoute(options as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [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 useLayoutEffect(() => {\n if (hasRenderFetched.current) {\n return\n }\n if (!disabled && preload === 'render') {\n doPreload()\n hasRenderFetched.current = true\n }\n }, [disabled, doPreload, preload])\n\n 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 hashScrollIntoView,\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 React.JSX.IntrinsicElements\n ? React.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 AnyRouter = 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","useLayoutEffect","flushSync"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyiBA;AAEgB;AAUd;AACA;AACM;AACA;AAEA;AAAA;AAAA;;AAGmB;AACvB;AACA;AACS;AACK;AACd;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAGC;AAAA;AAAA;AAEI;AACA;AACF;AACC;AACD;AACU;AACb;AASC;AACA;AACE;AACG;AAAA;AACD;AACD;AAAA;AAIT;AAAqC;AACT;AACP;AAKf;AAGI;AAAA;AACF;AACH;AAGL;AAAmB;AACwB;AACV;AAEjC;AAAsB;AACgB;AACO;AAE7C;AAGA;AAAgC;AAE5B;AACE;AAAkB;AACL;AACN;AACE;AAET;AACS;AAAA;AAAA;AAGT;AAAyB;AACZ;AACJ;AAET;AAAsB;AACf;AACE;AAGT;AAAuC;AACH;AAEpC;AACS;AAAA;AAAA;AAIP;AACF;AAA6D;AAClC;AACQ;AAEnC;AACS;AAAA;AAAA;AAIX;AACS;AAAyB;AAE3B;AAAA;AAAA;AAIL;AACJ;AACE;AACA;AAA2B;AAC5B;AAGH;AAAwC;AAEpC;AACY;AAAA;AAAA;AAEd;AACU;AAGZA;AAAA;AACE;AACA;AACsB;AAC8B;AAGtDC;AACE;AACE;AAAA;AAEE;AACQ;AACV;AAA2B;AAAA;AAI/B;AACS;AAAA;AACF;AACE;AACL;AACM;AACqB;AACJ;AACI;AACN;AACQ;AACJ;AACA;AACU;AACA;AACA;AACrC;AAII;AACJ;AAOE;AAEAC;AACE;AAAuB;AAGzB;AACQ;AACN;AAAwB;AAK1B;AAA8B;AACzB;AACH;AACA;AACA;AACA;AACA;AACA;AACD;AAAA;AAKC;AACJ;AACA;AACY;AAAA;AAAA;AAId;AAEM;AACJ;AACM;AAEN;AACE;AACE;AAAA;AAGU;AACV;AACU;AAAA;AACG;AAAA;AAIb;AACJ;AACM;AAEN;AACE;AACA;AAA6B;AAAA;AAIjC;;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;AACF;AAEJ;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 useLayoutEffect,\n} from './utils'\nimport { exactPathTest, removeTrailingSlash } from './path'\nimport { useMatch } from './useMatch'\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 {\n AnyRouter,\n RegisteredRouter,\n ViewTransitionOptions,\n} from './router'\nimport type {\n Constrain,\n ConstrainLiteral,\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 ParsePathParams<T extends string, TAcc = never> = T &\n `${string}$${string}` extends never\n ? TAcc\n : T extends `${string}$${infer TPossiblyParam}`\n ? TPossiblyParam extends ''\n ? TAcc\n : TPossiblyParam & `${string}/${string}` extends never\n ? TPossiblyParam | TAcc\n : TPossiblyParam extends `${infer TParam}/${infer TRest}`\n ? ParsePathParams<TRest, TParam extends '' ? TAcc : TParam | TAcc>\n : never\n : TAcc\n\nexport type AddTrailingSlash<T> = T & `${string}/` extends never\n ? `${T & string}/`\n : T\n\nexport type RemoveTrailingSlashes<T> = T & `${string}/` extends never\n ? T\n : T extends `${infer R}/`\n ? R\n : T\n\nexport type AddLeadingSlash<T> = T & `/${string}` extends never\n ? `/${T & string}`\n : T\n\nexport type RemoveLeadingSlashes<T> = T & `/${string}` extends never\n ? T\n : T extends `/${infer R}`\n ? R\n : T\n\nexport type FindDescendantPaths<\n TRouter extends AnyRouter,\n TPrefix extends string,\n> = `${TPrefix}${string}` & RouteToPath<TRouter>\n\nexport type SearchPaths<\n TRouter extends AnyRouter,\n TPrefix extends string,\n TPaths = FindDescendantPaths<TRouter, TPrefix>,\n> = TPaths 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 = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\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 : FindDescendantPaths<TRouter, TFrom> extends never\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>\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 TTo\n ? string\n : string extends TFrom\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : TTo & `..${string}` extends never\n ? TTo & `.${string}` extends never\n ? AbsolutePathAutoComplete<TRouter, TFrom>\n : RelativeToCurrentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : RelativeToParentPathAutoComplete<\n TRouter,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\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 // if set to `true`, the router will scroll the element with an id matching the hash into view with default ScrollIntoViewOptions.\n // if set to `false`, the router will not scroll the element with an id matching the hash into view.\n // if set to `ScrollIntoViewOptions`, the router will scroll the element with an id matching the hash into view with the provided options.\n hashScrollIntoView?: boolean | ScrollIntoViewOptions\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 // if set to `ViewTransitionOptions`, the router will pass the `types` field to document.startViewTransition({update: fn, types: viewTransition.types}) call\n viewTransition?: boolean | ViewTransitionOptions\n ignoreBlocker?: boolean\n reloadDocument?: boolean\n href?: string\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 TRouter extends AnyRouter = RegisteredRouter,\n TMaskFrom extends string = string,\n TMaskTo extends string = '.',\n> = ToSubOptions<TRouter, 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> = ConstrainLiteral<\n TTo,\n RelativeToPathAutoComplete<\n TRouter,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n>\n\nexport type FromPathOption<TRouter extends AnyRouter, TFrom> = ConstrainLiteral<\n TFrom,\n RoutePaths<TRouter['routeTree']>\n>\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n explicitUndefined?: 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' | 'render'\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\ntype JoinPath<TLeft extends string, TRight extends string> = TRight extends ''\n ? TLeft\n : TLeft extends ''\n ? TRight\n : `${RemoveTrailingSlashes<TLeft>}/${RemoveLeadingSlashes<TRight>}`\n\ntype RemoveLastSegment<\n T extends string,\n TAcc extends string = '',\n> = T extends `${infer TSegment}/${infer TRest}`\n ? TRest & `${string}/${string}` extends never\n ? `${TAcc}${TSegment}`\n : RemoveLastSegment<TRest, `${TAcc}${TSegment}/`>\n : TAcc\n\nexport type ResolveCurrentPath<TFrom, TTo> = TTo extends '.'\n ? TFrom\n : TTo extends './'\n ? AddTrailingSlash<TFrom>\n : TTo & `./${string}` extends never\n ? never\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : never\n\nexport type ResolveParentPath<TFrom extends string, TTo> = TTo extends '../'\n ? RemoveLastSegment<TFrom>\n : TTo & `..${string}` extends never\n ? never\n : TTo extends `..${infer ToRest}`\n ? ResolveRelativePath<\n RemoveLastSegment<TFrom>,\n RemoveLeadingSlashes<ToRest>\n >\n : never\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 & `..${string}` extends never\n ? TTo & `.${string}` extends never\n ? TTo & `/${string}` extends never\n ? AddLeadingSlash<JoinPath<TFrom, TTo>>\n : TTo\n : ResolveCurrentPath<TFrom, TTo>\n : ResolveParentPath<TFrom, 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 hasRenderFetched = React.useRef(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 hashScrollIntoView,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ignoreBlocker,\n ...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 reloadDocument: _reloadDocument,\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({\n select: (s) => s.location.search,\n structuralSharing: true as any,\n })\n\n // In the rare event that the user bypasses type-safety and doesn't supply a `from`\n // we'll use the current route as the `from` location so relative routing works as expected\n const parentRouteId = useMatch({ strict: false, select: (s) => s.pathname })\n\n // Use it as the default `from` location\n options = {\n from: parentRouteId,\n ...options,\n }\n\n const next = React.useMemo(\n () => router.buildLocation(options as any),\n [router, options, currentSearch],\n )\n const preload = React.useMemo(() => {\n if (options.reloadDocument) {\n return false\n }\n return userPreload ?? router.options.defaultPreload\n }, [router.options.defaultPreload, userPreload, options.reloadDocument])\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(s.location.search, next.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n return s.location.hash === next.hash\n }\n return true\n },\n })\n\n const doPreload = React.useCallback(() => {\n router.preloadRoute(options as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }, [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 useLayoutEffect(() => {\n if (hasRenderFetched.current) {\n return\n }\n if (!disabled && preload === 'render') {\n doPreload()\n hasRenderFetched.current = true\n }\n }, [disabled, doPreload, preload])\n\n 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 return router.navigate({\n ...options,\n replace,\n resetScroll,\n hashScrollIntoView,\n startTransition,\n viewTransition,\n ignoreBlocker,\n } as any)\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 React.JSX.IntrinsicElements\n ? React.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 AnyRouter = 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","useLayoutEffect","flushSync"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyiBA;AAEgB;AAUd;AACA;AACM;AACA;AAEA;AAAA;AAAA;;AAGmB;AACvB;AACA;AACS;AACK;AACd;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAGC;AAAA;AAAA;AAEI;AACA;AACF;AACC;AACD;AACU;AACb;AASC;AACA;AACE;AACG;AAAA;AACD;AACD;AAAA;AAIT;AAAqC;AACT;AACP;AAKf;AAGI;AAAA;AACF;AACH;AAGL;AAAmB;AACwB;AACV;AAE3B;AACJ;AACS;AAAA;AAEF;AAA8B;AAEvC;AAGA;AAAgC;AAE5B;AACE;AAAkB;AACL;AACN;AACE;AAET;AACS;AAAA;AAAA;AAGT;AAAyB;AACZ;AACJ;AAET;AAAsB;AACf;AACE;AAGT;AAAuC;AACH;AAEpC;AACS;AAAA;AAAA;AAIP;AACF;AAA6D;AAClC;AACQ;AAEnC;AACS;AAAA;AAAA;AAIX;AACS;AAAyB;AAE3B;AAAA;AAAA;AAIL;AACJ;AACE;AACA;AAA2B;AAC5B;AAGH;AAAwC;AAEpC;AACY;AAAA;AAAA;AAEd;AACU;AAGZA;AAAA;AACE;AACA;AACsB;AAC8B;AAGtDC;AACE;AACE;AAAA;AAEE;AACQ;AACV;AAA2B;AAAA;AAI/B;AACS;AAAA;AACF;AACE;AACL;AACM;AACqB;AACJ;AACI;AACN;AACQ;AACJ;AACA;AACU;AACA;AACA;AACrC;AAII;AACJ;AAOE;AAEAC;AACE;AAAuB;AAGzB;AACQ;AACN;AAAwB;AAK1B;AAAuB;AAClB;AACH;AACA;AACA;AACA;AACA;AACA;AACM;AAAA;AAKN;AACJ;AACA;AACY;AAAA;AAAA;AAId;AAEM;AACJ;AACM;AAEN;AACE;AACE;AAAA;AAGU;AACV;AACU;AAAA;AACG;AAAA;AAIb;AACJ;AACM;AAEN;AACE;AACA;AAA6B;AAAA;AAIjC;;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;AACF;AAEJ;AAEA;AACS;AACT;AAgBa;AACJ;AACT;;;;;"}
|
package/dist/cjs/router.cjs
CHANGED
|
@@ -1570,8 +1570,13 @@ ${script}\`)` : ""}; if (typeof __TSR__ !== 'undefined') __TSR__.cleanScripts()<
|
|
|
1570
1570
|
return;
|
|
1571
1571
|
});
|
|
1572
1572
|
const matches = [];
|
|
1573
|
+
const getParentContext = (parentMatch) => {
|
|
1574
|
+
const parentMatchId = parentMatch == null ? void 0 : parentMatch.id;
|
|
1575
|
+
const parentContext = !parentMatchId ? this.options.context ?? {} : parentMatch.context ?? this.options.context ?? {};
|
|
1576
|
+
return parentContext;
|
|
1577
|
+
};
|
|
1573
1578
|
matchedRoutes.forEach((route, index) => {
|
|
1574
|
-
var _a, _b, _c, _d
|
|
1579
|
+
var _a, _b, _c, _d;
|
|
1575
1580
|
const parentMatch = matches[index - 1];
|
|
1576
1581
|
const [preMatchSearch, searchError] = (() => {
|
|
1577
1582
|
const parentSearch = (parentMatch == null ? void 0 : parentMatch.search) ?? next.search;
|
|
@@ -1654,17 +1659,8 @@ ${script}\`)` : ""}; if (typeof __TSR__ !== 'undefined') __TSR__.cleanScripts()<
|
|
|
1654
1659
|
fullPath: route.fullPath
|
|
1655
1660
|
};
|
|
1656
1661
|
}
|
|
1657
|
-
const headFnContent = (_d = (_c = route.options).head) == null ? void 0 : _d.call(_c, {
|
|
1658
|
-
matches,
|
|
1659
|
-
match,
|
|
1660
|
-
params: match.params,
|
|
1661
|
-
loaderData: match.loaderData ?? void 0
|
|
1662
|
-
});
|
|
1663
|
-
match.links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1664
|
-
match.scripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1665
|
-
match.meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1666
1662
|
if (match.status === "success") {
|
|
1667
|
-
match.headers = (
|
|
1663
|
+
match.headers = (_d = (_c = route.options).headers) == null ? void 0 : _d.call(_c, {
|
|
1668
1664
|
loaderData: match.loaderData
|
|
1669
1665
|
});
|
|
1670
1666
|
}
|
|
@@ -1672,18 +1668,25 @@ ${script}\`)` : ""}; if (typeof __TSR__ !== 'undefined') __TSR__.cleanScripts()<
|
|
|
1672
1668
|
match.globalNotFound = globalNotFoundRouteId === route.id;
|
|
1673
1669
|
}
|
|
1674
1670
|
match.searchError = searchError;
|
|
1675
|
-
const
|
|
1676
|
-
const parentContext = !parentMatchId ? this.options.context ?? {} : parentMatch.context ?? this.options.context ?? {};
|
|
1671
|
+
const parentContext = getParentContext(parentMatch);
|
|
1677
1672
|
match.context = {
|
|
1678
1673
|
...parentContext,
|
|
1679
1674
|
...match.__routeContext,
|
|
1680
1675
|
...match.__beforeLoadContext
|
|
1681
1676
|
};
|
|
1677
|
+
matches.push(match);
|
|
1678
|
+
});
|
|
1679
|
+
matches.forEach((match, index) => {
|
|
1680
|
+
var _a, _b, _c, _d;
|
|
1681
|
+
const route = this.looseRoutesById[match.routeId];
|
|
1682
|
+
const existingMatch = this.getMatch(match.id);
|
|
1682
1683
|
if (!existingMatch && (opts == null ? void 0 : opts._buildLocation) !== true) {
|
|
1684
|
+
const parentMatch = matches[index - 1];
|
|
1685
|
+
const parentContext = getParentContext(parentMatch);
|
|
1683
1686
|
const contextFnContext = {
|
|
1684
|
-
deps: loaderDeps,
|
|
1687
|
+
deps: match.loaderDeps,
|
|
1685
1688
|
params: match.params,
|
|
1686
|
-
context:
|
|
1689
|
+
context: parentContext,
|
|
1687
1690
|
location: next,
|
|
1688
1691
|
navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
|
|
1689
1692
|
buildLocation: this.buildLocation,
|
|
@@ -1692,14 +1695,22 @@ ${script}\`)` : ""}; if (typeof __TSR__ !== 'undefined') __TSR__.cleanScripts()<
|
|
|
1692
1695
|
preload: !!match.preload,
|
|
1693
1696
|
matches
|
|
1694
1697
|
};
|
|
1695
|
-
match.__routeContext = ((
|
|
1698
|
+
match.__routeContext = ((_b = (_a = route.options).context) == null ? void 0 : _b.call(_a, contextFnContext)) ?? {};
|
|
1696
1699
|
match.context = {
|
|
1697
1700
|
...parentContext,
|
|
1698
1701
|
...match.__routeContext,
|
|
1699
1702
|
...match.__beforeLoadContext
|
|
1700
1703
|
};
|
|
1701
1704
|
}
|
|
1702
|
-
|
|
1705
|
+
const headFnContent = (_d = (_c = route.options).head) == null ? void 0 : _d.call(_c, {
|
|
1706
|
+
matches,
|
|
1707
|
+
match,
|
|
1708
|
+
params: match.params,
|
|
1709
|
+
loaderData: match.loaderData ?? void 0
|
|
1710
|
+
});
|
|
1711
|
+
match.links = headFnContent == null ? void 0 : headFnContent.links;
|
|
1712
|
+
match.scripts = headFnContent == null ? void 0 : headFnContent.scripts;
|
|
1713
|
+
match.meta = headFnContent == null ? void 0 : headFnContent.meta;
|
|
1703
1714
|
});
|
|
1704
1715
|
return matches;
|
|
1705
1716
|
}
|