@nifrajs/web-react 3.3.0 → 4.0.0
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/dist/auth.d.ts +32 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +85 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -24
- package/dist/client.js.map +1 -1
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +1 -0
- package/dist/compose.js.map +1 -1
- package/dist/content.d.ts +2 -1
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js.map +1 -1
- package/dist/i18n.d.ts +19 -6
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +27 -6
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/react-dom-server.d.ts +3 -1
- package/dist/react-dom-server.d.ts.map +1 -1
- package/dist/react-dom-server.js.map +1 -1
- package/dist/render-error.d.ts +4 -0
- package/dist/render-error.d.ts.map +1 -0
- package/dist/render-error.js +15 -0
- package/dist/render-error.js.map +1 -0
- package/dist/route-props.d.ts +4 -0
- package/dist/route-props.d.ts.map +1 -0
- package/dist/route-props.js +32 -0
- package/dist/route-props.js.map +1 -0
- package/dist/router.d.ts +23 -3
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +29 -2
- package/dist/router.js.map +1 -1
- package/package.json +14 -5
- package/src/auth.ts +128 -0
- package/src/client.ts +9 -24
- package/src/compose.ts +1 -0
- package/src/content.ts +3 -1
- package/src/i18n.ts +49 -9
- package/src/index.ts +15 -3
- package/src/react-dom-server.ts +4 -1
- package/src/render-error.ts +18 -0
- package/src/route-props.ts +37 -0
- package/src/router.ts +42 -4
package/src/router.ts
CHANGED
|
@@ -22,6 +22,9 @@ import type {
|
|
|
22
22
|
NavigateFunction,
|
|
23
23
|
NavigateOptions,
|
|
24
24
|
NavigateTargetInput,
|
|
25
|
+
PrefetchMode,
|
|
26
|
+
RenderProps,
|
|
27
|
+
UIMatch,
|
|
25
28
|
} from "@nifrajs/web"
|
|
26
29
|
// `/client`, not the root - these are DOM values, and the root's graph carries the
|
|
27
30
|
// server, which Vite's dev server evaluates rather than tree-shakes.
|
|
@@ -31,6 +34,8 @@ import {
|
|
|
31
34
|
registerBlocker,
|
|
32
35
|
resolveNavigate,
|
|
33
36
|
} from "@nifrajs/web/client"
|
|
37
|
+
// Its own subpath, so an app that never calls `useMatches` bundles none of it.
|
|
38
|
+
import { chainMatches } from "@nifrajs/web/internal/matches-runtime"
|
|
34
39
|
import {
|
|
35
40
|
type AnchorHTMLAttributes,
|
|
36
41
|
type CSSProperties,
|
|
@@ -47,7 +52,7 @@ import {
|
|
|
47
52
|
useState,
|
|
48
53
|
} from "react"
|
|
49
54
|
|
|
50
|
-
export type { Blocker, BlockerFunction, BlockerState, NavigateFunction }
|
|
55
|
+
export type { Blocker, BlockerFunction, BlockerState, NavigateFunction, PrefetchMode, UIMatch }
|
|
51
56
|
|
|
52
57
|
/** The current route the routing hooks read. Provided by `compose` on SSR + client mount alike. */
|
|
53
58
|
export interface RouterContextValue {
|
|
@@ -66,6 +71,8 @@ export interface RouterContextValue {
|
|
|
66
71
|
/** The `pathname + search` a navigation is transitioning TO while `pending` (`undefined` when idle or
|
|
67
72
|
* during a same-route revalidation). Powers {@link NavLink}'s per-link `isPending`. */
|
|
68
73
|
readonly pendingPath?: string | undefined
|
|
74
|
+
/** The render's props, which {@link useMatches} derives the matches from. */
|
|
75
|
+
readonly renderProps?: RenderProps | undefined
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
// Frozen empty params/search so the default context value has a stable reference (no needless re-renders).
|
|
@@ -141,6 +148,26 @@ export function useSearch<
|
|
|
141
148
|
: Record<string, unknown>
|
|
142
149
|
}
|
|
143
150
|
|
|
151
|
+
const NO_MATCHES: readonly UIMatch[] = Object.freeze([])
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The rendered chain, outermost layout first and the page last: each module's `id`, the URL
|
|
155
|
+
* `pathname` it wraps, its `params` and loader `data`, and its `handle` export. The same list on the
|
|
156
|
+
* server and in the browser, so a layout can render breadcrumbs or read a flag the page exports:
|
|
157
|
+
*
|
|
158
|
+
* ```tsx
|
|
159
|
+
* export const handle = { crumb: "Settings" } // in a page or a layout
|
|
160
|
+
* // in a layout above it:
|
|
161
|
+
* const crumbs = useMatches().flatMap((m) => (m.handle as { crumb?: string } | undefined)?.crumb ?? [])
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* Empty outside a nifra route tree.
|
|
165
|
+
*/
|
|
166
|
+
export function useMatches(): readonly UIMatch[] {
|
|
167
|
+
const props = useContext(RouterContext).renderProps
|
|
168
|
+
return useMemo(() => (props === undefined ? NO_MATCHES : chainMatches(props)), [props])
|
|
169
|
+
}
|
|
170
|
+
|
|
144
171
|
/** The parsed current location. `hash` is always `""` - the fragment is client-only and never reaches
|
|
145
172
|
* the router state / server, so exposing a live hash would hydration-mismatch; read `window.location.hash`
|
|
146
173
|
* directly (in an effect) if you truly need it. */
|
|
@@ -307,12 +334,16 @@ function isPlainLeftClick(event: MouseEvent, target: string | undefined): boolea
|
|
|
307
334
|
return target === undefined || target === "" || target === "_self"
|
|
308
335
|
}
|
|
309
336
|
|
|
310
|
-
/** {@link Link} props: every `<a>` attribute except `href` (set from `to`), plus `to
|
|
337
|
+
/** {@link Link} props: every `<a>` attribute except `href` (set from `to`), plus `to`, `replace` and
|
|
338
|
+
* `prefetch`. */
|
|
311
339
|
export interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href"> {
|
|
312
340
|
/** Same-origin destination path (e.g. `/users/7?tab=posts`). Rendered as the `<a href>`. */
|
|
313
341
|
readonly to: string
|
|
314
342
|
/** Replace the current history entry instead of pushing. */
|
|
315
343
|
readonly replace?: boolean
|
|
344
|
+
/** When the link warms its route ahead of a click - rendered as `data-nifra-prefetch`. Unset, the
|
|
345
|
+
* nearest ancestor's `data-nifra-prefetch` decides, else `intent` (hover or focus). */
|
|
346
|
+
readonly prefetch?: PrefetchMode
|
|
316
347
|
}
|
|
317
348
|
|
|
318
349
|
/**
|
|
@@ -322,7 +353,7 @@ export interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
|
322
353
|
* document-level click handler sees `defaultPrevented` and stands down - exactly one navigation.
|
|
323
354
|
*/
|
|
324
355
|
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
|
|
325
|
-
{ to, replace, onClick, target, ...rest },
|
|
356
|
+
{ to, replace, prefetch, onClick, target, ...rest },
|
|
326
357
|
ref,
|
|
327
358
|
) {
|
|
328
359
|
const handleClick = (event: MouseEvent<HTMLAnchorElement>): void => {
|
|
@@ -334,7 +365,14 @@ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
|
|
|
334
365
|
event.preventDefault()
|
|
335
366
|
navigate(to, { replace: replace === true })
|
|
336
367
|
}
|
|
337
|
-
return createElement("a", {
|
|
368
|
+
return createElement("a", {
|
|
369
|
+
...rest,
|
|
370
|
+
href: to,
|
|
371
|
+
target,
|
|
372
|
+
onClick: handleClick,
|
|
373
|
+
ref,
|
|
374
|
+
...(prefetch !== undefined ? { "data-nifra-prefetch": prefetch } : {}),
|
|
375
|
+
})
|
|
338
376
|
})
|
|
339
377
|
|
|
340
378
|
/** The state a {@link NavLink}'s function-form `className`/`style`/`children` receive. */
|