@tanstack/solid-router 1.131.27 → 1.131.29

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.
Files changed (39) hide show
  1. package/dist/cjs/Matches.cjs +22 -18
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/RouterProvider.cjs +9 -9
  4. package/dist/cjs/RouterProvider.cjs.map +1 -1
  5. package/dist/cjs/link.cjs +13 -9
  6. package/dist/cjs/link.cjs.map +1 -1
  7. package/dist/cjs/useActiveLocation.cjs +40 -0
  8. package/dist/cjs/useActiveLocation.cjs.map +1 -0
  9. package/dist/cjs/useActiveLocation.d.cts +8 -0
  10. package/dist/cjs/useNavigate.cjs +9 -10
  11. package/dist/cjs/useNavigate.cjs.map +1 -1
  12. package/dist/esm/Matches.js +16 -12
  13. package/dist/esm/Matches.js.map +1 -1
  14. package/dist/esm/RouterProvider.js +9 -9
  15. package/dist/esm/RouterProvider.js.map +1 -1
  16. package/dist/esm/link.js +13 -9
  17. package/dist/esm/link.js.map +1 -1
  18. package/dist/esm/useActiveLocation.d.ts +8 -0
  19. package/dist/esm/useActiveLocation.js +40 -0
  20. package/dist/esm/useActiveLocation.js.map +1 -0
  21. package/dist/esm/useNavigate.js +9 -10
  22. package/dist/esm/useNavigate.js.map +1 -1
  23. package/dist/source/Matches.jsx +11 -7
  24. package/dist/source/Matches.jsx.map +1 -1
  25. package/dist/source/RouterProvider.jsx +7 -7
  26. package/dist/source/RouterProvider.jsx.map +1 -1
  27. package/dist/source/link.jsx +10 -11
  28. package/dist/source/link.jsx.map +1 -1
  29. package/dist/source/useActiveLocation.d.ts +8 -0
  30. package/dist/source/useActiveLocation.js +33 -0
  31. package/dist/source/useActiveLocation.js.map +1 -0
  32. package/dist/source/useNavigate.jsx +7 -10
  33. package/dist/source/useNavigate.jsx.map +1 -1
  34. package/package.json +2 -2
  35. package/src/Matches.tsx +18 -16
  36. package/src/RouterProvider.tsx +9 -10
  37. package/src/link.tsx +11 -11
  38. package/src/useActiveLocation.ts +61 -0
  39. package/src/useNavigate.tsx +10 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-router",
3
- "version": "1.131.27",
3
+ "version": "1.131.29",
4
4
  "description": "Modern and scalable routing for Solid applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -89,7 +89,7 @@
89
89
  "tiny-invariant": "^1.3.3",
90
90
  "tiny-warning": "^1.0.3",
91
91
  "@tanstack/history": "1.131.2",
