@tanstack/react-router 0.0.1-alpha.9 → 0.0.1-beta.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
3
  "author": "Tanner Linsley",
4
- "version": "0.0.1-alpha.9",
4
+ "version": "0.0.1-beta.1",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://react-router.tanstack.com/",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@babel/runtime": "^7.16.7",
43
- "@tanstack/router-core": "0.0.1-alpha.9",
43
+ "@tanstack/router-core": "0.0.1-beta.1",
44
44
  "use-sync-external-store": "^1.2.0"
45
45
  },
46
46
  "devDependencies": {
package/src/index.tsx CHANGED
@@ -4,10 +4,11 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim'
4
4
 
5
5
  import {
6
6
  AnyRoute,
7
- RootRouteId,
7
+ CheckId,
8
8
  rootRouteId,
9
9
  Router,
10
10
  RouterState,
11
+ ToIdOption,
11
12
  } from '@tanstack/router-core'
12
13
  import {
13
14
  warning,
@@ -37,19 +38,14 @@ export * from '@tanstack/router-core'
37
38
  declare module '@tanstack/router-core' {
38
39
  interface FrameworkGenerics {
39
40
  Element: React.ReactNode
40
- AsyncElement: (opts: {
41
- params: Record<string, string>
42
- }) => Promise<React.ReactNode>
43
- SyncOrAsyncElement: React.ReactNode | FrameworkGenerics['AsyncElement']
41
+ // Any is required here so import() will work without having to do import().then(d => d.default)
42
+ SyncOrAsyncElement: React.ReactNode | (() => Promise<any>)
44
43
  }
45
44
 
46
45
  interface Router<
47
46
  TRouteConfig extends AnyRouteConfig = RouteConfig,
48
47
  TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
49
- > extends Pick<
50
- Route<TAllRouteInfo, TAllRouteInfo['routeInfoById'][RootRouteId]>,
51
- 'linkProps' | 'Link' | 'MatchRoute'
52
- > {
48
+ > {
53
49
  useState: () => RouterState
54
50
  useRoute: <TId extends keyof TAllRouteInfo['routeInfoById']>(
55
51
  routeId: TId,
@@ -91,6 +87,19 @@ declare module '@tanstack/router-core' {
91
87
  TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
92
88
  TRouteInfo extends AnyRouteInfo = RouteInfo,
93
89
  > {
90
+ useRoute: <
91
+ TTo extends string = '.',
92
+ TResolved extends string = ResolveRelativePath<
93
+ TRouteInfo['id'],
94
+ NoInfer<TTo>
95
+ >,
96
+ >(
97
+ routeId: CheckId<
98
+ TAllRouteInfo,
99
+ TResolved,
100
+ ToIdOption<TAllRouteInfo, TRouteInfo['id'], TTo>
101
+ >,
102
+ ) => Route<TAllRouteInfo, TAllRouteInfo['routeInfoById'][TResolved]>
94
103
  linkProps: <TTo extends string = '.'>(
95
104
  props: LinkPropsOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo> &
96
105
  React.AnchorHTMLAttributes<HTMLAnchorElement>,
@@ -179,8 +188,23 @@ export function createReactRouter<
179
188
  const makeRouteExt = (
180
189
  route: AnyRoute,
181
190
  router: Router<any, any>,
182
- ): Pick<AnyRoute, 'linkProps' | 'Link' | 'MatchRoute'> => {
191
+ ): Pick<AnyRoute, 'useRoute' | 'linkProps' | 'Link' | 'MatchRoute'> => {
183
192
  return {
193
+ useRoute: (subRouteId = '.' as any) => {
194
+ const resolvedRouteId = router.resolvePath(
195
+ route.routeId,
196
+ subRouteId as string,
197
+ )
198
+ const resolvedRoute = router.getRoute(resolvedRouteId)
199
+ useRouterSubscription(router)
200
+ invariant(
201
+ resolvedRoute,
202
+ `Could not find a route for route "${
203
+ resolvedRouteId as string
204
+ }"! Did you forget to add it to your route config?`,
205
+ )
206
+ return resolvedRoute
207
+ },
184
208
  linkProps: (options) => {
185
209
  const {
186
210
  // custom props
@@ -319,25 +343,11 @@ export function createReactRouter<
319
343
  const coreRouter = createRouter<TRouteConfig>({
320
344
  ...opts,
321
345
  createRouter: (router) => {
322
- const routerExt: Pick<
323
- Router<any, any>,
324
- 'useRoute' | 'useMatch' | 'useState'
325
- > = {
346
+ const routerExt: Pick<Router<any, any>, 'useMatch' | 'useState'> = {
326
347
  useState: () => {
327
348
  useRouterSubscription(router)
328
349
  return router.state
329
350
  },
330
- useRoute: (routeId) => {
331
- const route = router.getRoute(routeId)
332
- useRouterSubscription(router)
333
- invariant(
334
- route,
335
- `Could not find a route for route "${
336
- routeId as string
337
- }"! Did you forget to add it to your route config?`,
338
- )
339
- return route
340
- },
341
351
  useMatch: (routeId) => {
342
352
  useRouterSubscription(router)
343
353
 
@@ -384,6 +394,20 @@ export function createReactRouter<
384
394
 
385
395
  Object.assign(route, routeExt)
386
396
  },
397
+ createElement: async (element) => {
398
+ if (typeof element === 'function') {
399
+ const res = (await element()) as any
400
+
401
+ // Support direct import() calls
402
+ if (typeof res === 'object' && res.default) {
403
+ return React.createElement(res.default)
404
+ } else {
405
+ return res
406
+ }
407
+ }
408
+
409
+ return element
410
+ },
387
411
  })
388
412
 
389
413
  return coreRouter as any
@@ -576,4 +600,26 @@ export function DefaultErrorBoundary({ error }: { error: any }) {
576
600
  )
577
601
  }
578
602
 
579
- // TODO: Add prompt
603
+ export function usePrompt(message: string, when: boolean | any): void {
604
+ const router = useRouter()
605
+
606
+ React.useEffect(() => {
607
+ if (!when) return
608
+
609
+ let unblock = router.history.block((transition) => {
610
+ if (window.confirm(message)) {
611
+ unblock()
612
+ transition.retry()
613
+ } else {
614
+ router.location.pathname = window.location.pathname
615
+ }
616
+ })
617
+
618
+ return unblock
619
+ }, [when, location, message])
620
+ }
621
+
622
+ export function Prompt({ message, when, children }: PromptProps) {
623
+ usePrompt(message, when ?? true)
624
+ return (children ?? null) as React.ReactNode
625
+ }