{"version":3,"file":"link.cjs","names":[],"sources":["../../src/link.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useSelector } from '@tanstack/react-store'\nimport {\n  deepEqual,\n  functionalUpdate,\n  getUrlScheme,\n  isDangerousProtocol,\n  preloadWarning,\n  removeTrailingSlash,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouter } from './useRouter'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n  ActiveOptions,\n  AnyRouter,\n  Constrain,\n  LinkOptions,\n  ParsedLocation,\n  RegisteredRouter,\n  RoutePaths,\n} from '@tanstack/router-core'\nimport type { ReactNode } from 'react'\nimport type {\n  ValidateLinkOptions,\n  ValidateLinkOptionsArray,\n} from './typePrimitives'\n\n// Undefined active state marks an external or blocked link.\n// Keep that classification with the href instead of parsing it again on render.\ntype LinkState = [href: string | undefined, isActive?: boolean]\n\n// Keep referentially stable values while their contents are equal. Links\n// routinely pass inline `params` / `search` object literals, which would\n// otherwise change `_options` identity on every parent render, rebuild the\n// store selector, and discard its memoized selection. One ref holds all of\n// them; each entry is replaced only when its own contents change.\n//\n// The router reuses a built location for as long as it sees the same options\n// object, so the references returned here are its invalidation signal: pass a\n// new object to change a destination. Like every other React prop, an object\n// mutated in place is not re-read. `deepEqual` short-circuits on reference\n// equality, so an unchanged reference costs nothing.\n//\n// `explicitUndefined` is required: an explicit `undefined` clears an\n// inherited param or search key, so `{}` and `{ category: undefined }` build\n// different locations and must not be treated as equal here.\nfunction useStableValues<T extends ReadonlyArray<unknown>>(...values: T): T {\n  const ref = React.useRef<ReadonlyArray<unknown>>(values)\n  const stable = ref.current as Array<unknown>\n  values.forEach((value, index) => {\n    if (!deepEqual(stable[index], value, false, true)) {\n      stable[index] = value\n    }\n  })\n  return ref.current as T\n}\n\nfunction preloadLink(router: AnyRouter, options: unknown) {\n  router.preloadRoute(options as any).catch((err) => {\n    console.warn(err)\n    console.warn(preloadWarning)\n  })\n}\n\nconst LINK_SELECTOR_OPTIONS = {\n  compare: (a: LinkState, b: LinkState) => a[0] === b[0] && a[1] === b[1],\n}\n\nfunction resolveExternalLink(\n  to: string | undefined,\n  protocolAllowlist: AnyRouter['protocolAllowlist'],\n): string | null | undefined {\n  const scheme = typeof to === 'string' && getUrlScheme(to)\n  if (!scheme) {\n    return undefined\n  }\n  if (!protocolAllowlist.has(scheme)) {\n    if (process.env.NODE_ENV !== 'production') {\n      console.warn(`Blocked Link with dangerous protocol: ${to}`)\n    }\n    return null\n  }\n  return to\n}\n\nfunction resolveIsActive(\n  location: ParsedLocation,\n  next: ParsedLocation,\n  activeOptions: ActiveOptions | undefined,\n  basepath: string,\n  isHydrated: boolean,\n): boolean {\n  const currentPath = removeTrailingSlash(location.pathname, basepath)\n  const nextPath = removeTrailingSlash(next.pathname, basepath)\n\n  // Both modes compare normalized paths; fuzzy matches need a segment boundary.\n  if (\n    activeOptions?.exact\n      ? currentPath !== nextPath\n      : !(\n          currentPath.startsWith(nextPath) &&\n          (currentPath.length === nextPath.length ||\n            currentPath[nextPath.length] === '/')\n        )\n  ) {\n    return false\n  }\n\n  if (activeOptions?.includeSearch ?? true) {\n    const searchTest = deepEqual(\n      location.search,\n      next.search,\n      !activeOptions?.exact,\n      activeOptions?.explicitUndefined,\n    )\n    if (!searchTest) {\n      return false\n    }\n  }\n\n  if (activeOptions?.includeHash) {\n    return isHydrated && location.hash === next.hash\n  }\n  return true\n}\n\n/**\n * Build anchor-like props for declarative navigation and preloading.\n *\n * Returns stable `href`, event handlers and accessibility props derived from\n * router options and active state. Used internally by `Link` and custom links.\n *\n * Options cover `to`, `params`, `search`, `hash`, `state`, `preload`,\n * `activeProps`, `inactiveProps`, and more.\n *\n * @returns React anchor props suitable for `<a>` or custom components.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useLinkPropsHook\n */\nexport function useLinkProps<\n  TRouter extends AnyRouter = RegisteredRouter,\n  const TFrom extends string = string,\n  const TTo extends string | undefined = undefined,\n  const TMaskFrom extends string = TFrom,\n  const TMaskTo extends string = '',\n>(\n  options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n  forwardedRef?: React.ForwardedRef<Element>,\n): React.ComponentPropsWithRef<'a'>\n/**\n * `host` is what the props are rendered on: `'a'` for `Link` or the component\n * given to `createLink`. `Link` never renders `type` and an anchor never\n * receives `disabled`, so those are left out here rather than copied away\n * from the result in the component. Stripped from the public declarations.\n *\n * @internal\n */\nexport function useLinkProps<\n  TRouter extends AnyRouter = RegisteredRouter,\n  const TFrom extends string = string,\n  const TTo extends string | undefined = undefined,\n  const TMaskFrom extends string = TFrom,\n  const TMaskTo extends string = '',\n>(\n  options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n  forwardedRef: React.ForwardedRef<Element> | undefined,\n  host: 'a' | React.ElementType,\n): React.ComponentPropsWithRef<'a'>\nexport function useLinkProps<\n  TRouter extends AnyRouter = RegisteredRouter,\n  const TFrom extends string = string,\n  const TTo extends string | undefined = undefined,\n  const TMaskFrom extends string = TFrom,\n  const TMaskTo extends string = '',\n>(\n  options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n  forwardedRef?: React.ForwardedRef<Element>,\n  host?: 'a' | React.ElementType,\n): React.ComponentPropsWithRef<'a'> {\n  const router = useRouter()\n\n  // ==========================================================================\n  // SERVER EARLY RETURN\n  // On the server, we return static props without any event handlers,\n  // effects, or client-side interactivity.\n  //\n  // For SSR parity (to avoid hydration errors), we still compute the link's\n  // active status on the server, but we avoid creating any router-state\n  // subscriptions by reading from the location store directly.\n  //\n  // Note: `location.hash` is not available on the server.\n  // ==========================================================================\n  // The expression must stay inlined in the `if` so bundlers fold the\n  // browser-build constant `isServer = false` and drop this server block,\n  // together with `getServerLinkProps` and the key sets only it references.\n  if (isServer ?? router.isServer) {\n    return getServerLinkProps(router, options, forwardedRef, host)\n  }\n\n  // ==========================================================================\n  // CLIENT-ONLY CODE\n  // Everything below this point only runs on the client. The `isServer` check\n  // above is a compile-time constant that bundlers use for dead code elimination,\n  // so this entire section is removed from server bundles.\n  //\n  // We disable the rules-of-hooks lint rule because these hooks appear after\n  // an early return. This is safe because:\n  // 1. `isServer` is a compile-time constant from conditional exports\n  // 2. In server bundles, this code is completely eliminated by the bundler\n  // 3. In client bundles, `isServer` is `false`, so the early return never executes\n  // ==========================================================================\n\n  // The link's own ref: the element for the viewport observer and the key\n  // of a pending intent timer. A forwarded ref is filled alongside it by one\n  // callback, memoized on the forwarded ref so React re-attaches it (and\n  // notifies the consumer) only when their ref changes, not on every render.\n  // A cleanup returned by a consumer callback is passed through to React.\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const innerRef = React.useRef<Element>(null)\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const mergedRef = React.useCallback(\n    (element: Element | null) => {\n      innerRef.current = element\n      if (typeof forwardedRef === 'function') {\n        return forwardedRef(element)\n      }\n      if (forwardedRef) {\n        forwardedRef.current = element\n      }\n      return undefined\n    },\n    [forwardedRef],\n  )\n\n  const {\n    activeOptions,\n    to,\n    preload: userPreload,\n    preloadDelay: userPreloadDelay,\n    hashScrollIntoView,\n    replace,\n    startTransition,\n    resetScroll,\n    viewTransition,\n    ignoreBlocker,\n    disabled,\n    target,\n    onClick,\n    onBlur,\n    onFocus,\n    onMouseEnter,\n    onMouseLeave,\n    onTouchStart,\n  } = options as typeof options & { to?: string }\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const isHydrated = useHydrated(!!activeOptions?.includeHash)\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const [stableSearch, stableParams, stableActiveOptions] = useStableValues(\n    options.search,\n    options.params,\n    activeOptions,\n  )\n  // `_options` is the options object from the render that last changed the\n  // destination. `dest` is its copy that the link owns: one stable object per\n  // link lets the router reuse location-independent results.\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const [_options, dest] = React.useMemo(\n    () => [options, { ...options } as any] as const,\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [\n      router,\n      options.from,\n      options._fromLocation,\n      options.hash,\n      options.to,\n      stableSearch,\n      stableParams,\n      options.state,\n      options.mask,\n      options.unsafeRelative,\n    ],\n  )\n\n  // Derive inside the selector so `compareLinkState` can bail out. Deriving after\n  // the subscription instead re-renders every link on every navigation, because\n  // the comparator only sees the location, not whether this link's output moved.\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const selectLinkState = React.useCallback(\n    (location: ParsedLocation): LinkState => {\n      const directExternalLink = resolveExternalLink(\n        to,\n        router.protocolAllowlist,\n      )\n      if (directExternalLink !== undefined) {\n        return [directExternalLink ?? undefined]\n      }\n\n      if (!_options._fromLocation) {\n        dest._fromLocation = location\n      }\n      const next = router.buildLocation(dest)\n\n      // Use publicHref - it contains the correct href for display\n      // When a rewrite changes the origin, publicHref is the full URL\n      // Otherwise it's the origin-stripped path\n      // This avoids constructing URL objects in the hot path\n      const hrefOption = getHrefOption(next, router, disabled)\n      return [\n        hrefOption,\n        !disabled && (!hrefOption || getUrlScheme(hrefOption))\n          ? undefined\n          : resolveIsActive(\n              location,\n              next,\n              stableActiveOptions,\n              router.basepath,\n              isHydrated,\n            ),\n      ]\n    },\n    [stableActiveOptions, disabled, isHydrated, _options, dest, router, to],\n  )\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const [href, isActive] = useSelector(\n    router.stores.location,\n    selectLinkState,\n    LINK_SELECTOR_OPTIONS,\n  )\n  const externalLink = isActive === undefined ? href : undefined\n  const linkDisabled = disabled || href === undefined\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const hasRenderFetched = React.useRef(false)\n\n  const preload =\n    options.reloadDocument || externalLink || linkDisabled\n      ? false\n      : (userPreload ?? router.options.defaultPreload)\n  const preloadDelay =\n    userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n  // `preloadRoute` builds the location itself and only reads the options, so\n  // `_options` goes through as-is.\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  const enqueuePreload = React.useCallback(\n    (e?: React.MouseEvent | React.FocusEvent | IntersectionObserverEntry) => {\n      const isIntersecting = (e as IntersectionObserverEntry | undefined)\n        ?.isIntersecting\n      if (!(isIntersecting ?? preload === 'intent')) {\n        if (isIntersecting === false) {\n          cancelPreload(innerRef)\n        }\n        return\n      }\n\n      if (!preloadDelay) {\n        preloadLink(router, _options)\n        return\n      }\n\n      if (timeoutMap.has(innerRef)) {\n        return\n      }\n\n      timeoutMap.set(\n        innerRef,\n        setTimeout(() => {\n          timeoutMap.delete(innerRef)\n          preloadLink(router, _options)\n        }, preloadDelay),\n      )\n    },\n    [router, _options, innerRef, preload, preloadDelay],\n  )\n\n  // Preload side effects: `render` preloads once per link, `viewport` watches\n  // the element. The cleanup also cancels a pending intent timer.\n  // eslint-disable-next-line react-hooks/rules-of-hooks\n  React.useEffect(() => {\n    if (preload === 'render' && !hasRenderFetched.current) {\n      hasRenderFetched.current = true\n      preloadLink(router, _options)\n    }\n    let observer: IntersectionObserver | undefined\n    if (\n      preload === 'viewport' &&\n      innerRef.current &&\n      typeof IntersectionObserver === 'function'\n    ) {\n      observer = new IntersectionObserver(\n        (entries) => enqueuePreload(entries.pop()),\n        { rootMargin: '100px' },\n      )\n      observer.observe(innerRef.current)\n    }\n    return () => {\n      observer?.disconnect()\n      cancelPreload(innerRef)\n    }\n  }, [router, _options, preload, enqueuePreload, innerRef])\n\n  const props = collectElementProps(options, host)\n  props.ref = forwardedRef ? mergedRef : innerRef\n  // External links get no router behavior: element props pass through as given.\n  if (externalLink) {\n    props.href = externalLink\n    return props\n  }\n\n  // The click handler\n  const handleClick = (e: React.MouseEvent) => {\n    // The element's own target attribute is the fallback.\n    const effectiveTarget =\n      target ??\n      (e.currentTarget as HTMLAnchorElement | SVGAElement).getAttribute(\n        'target',\n      )\n\n    if (\n      !linkDisabled &&\n      !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) &&\n      !e.defaultPrevented &&\n      (!effectiveTarget || effectiveTarget === '_self') &&\n      e.button === 0\n    ) {\n      e.preventDefault()\n\n      // All is well? Navigate!\n      // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n      router.navigate({\n        ..._options,\n        replace,\n        resetScroll,\n        hashScrollIntoView,\n        startTransition,\n        viewTransition,\n        ignoreBlocker,\n      })\n    }\n  }\n\n  const handleTouchStart = () => {\n    if (preload === 'intent') {\n      preloadLink(router, _options)\n    }\n  }\n\n  const handleLeave = () => {\n    if (preload === 'intent') {\n      cancelPreload(innerRef)\n    }\n  }\n\n  props.onClick = composeHandlers(onClick, handleClick)\n  props.onBlur = composeHandlers(onBlur, handleLeave)\n  props.onFocus = composeHandlers(onFocus, enqueuePreload)\n  props.onMouseEnter = composeHandlers(onMouseEnter, enqueuePreload)\n  props.onMouseLeave = composeHandlers(onMouseLeave, handleLeave)\n  props.onTouchStart = composeHandlers(onTouchStart, handleTouchStart)\n  return applyLinkState(props, options, isActive, href, linkDisabled, host)\n}\n\nconst STATIC_EMPTY_OBJECT = {}\nconst STATIC_ACTIVE_OBJECT = { className: 'active' }\n// Options the router consumes; they never reach the element. Every other\n// option is an element prop and passes through.\nconst ROUTER_OPTION_KEYS = /* @__PURE__ */ new Set([\n  'to',\n  'params',\n  'search',\n  'hash',\n  'state',\n  'mask',\n  'from',\n  'unsafeRelative',\n  '_fromLocation',\n  'reloadDocument',\n  'preload',\n  'preloadDelay',\n  'preloadIntentProximity',\n  'hashScrollIntoView',\n  'replace',\n  'startTransition',\n  'resetScroll',\n  'viewTransition',\n  'ignoreBlocker',\n  'activeProps',\n  'inactiveProps',\n  'activeOptions',\n  '_asChild',\n])\n\n// Copies the element props. An object rest would test every key against the\n// whole exclusion list; the key set is much cheaper. `Link` hosts never render\n// `type`, and an anchor has no `disabled` attribute.\nfunction collectElementProps(\n  options: object,\n  host: 'a' | React.ElementType | undefined,\n): Record<string, unknown> {\n  const props: Record<string, unknown> = {}\n  for (const key in options) {\n    if (\n      ROUTER_OPTION_KEYS.has(key) ||\n      (key === 'type' && host !== undefined) ||\n      (key === 'disabled' && host === 'a')\n    ) {\n      continue\n    }\n    props[key] = (options as Record<string, unknown>)[key]\n  }\n  return props\n}\n\n// Finishes a router-controlled link: the selected state props, then the\n// routing attributes. This is the one place that defines precedence: state\n// props override element props, `ref` and handlers; `href`, `disabled`,\n// `target` and the merged class and style always win.\nfunction applyLinkState(\n  props: Record<string, unknown>,\n  options: {\n    activeProps?: unknown\n    inactiveProps?: unknown\n    className?: string\n    style?: React.CSSProperties\n    target?: string\n  },\n  isActive: boolean | undefined,\n  href: string | undefined,\n  linkDisabled: boolean,\n  host: 'a' | React.ElementType | undefined,\n): React.ComponentPropsWithRef<'a'> {\n  const { activeProps, inactiveProps, className, style, target } = options\n  const stateProps: React.HTMLAttributes<HTMLAnchorElement> =\n    functionalUpdate((isActive ? activeProps : inactiveProps) as any, {}) ??\n    (isActive ? STATIC_ACTIVE_OBJECT : STATIC_EMPTY_OBJECT)\n  Object.assign(props, stateProps)\n  props.href = href\n  if (host !== 'a') {\n    props.disabled = linkDisabled\n  }\n  props.target = target\n  // Merge class and style with the state's. Links without either keep their\n  // props as given and carry no `undefined` keys.\n  const stateStyle = stateProps.style\n  if (style || stateStyle) {\n    props.style =\n      style && stateStyle ? { ...style, ...stateStyle } : style || stateStyle\n  }\n  const stateClassName = stateProps.className\n  if (className || stateClassName) {\n    props.className = className\n      ? stateClassName\n        ? `${className} ${stateClassName}`\n        : className\n      : stateClassName\n  }\n  if (linkDisabled) {\n    props.role = 'link'\n    props['aria-disabled'] = true\n  }\n  if (isActive) {\n    props['data-status'] = 'active'\n    props['aria-current'] = 'page'\n  }\n  return props\n}\n\n// Server render of a Link: static props only, no hooks. Only server bundles\n// keep this function; the `isServer` check that calls it folds away on the client.\nfunction getServerLinkProps(\n  router: AnyRouter,\n  options: any,\n  forwardedRef: React.ForwardedRef<Element> | undefined,\n  host: 'a' | React.ElementType | undefined,\n): React.ComponentPropsWithRef<'a'> {\n  const { to, disabled, activeOptions } = options as {\n    to: string | undefined\n    disabled: boolean | undefined\n    activeOptions: ActiveOptions | undefined\n  }\n\n  const directExternalLink = resolveExternalLink(to, router.protocolAllowlist)\n\n  // Direct-scheme links need no route resolution. Blocked links still use\n  // the shared inactive-prop merge so their server and client markup agree.\n  const next =\n    directExternalLink === undefined ? router.buildLocation(options) : undefined\n\n  const hrefOption = next\n    ? getHrefOption(next, router, disabled)\n    : (directExternalLink ?? undefined)\n  const linkDisabled = disabled || !hrefOption\n\n  const externalLink =\n    directExternalLink ??\n    (hrefOption && getUrlScheme(hrefOption) ? hrefOption : undefined)\n\n  const props = collectElementProps(options, host)\n  props.ref = forwardedRef\n  if (externalLink) {\n    props.href = externalLink\n    return props\n  }\n\n  const blockedLink = !disabled && !hrefOption\n  // Hash is not available on the server, so it never counts as hydrated.\n  const isActive =\n    !!next &&\n    !blockedLink &&\n    resolveIsActive(\n      router.stores.location.get(),\n      next,\n      activeOptions,\n      router.basepath,\n      false,\n    )\n  return applyLinkState(\n    props,\n    options,\n    isActive,\n    hrefOption,\n    linkDisabled,\n    host,\n  )\n}\n\nconst timeoutMap = new WeakMap<object, ReturnType<typeof setTimeout>>()\nconst cancelPreload = (eventTarget: object) => {\n  clearTimeout(timeoutMap.get(eventTarget))\n  timeoutMap.delete(eventTarget)\n}\n\nexport const composeHandlers = (\n  first: React.EventHandler<any> | undefined,\n  second: React.EventHandler<any>,\n) => {\n  if (!first) {\n    return second\n  }\n\n  // The first guard skips user handlers for already-prevented events; the second\n  // lets user handlers prevent the internal handler from running.\n  return (event: React.SyntheticEvent) =>\n    event.defaultPrevented ||\n    (first(event), event.defaultPrevented || second(event))\n}\n\nfunction getHrefOption(\n  next: ParsedLocation,\n  router: AnyRouter,\n  disabled: boolean | undefined,\n) {\n  if (disabled) {\n    return undefined\n  }\n  const location = next.maskedLocation ?? next\n  // A rewritten external URL must bypass history's relative-path formatting.\n  const href = location.external\n    ? location.publicHref\n    : router.history.createHref(location.publicHref) || '/'\n  if (\n    (location.external || href !== location.publicHref) &&\n    isDangerousProtocol(href, router.protocolAllowlist)\n  ) {\n    if (process.env.NODE_ENV !== 'production') {\n      console.warn(`Blocked Link with dangerous protocol: ${href}`)\n    }\n    return undefined\n  }\n  return href\n}\n\ntype UseLinkReactProps<TComp> = TComp extends keyof React.JSX.IntrinsicElements\n  ? React.JSX.IntrinsicElements[TComp]\n  : TComp extends React.ComponentType<any>\n    ? React.ComponentPropsWithoutRef<TComp> &\n        React.RefAttributes<React.ComponentRef<TComp>>\n    : never\n\nexport type UseLinkPropsOptions<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n  TTo extends string | undefined = '.',\n  TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n  TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n  UseLinkReactProps<'a'>\n\nexport type ActiveLinkOptions<\n  TComp = 'a',\n  TRouter extends AnyRouter = RegisteredRouter,\n  TFrom extends string = string,\n  TTo extends string | undefined = '.',\n  TMaskFrom extends string = TFrom,\n  TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n  ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n  LinkComponentReactProps<TComp> & {\n    [key: `data-${string}`]: unknown\n  }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n  /**\n   * A function that returns additional props for the `active` state of this link.\n   * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n   */\n  activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n  /**\n   * A function that returns additional props for the `inactive` state of this link.\n   * These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n   */\n  inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n  TComp = 'a',\n  TRouter extends AnyRouter = RegisteredRouter,\n  TFrom extends string = string,\n  TTo extends string | undefined = '.',\n  TMaskFrom extends string = TFrom,\n  TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n  LinkPropsChildren\n\nexport interface LinkPropsChildren {\n  // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n  children?:\n    | React.ReactNode\n    | ((state: { isActive: boolean }) => React.ReactNode)\n}\n\ntype LinkComponentReactProps<TComp> = Omit<\n  UseLinkReactProps<TComp>,\n  keyof CreateLinkProps\n>\n\nexport type LinkComponentProps<\n  TComp = 'a',\n  TRouter extends AnyRouter = RegisteredRouter,\n  TFrom extends string = string,\n  TTo extends string | undefined = '.',\n  TMaskFrom extends string = TFrom,\n  TMaskTo extends string = '.',\n> = LinkComponentReactProps<TComp> &\n  LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n  any,\n  any,\n  string,\n  string,\n  string,\n  string\n>\n\nexport type LinkComponent<\n  in out TComp,\n  in out TDefaultFrom extends string = string,\n> = <\n  TRouter extends AnyRouter = RegisteredRouter,\n  const TFrom extends string = TDefaultFrom,\n  const TTo extends string | undefined = undefined,\n  const TMaskFrom extends string = TFrom,\n  const TMaskTo extends string = '',\n>(\n  props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => React.ReactElement\n\nexport interface LinkComponentRoute<\n  in out TDefaultFrom extends string = string,\n> {\n  defaultFrom: TDefaultFrom;\n  <\n    TRouter extends AnyRouter = RegisteredRouter,\n    const TTo extends string | undefined = undefined,\n    const TMaskTo extends string = '',\n  >(\n    props: LinkComponentProps<\n      'a',\n      TRouter,\n      this['defaultFrom'],\n      TTo,\n      this['defaultFrom'],\n      TMaskTo\n    >,\n  ): React.ReactElement\n}\n\n/**\n * Creates a typed Link-like component that preserves TanStack Router's\n * navigation semantics and type-safety while delegating rendering to the\n * provided host component.\n *\n * Useful for integrating design system anchors/buttons while keeping\n * router-aware props (eg. `to`, `params`, `search`, `preload`).\n *\n * @param Comp The host component to render (eg. a design-system Link/Button)\n * @returns A router-aware component with the same API as `Link`.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-link\n */\nexport function createLink<const TComp>(\n  Comp: Constrain<TComp, any, (props: CreateLinkProps) => ReactNode>,\n): LinkComponent<TComp> {\n  return React.forwardRef(function CreatedLink(props, ref) {\n    return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n  }) as any\n}\n\n/**\n * A strongly-typed anchor component for declarative navigation.\n * Handles path, search, hash and state updates with optional route preloading\n * and active-state styling.\n *\n * Props:\n * - `preload`: Controls route preloading (eg. 'intent', 'render', 'viewport', true/false)\n * - `preloadDelay`: Delay in ms before preloading on focus, hover, or viewport entry\n * - `activeProps`/`inactiveProps`: Additional props merged when link is active/inactive\n * - `resetScroll`/`hashScrollIntoView`: Control scroll behavior on navigation\n * - `viewTransition`/`startTransition`: Use View Transitions/React transitions for navigation\n * - `ignoreBlocker`: Bypass registered blockers\n *\n * @returns An anchor-like element that navigates without full page reloads.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkComponent\n */\nexport const Link: LinkComponent<'a'> = React.memo(\n  React.forwardRef<Element, any>((props, ref) => {\n    const host = props._asChild || 'a'\n    const linkProps = useLinkProps(props as any, ref, host)\n\n    const children =\n      typeof props.children === 'function'\n        ? props.children({\n            isActive: (linkProps as any)['data-status'] === 'active',\n          })\n        : props.children\n\n    return React.createElement(host, linkProps, children)\n  }),\n  areLinkPropsEqual,\n) as any\n\n// A Link's output depends only on its props, the router context and the\n// location store, which React tracks for memoized components, so a parent\n// re-render with equal props can skip it. Router options are compared by\n// value: destinations are usually inline object literals. Element props\n// (`children`, handlers, `style`, ...) are compared by reference only, since\n// they may hold arbitrary (even cyclic) data.\nfunction areLinkPropsEqual(\n  prev: Record<string, unknown>,\n  next: Record<string, unknown>,\n): boolean {\n  let extraKeys = 0\n  for (const key in next) {\n    extraKeys++\n    if (prev[key] === next[key]) {\n      continue\n    }\n    if (\n      !ROUTER_OPTION_KEYS.has(key) ||\n      !deepEqual(prev[key], next[key], false, true)\n    ) {\n      return false\n    }\n  }\n  for (const _key in prev) {\n    extraKeys--\n  }\n  return extraKeys === 0\n}\n\nexport type LinkOptionsFnOptions<\n  TOptions,\n  TComp,\n  TRouter extends AnyRouter = RegisteredRouter,\n> =\n  TOptions extends ReadonlyArray<any>\n    ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n    : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n  const TOptions,\n  TRouter extends AnyRouter = RegisteredRouter,\n>(\n  options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\n/**\n * Validate and reuse navigation options for `Link`, `navigate` or `redirect`.\n * Accepts a literal options object and returns it typed for later spreading.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n  return options as any\n}\n\n/**\n * Type-check a literal object for use with `Link`, `navigate` or `redirect`.\n * Use to validate and reuse navigation options across your app.\n * @example\n * const opts = linkOptions({ to: '/dashboard', search: { tab: 'home' } })\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/linkOptions\n */\n"],"mappings":"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"}