92
- "@tanstack/router-core": "1.131.27"
92
+ "@tanstack/router-core": "1.131.28"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@solidjs/testing-library": "^0.8.10",
package/src/Matches.tsx CHANGED
@@ -38,27 +38,27 @@ declare module '@tanstack/router-core' {
38
38
  export function Matches() {
39
39
  const router = useRouter()
40
40
 
41
- const pendingElement = router.options.defaultPendingComponent ? (
42
- <router.options.defaultPendingComponent />
43
- ) : null
44
-
45
41
  // Do not render a root Suspense during SSR or hydrating from SSR
46
42
  const ResolvedSuspense =
47
43
  router.isServer || (typeof document !== 'undefined' && router.ssr)
48
44
  ? SafeFragment
49
45
  : Solid.Suspense
50
46
 
51
- const inner = (
52
- <ResolvedSuspense fallback={pendingElement}>
53
- {!router.isServer && <Transitioner />}
54
- <MatchesInner />
55
- </ResolvedSuspense>
56
- )
47
+ const OptionalWrapper = router.options.InnerWrap || SafeFragment
57
48
 
58
- return router.options.InnerWrap ? (
59
- <router.options.InnerWrap>{inner}</router.options.InnerWrap>
60
- ) : (
61
- inner
49
+ return (
50
+ <OptionalWrapper>
51
+ <ResolvedSuspense
52
+ fallback={
53
+ router.options.defaultPendingComponent ? (
54
+ <router.options.defaultPendingComponent />
55
+ ) : null
56
+ }
57
+ >
58
+ {!router.isServer && <Transitioner />}
59
+ <MatchesInner />
60
+ </ResolvedSuspense>
61
+ </OptionalWrapper>
62
62
  )
63
63
  }
64
64
 
@@ -74,8 +74,10 @@ function MatchesInner() {
74
74
  select: (s) => s.loadedAt,
75
75
  })
76
76
 
77
- const matchComponent = () =>
78
- matchId() ? <Match matchId={matchId()!} /> : null
77
+ const matchComponent = () => {
78
+ const id = matchId()
79
+ return id ? <Match matchId={id} /> : null
80
+ }
79
81
 
80
82
  return (
81
83
  <matchContext.Provider value={matchId}>
@@ -1,5 +1,6 @@
1
1
  import { Matches } from './Matches'
2
2
  import { getRouterContext } from './routerContext'
3
+ import { SafeFragment } from './SafeFragment'
3
4
  import type * as Solid from 'solid-js'
4
5
  import type {
5
6
  AnyRouter,
@@ -29,17 +30,15 @@ export function RouterContextProvider<
29
30
 
30
31
  const routerContext = getRouterContext()
31
32
 
32
- const provider = (
33
- <routerContext.Provider value={router as AnyRouter}>
34
- {children()}
35
- </routerContext.Provider>
36
- )
37
-
38
- if (router.options.Wrap) {
39
- return <router.options.Wrap>{provider}</router.options.Wrap>
40
- }
33
+ const OptionalWrapper = router.options.Wrap || SafeFragment
41
34
 
42
- return provider
35
+ return (
36
+ <OptionalWrapper>
37
+ <routerContext.Provider value={router as AnyRouter}>
38
+ {children()}
39
+ </routerContext.Provider>
40
+ </OptionalWrapper>
41
+ )
43
42
  }
44
43
 
45
44
  export function RouterProvider<
package/src/link.tsx CHANGED
@@ -15,7 +15,7 @@ import { useRouter } from './useRouter'
15
15
 
16
16
  import { useIntersectionObserver } from './utils'
17
17
 
18
- import { useMatch } from './useMatch'
18
+ import { useActiveLocation } from './useActiveLocation'
19
19
  import type {
20
20
  AnyRouter,
21
21
  Constrain,
@@ -133,20 +133,20 @@ export function useLinkProps<
133
133
  select: (s) => s.location.searchStr,
134
134
  })
135
135
 
136
- // when `from` is not supplied, use the route of the current match as the `from` location
137
- // so relative routing works as expected
138
- const from = useMatch({
139
- strict: false,
140
- select: (match) => options.from ?? match.fullPath,
141
- })
136
+ const { getFromPath, activeLocation } = useActiveLocation()
142
137
 
143
- const _options = () => ({
144
- ...options,
145
- from: from(),
146
- })
138
+ const from = getFromPath(options.from)
139
+
140
+ const _options = () => {
141
+ return {
142
+ ...options,
143
+ from: from(),
144
+ }
145
+ }
147
146
 
148
147
  const next = Solid.createMemo(() => {
149
148
  currentSearch()
149
+ activeLocation()
150
150
  return router.buildLocation(_options() as any)
151
151
  })
152
152
 
@@ -0,0 +1,61 @@
1
+ import { last } from '@tanstack/router-core'
2
+ import { createEffect, createMemo, createSignal } from 'solid-js'
3
+ import { useMatch } from './useMatch'
4
+ import { useRouter } from './useRouter'
5
+ import { useRouterState } from './useRouterState'
6
+ import type { Accessor } from 'solid-js'
7
+ import type { ParsedLocation } from '@tanstack/router-core'
8
+
9
+ export type UseLocationResult = {
10
+ activeLocation: Accessor<ParsedLocation>
11
+ getFromPath: (from?: string) => Accessor<string>
12
+ setActiveLocation: (location?: ParsedLocation) => void
13
+ }
14
+
15
+ export function useActiveLocation(
16
+ location?: ParsedLocation,
17
+ ): UseLocationResult {
18
+ const router = useRouter()
19
+ // we are not using a variable here for router state location since we need to only calculate that if the location is not passed in. It can result in unnecessary history actions if we do that.
20
+ const [activeLocation, setActiveLocation] = createSignal<ParsedLocation>(
21
+ location ?? useRouterState({ select: (s) => s.location })(),
22
+ )
23
+ const [customActiveLocation, setCustomActiveLocation] = createSignal<
24
+ ParsedLocation | undefined
25
+ >(location)
26
+
27
+ createEffect(() => {
28
+ setActiveLocation(
29
+ customActiveLocation() ?? useRouterState({ select: (s) => s.location })(),
30
+ )
31
+ })
32
+
33
+ const matchIndex = useMatch({
34
+ strict: false,
35
+ select: (match) => match.index,
36
+ })
37
+
38
+ const getFromPath = (from?: string) =>
39
+ createMemo(() => {
40
+ const activeLocationMatches = router.matchRoutes(
41
+ customActiveLocation() ?? activeLocation(),
42
+ {
43
+ _buildLocation: false,
44
+ },
45
+ )
46
+
47
+ const activeLocationMatch = last(activeLocationMatches)
48
+
49
+ return (
50
+ from ??
51
+ activeLocationMatch?.fullPath ??
52
+ router.state.matches[matchIndex()]!.fullPath
53
+ )
54
+ })
55
+
56
+ return {
57
+ activeLocation,
58
+ getFromPath,
59
+ setActiveLocation: setCustomActiveLocation,
60
+ }
61
+ }
@@ -1,6 +1,6 @@
1
1
  import * as Solid from 'solid-js'
2
2
  import { useRouter } from './useRouter'
3
- import { useMatch } from './useMatch'
3
+ import { useActiveLocation } from './useActiveLocation'
4
4
  import type {
5
5
  AnyRouter,
6
6
  FromPathOption,
@@ -15,20 +15,19 @@ export function useNavigate<
15
15
  >(_defaultOpts?: {
16
16
  from?: FromPathOption<TRouter, TDefaultFrom>
17
17
  }): UseNavigateResult<TDefaultFrom> {
18
- const { navigate, state } = useRouter()
18
+ const router = useRouter()
19
19
 
20
- const matchIndex = useMatch({
21
- strict: false,
22
- select: (match) => match.index,
23
- })
20
+ const { getFromPath, setActiveLocation } = useActiveLocation(
21
+ router.latestLocation,
22
+ )
24
23
 
25
24
  return ((options: NavigateOptions) => {
26
- return navigate({
25
+ setActiveLocation(router.latestLocation)
26
+ const from = getFromPath(options.from ?? _defaultOpts?.from)
27
+
28
+ return router.navigate({
27
29
  ...options,
28
- from:
29
- options.from ??
30
- _defaultOpts?.from ??
31
- state.matches[matchIndex()]!.fullPath,
30
+ from: from(),
32
31
  })
33
32
  }) as UseNavigateResult<TDefaultFrom>
34
33
  }