@tanstack/react-router
Version:
Modern and scalable routing for React applications
1 lines • 6.03 kB
Source Map (JSON)
{"version":3,"file":"useMatch.cjs","names":[],"sources":["../../src/useMatch.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { invariant, replaceEqualDeep } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { dummyMatchContext, matchContext } from './matchContext'\nimport { useRouter } from './useRouter'\nimport type {\n StructuralSharingOption,\n ValidateSelected,\n} from './structuralSharing'\nimport type {\n AnyRouter,\n MakeRouteMatch,\n MakeRouteMatchUnion,\n RegisteredRouter,\n StrictOrFrom,\n ThrowConstraint,\n ThrowOrOptional,\n} from '@tanstack/router-core'\n\nconst dummyStore = {\n state: undefined,\n get: () => undefined,\n subscribe: () => () => {},\n} as any\n\nexport interface UseMatchBaseOptions<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TThrow extends boolean,\n TSelected,\n TStructuralSharing extends boolean,\n> {\n select?: (\n match: MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>,\n ) => ValidateSelected<TRouter, TSelected, TStructuralSharing>\n shouldThrow?: TThrow\n}\n\nexport type UseMatchRoute<out TFrom> = <\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts?: UseMatchBaseOptions<\n TRouter,\n TFrom,\n true,\n true,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n) => UseMatchResult<TRouter, TFrom, true, TSelected>\n\nexport type UseMatchOptions<\n TRouter extends AnyRouter,\n TFrom extends string | undefined,\n TStrict extends boolean,\n TThrow extends boolean,\n TSelected,\n TStructuralSharing extends boolean,\n> = StrictOrFrom<TRouter, TFrom, TStrict> &\n UseMatchBaseOptions<\n TRouter,\n TFrom,\n TStrict,\n TThrow,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>\n\nexport type UseMatchResult<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TSelected,\n> = unknown extends TSelected\n ? TStrict extends true\n ? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>\n : MakeRouteMatchUnion<TRouter>\n : TSelected\n\n/**\n * Read and select the nearest or targeted route match.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useMatchHook\n */\nexport function useMatch<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TThrow extends boolean = true,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts: UseMatchOptions<\n TRouter,\n TFrom,\n TStrict,\n ThrowConstraint<TStrict, TThrow>,\n TSelected,\n TStructuralSharing\n >,\n): ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> {\n const router = useRouter<TRouter>()\n const nearestMatchId = React.useContext(\n opts.from ? dummyMatchContext : matchContext,\n )\n\n const key = opts.from ?? nearestMatchId\n const matchStore = key\n ? opts.from\n ? router.stores.getMatchStoreByRouteId(key)\n : router.stores.activeMatchStoresById.get(key)\n : undefined\n\n if (isServer ?? router.isServer) {\n const match = matchStore?.state\n if ((opts.shouldThrow ?? true) && !match) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `Invariant failed: Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n }\n\n invariant()\n }\n\n if (match === undefined) {\n return undefined as any\n }\n\n return (opts.select ? opts.select(match as any) : match) as any\n }\n\n const previousResult =\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n React.useRef<ValidateSelected<TRouter, TSelected, TStructuralSharing>>(\n undefined,\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n return useStore(matchStore ?? dummyStore, (match) => {\n if ((opts.shouldThrow ?? true) && !match) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `Invariant failed: Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n }\n\n invariant()\n }\n\n if (match === undefined) {\n return undefined\n }\n\n const selected = (\n opts.select ? opts.select(match as any) : match\n ) as ValidateSelected<TRouter, TSelected, TStructuralSharing>\n\n if (opts.structuralSharing ?? router.options.defaultStructuralSharing) {\n const shared = replaceEqualDeep(previousResult.current, selected)\n previousResult.current = shared\n return shared\n }\n\n return selected\n }) as any\n}\n"],"mappings":";;;;;;;;;AAoBA,IAAM,aAAa;CACjB,OAAO,KAAA;CACP,WAAW,KAAA;CACX,uBAAuB;CACxB;;;;;AAiED,SAAgB,SAQd,MAQ6E;CAC7E,MAAM,SAAS,kBAAA,WAAoB;CACnC,MAAM,iBAAiB,MAAM,WAC3B,KAAK,OAAO,qBAAA,oBAAoB,qBAAA,aACjC;CAED,MAAM,MAAM,KAAK,QAAQ;CACzB,MAAM,aAAa,MACf,KAAK,OACH,OAAO,OAAO,uBAAuB,IAAI,GACzC,OAAO,OAAO,sBAAsB,IAAI,IAAI,GAC9C,KAAA;AAEJ,KAAI,+BAAA,YAAY,OAAO,UAAU;EAC/B,MAAM,QAAQ,YAAY;AAC1B,OAAK,KAAK,eAAe,SAAS,CAAC,OAAO;AACxC,OAAA,QAAA,IAAA,aAA6B,aAC3B,OAAM,IAAI,MACR,oCAAoC,KAAK,OAAO,yBAAyB,KAAK,KAAK,KAAK,qBACzF;AAGH,IAAA,GAAA,sBAAA,YAAW;;AAGb,MAAI,UAAU,KAAA,EACZ;AAGF,SAAQ,KAAK,SAAS,KAAK,OAAO,MAAa,GAAG;;CAGpD,MAAM,iBAEJ,MAAM,OACJ,KAAA,EACD;AAGH,SAAA,GAAA,sBAAA,UAAgB,cAAc,aAAa,UAAU;AACnD,OAAK,KAAK,eAAe,SAAS,CAAC,OAAO;AACxC,OAAA,QAAA,IAAA,aAA6B,aAC3B,OAAM,IAAI,MACR,oCAAoC,KAAK,OAAO,yBAAyB,KAAK,KAAK,KAAK,qBACzF;AAGH,IAAA,GAAA,sBAAA,YAAW;;AAGb,MAAI,UAAU,KAAA,EACZ;EAGF,MAAM,WACJ,KAAK,SAAS,KAAK,OAAO,MAAa,GAAG;AAG5C,MAAI,KAAK,qBAAqB,OAAO,QAAQ,0BAA0B;GACrE,MAAM,UAAA,GAAA,sBAAA,kBAA0B,eAAe,SAAS,SAAS;AACjE,kBAAe,UAAU;AACzB,UAAO;;AAGT,SAAO;GACP"}