{"version":3,"file":"Matches.cjs","names":[],"sources":["../../src/Matches.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { CatchBoundary } from './CatchBoundary'\nimport { useRouter } from './useRouter'\nimport { useStructuralSharing } from './useMatch'\nimport { useLayoutEffect } from './utils'\nimport { Transitioner, settleOwner } from './Transitioner'\nimport { matchContext } from './matchContext'\nimport { Match, renderPending } from './Match'\nimport { SafeFragment } from './SafeFragment'\nimport type {\n  StructuralSharingOption,\n  ValidateSelected,\n} from './structuralSharing'\nimport type {\n  AnyRoute,\n  AnyRouter,\n  DeepPartial,\n  Expand,\n  MakeOptionalPathParams,\n  MakeOptionalSearchParams,\n  MakeRouteMatchUnion,\n  MaskOptions,\n  MatchRouteOptions,\n  RegisteredRouter,\n  ResolveRoute,\n  ToSubOptionsProps,\n} from '@tanstack/router-core'\n\ndeclare module '@tanstack/router-core' {\n  export interface RouteMatchExtensions {\n    meta?: Array<React.JSX.IntrinsicElements['meta'] | undefined>\n    links?: Array<React.JSX.IntrinsicElements['link'] | undefined>\n    scripts?: Array<React.JSX.IntrinsicElements['script'] | undefined>\n    styles?: Array<React.JSX.IntrinsicElements['style'] | undefined>\n    headScripts?: Array<React.JSX.IntrinsicElements['script'] | undefined>\n  }\n}\n\n/**\n * Internal component that renders the router's active match tree with\n * suspense, error, and not-found boundaries. Rendered by `RouterProvider`.\n */\nexport function Matches() {\n  const router = useRouter()\n  const rootRoute: AnyRoute = router.routesById[rootRouteId]\n\n  const pendingElement = renderPending(router, rootRoute)\n\n  // Do not render a root Suspense during SSR or hydrating from SSR\n  const ResolvedSuspense =\n    (isServer ?? router.isServer) || router.ssr ? SafeFragment : React.Suspense\n\n  const inner = (\n    <>\n      {!(isServer ?? router.isServer) && (\n        <Transitioner\n          // The initial load publishes matches before MatchesInner's store\n          // subscription is active. Storing the router here forces Matches to render\n          // that first publication before paint. Later publications store the same\n          // router object, so React skips the update.\n          // eslint-disable-next-line react-hooks/rules-of-hooks -- server only, condition is static\n          t={React.useState<AnyRouter>()[1]}\n        />\n      )}\n      <ResolvedSuspense fallback={pendingElement}>\n        <MatchesInner />\n      </ResolvedSuspense>\n    </>\n  )\n\n  return router.options.InnerWrap ? (\n    <router.options.InnerWrap>{inner}</router.options.InnerWrap>\n  ) : (\n    inner\n  )\n}\n\nfunction MatchesInner() {\n  const router = useRouter()\n  const acknowledgement = router._rendered!\n  const matches =\n    (isServer ?? router.isServer)\n      ? router.stores.matches.get()\n      : // eslint-disable-next-line react-hooks/rules-of-hooks\n        useStore(\n          router.stores.matches,\n          (value) => acknowledgement[0 /* offered */] ?? value,\n        )\n  const match = matches[0]\n  const routeId = match?.routeId\n\n  useLayoutEffect(() => {\n    if (acknowledgement[0 /* offered */] === matches) {\n      settleOwner(acknowledgement, true)\n    }\n  }, [acknowledgement, matches])\n\n  const matchComponent = routeId ? <Match routeId={routeId} /> : null\n\n  return (\n    <matchContext.Provider value={routeId}>\n      {router.options.disableGlobalCatchBoundary ? (\n        matchComponent\n      ) : (\n        <CatchBoundary\n          getResetKey={() => match}\n          onCatch={\n            process.env.NODE_ENV !== 'production'\n              ? (error) => {\n                  console.warn(\n                    `Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`,\n                  )\n                  console.warn(`Warning: ${error.message || error.toString()}`)\n                }\n              : undefined\n          }\n        >\n          {matchComponent}\n        </CatchBoundary>\n      )}\n    </matchContext.Provider>\n  )\n}\n\nexport type UseMatchRouteOptions<\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> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n  DeepPartial<MakeOptionalSearchParams<TRouter, TFrom, TTo>> &\n  DeepPartial<MakeOptionalPathParams<TRouter, TFrom, TTo>> &\n  MaskOptions<TRouter, TMaskFrom, TMaskTo> &\n  MatchRouteOptions\n\n/**\n * Create a matcher function for testing locations against route definitions.\n *\n * The returned function accepts standard navigation options (`to`, `params`,\n * `search`, etc.) and returns either `false` (no match) or the matched params\n * object when the route matches the current or pending location.\n *\n * Useful for conditional rendering and active UI states.\n *\n * @returns A `matchRoute(options)` function that returns `false` or params.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useMatchRouteHook\n */\nexport function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {\n  const router = useRouter()\n\n  if (!(isServer ?? router.isServer)) {\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useStore(router.stores.location, (location) => location.href)\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useStore(router.stores.resolvedLocation, (location) => location?.href)\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useStore(router.stores.status, (status) => status)\n  }\n\n  return React.useCallback(\n    <\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      opts: UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n    ):\n      | false\n      | Expand<ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']> => {\n      const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts\n\n      return router.matchRoute(rest as any, {\n        pending,\n        caseSensitive,\n        fuzzy,\n        includeSearch,\n      })\n    },\n    [router],\n  )\n}\n\nexport type MakeMatchRouteOptions<\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> = UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\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    | ((\n        params?: Expand<\n          ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']\n        >,\n      ) => React.ReactNode)\n    | React.ReactNode\n}\n\n/**\n * Component that conditionally renders its children based on whether a route\n * matches the provided `from`/`to` options. If `children` is a function, it\n * receives the matched params object.\n *\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/matchRouteComponent\n */\nexport function MatchRoute<\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>(props: MakeMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): any {\n  const matchRoute = useMatchRoute()\n  const params = matchRoute(props as any) as boolean\n\n  if (typeof props.children === 'function') {\n    return (props.children as any)(params)\n  }\n\n  return params ? props.children : null\n}\n\nexport interface UseMatchesBaseOptions<\n  TRouter extends AnyRouter,\n  TSelected,\n  TStructuralSharing,\n> {\n  select?: (\n    matches: Array<MakeRouteMatchUnion<TRouter>>,\n  ) => ValidateSelected<TRouter, TSelected, TStructuralSharing>\n}\n\nexport type UseMatchesResult<\n  TRouter extends AnyRouter,\n  TSelected,\n> = unknown extends TSelected ? Array<MakeRouteMatchUnion<TRouter>> : TSelected\n\nexport function useMatches<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TSelected = unknown,\n  TStructuralSharing extends boolean = boolean,\n>(\n  opts?: UseMatchesBaseOptions<TRouter, TSelected, TStructuralSharing> &\n    StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n): UseMatchesResult<TRouter, TSelected> {\n  const router = useRouter<TRouter>()\n\n  if (isServer ?? router.isServer) {\n    const matches = router.stores.matches.get() as Array<\n      MakeRouteMatchUnion<TRouter>\n    >\n    return (opts?.select ? opts.select(matches) : matches) as UseMatchesResult<\n      TRouter,\n      TSelected\n    >\n  }\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  return useStore(\n    router.stores.matches,\n    // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n    useStructuralSharing(opts, router),\n  ) as UseMatchesResult<TRouter, TSelected>\n}\n\n/**\n * Read the presented route matches above the current match, or select a\n * derived value from them.\n */\nexport function useParentMatches<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TSelected = unknown,\n  TStructuralSharing extends boolean = boolean,\n>(\n  opts?: UseMatchesBaseOptions<TRouter, TSelected, TStructuralSharing> &\n    StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n): UseMatchesResult<TRouter, TSelected> {\n  const contextRouteId = React.useContext(matchContext)\n\n  return useMatches({\n    select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {\n      matches = matches.slice(\n        0,\n        matches.findIndex((d) => d.routeId === contextRouteId),\n      )\n      return opts?.select ? opts.select(matches) : matches\n    },\n    structuralSharing: opts?.structuralSharing,\n  } as any)\n}\n\n/**\n * Read the presented route matches below the current match, or select a\n * derived value from them.\n */\nexport function useChildMatches<\n  TRouter extends AnyRouter = RegisteredRouter,\n  TSelected = unknown,\n  TStructuralSharing extends boolean = boolean,\n>(\n  opts?: UseMatchesBaseOptions<TRouter, TSelected, TStructuralSharing> &\n    StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n): UseMatchesResult<TRouter, TSelected> {\n  const contextRouteId = React.useContext(matchContext)\n\n  return useMatches({\n    select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {\n      matches = matches.slice(\n        matches.findIndex((d) => d.routeId === contextRouteId) + 1,\n      )\n      return opts?.select ? opts.select(matches) : matches\n    },\n    structuralSharing: opts?.structuralSharing,\n  } as any)\n}\n"],"mappings":"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"}