react-router-dom 0.0.0-experimental-a077dc2d → 0.0.0-experimental-e192105b
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/CHANGELOG.md +21 -0
- package/dist/dom.d.ts +4 -0
- package/dist/index.d.ts +14 -12
- package/dist/index.js +99 -69
- package/dist/index.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/react-router-dom.development.js +103 -67
- package/dist/react-router-dom.development.js.map +1 -1
- package/dist/react-router-dom.production.min.js +2 -2
- package/dist/react-router-dom.production.min.js.map +1 -1
- package/dist/server.js +2 -5
- package/dist/server.mjs +2 -5
- package/dist/umd/react-router-dom.development.js +111 -75
- package/dist/umd/react-router-dom.development.js.map +1 -1
- package/dist/umd/react-router-dom.production.min.js +2 -2
- package/dist/umd/react-router-dom.production.min.js.map +1 -1
- package/package.json +3 -3
- package/server.js +2 -5
- package/server.mjs +2 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# `react-router-dom`
|
|
2
2
|
|
|
3
|
+
## 6.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add support for manual fetcher key specification via `useFetcher({ key: string })` so you can access the same fetcher instance from different components in your application without prop-drilling ([RFC](https://github.com/remix-run/remix/discussions/7698)) ([#10960](https://github.com/remix-run/react-router/pull/10960))
|
|
8
|
+
|
|
9
|
+
- Fetcher keys are now also exposed on the fetchers returned from `useFetchers` so that they can be looked up by `key`
|
|
10
|
+
|
|
11
|
+
- Add `navigate`/`fetcherKey` params/props to `useSumbit`/`Form` to support kicking off a fetcher submission under the hood with an optionally user-specified `key` ([#10960](https://github.com/remix-run/react-router/pull/10960))
|
|
12
|
+
|
|
13
|
+
- Invoking a fetcher in this way is ephemeral and stateless
|
|
14
|
+
- If you need to access the state of one of these fetchers, you will need to leverage `useFetcher({ key })` to look it up elsewhere
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Adds a fetcher context to `RouterProvider` that holds completed fetcher data, in preparation for the upcoming future flag that will change the fetcher persistence/cleanup behavior ([#10961](https://github.com/remix-run/react-router/pull/10961))
|
|
19
|
+
- Fix the `future` prop on `BrowserRouter`, `HashRouter` and `MemoryRouter` so that it accepts a `Partial<FutureConfig>` instead of requiring all flags to be included. ([#10962](https://github.com/remix-run/react-router/pull/10962))
|
|
20
|
+
- Updated dependencies:
|
|
21
|
+
- `@remix-run/router@1.11.0`
|
|
22
|
+
- `react-router@6.18.0`
|
|
23
|
+
|
|
3
24
|
## 6.17.0
|
|
4
25
|
|
|
5
26
|
### Minor Changes
|
package/dist/dom.d.ts
CHANGED
|
@@ -85,6 +85,10 @@ export interface SubmitOptions {
|
|
|
85
85
|
* navigation when using the <ScrollRestoration> component
|
|
86
86
|
*/
|
|
87
87
|
preventScrollReset?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Enable flushSync for this navigation's state updates
|
|
90
|
+
*/
|
|
91
|
+
unstable_flushSync?: boolean;
|
|
88
92
|
/**
|
|
89
93
|
* Enable view transitions on this submission navigation
|
|
90
94
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import type { FutureConfig, Location, NavigateOptions, RelativeRoutingType, RouteObject, RouterProviderProps, To } from "react-router";
|
|
7
|
-
import type { Fetcher, FormEncType, FormMethod, FutureConfig as RouterFutureConfig, GetScrollRestorationKeyFunction, History, HTMLFormMethod, HydrationState, Router as RemixRouter, V7_FormMethod } from "@remix-run/router";
|
|
7
|
+
import type { Fetcher, FormEncType, FormMethod, FutureConfig as RouterFutureConfig, GetScrollRestorationKeyFunction, History, HTMLFormMethod, HydrationState, Router as RemixRouter, V7_FormMethod, BlockerFunction } from "@remix-run/router";
|
|
8
8
|
import type { SubmitOptions, ParamKeyValuePair, URLSearchParamsInit, SubmitTarget } from "./dom";
|
|
9
9
|
import { createSearchParams } from "./dom";
|
|
10
10
|
export type { FormEncType, FormMethod, GetScrollRestorationKeyFunction, ParamKeyValuePair, SubmitOptions, URLSearchParamsInit, V7_FormMethod, };
|
|
11
11
|
export { createSearchParams };
|
|
12
12
|
export type { ActionFunction, ActionFunctionArgs, AwaitProps, unstable_Blocker, unstable_BlockerFunction, DataRouteMatch, DataRouteObject, ErrorResponse, Fetcher, Hash, IndexRouteObject, IndexRouteProps, JsonFunction, LazyRouteFunction, LayoutRouteProps, LoaderFunction, LoaderFunctionArgs, Location, MemoryRouterProps, NavigateFunction, NavigateOptions, NavigateProps, Navigation, Navigator, NonIndexRouteObject, OutletProps, Params, ParamParseKey, Path, PathMatch, Pathname, PathPattern, PathRouteProps, RedirectFunction, RelativeRoutingType, RouteMatch, RouteObject, RouteProps, RouterProps, RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, To, UIMatch, } from "react-router";
|
|
13
|
-
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, Routes, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, defer, isRouteErrorResponse, generatePath, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, resolvePath, useActionData, useAsyncError, useAsyncValue,
|
|
13
|
+
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, Routes, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, defer, isRouteErrorResponse, generatePath, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, resolvePath, useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, } from "react-router";
|
|
14
14
|
/** @internal */
|
|
15
15
|
export { UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_NavigationContext, UNSAFE_LocationContext, UNSAFE_RouteContext, UNSAFE_useRouteId, } from "react-router";
|
|
16
16
|
declare global {
|
|
@@ -31,17 +31,14 @@ type ViewTransitionContextObject = {
|
|
|
31
31
|
isTransitioning: false;
|
|
32
32
|
} | {
|
|
33
33
|
isTransitioning: true;
|
|
34
|
+
flushSync: boolean;
|
|
34
35
|
currentLocation: Location;
|
|
35
36
|
nextLocation: Location;
|
|
36
37
|
};
|
|
37
38
|
declare const ViewTransitionContext: React.Context<ViewTransitionContextObject>;
|
|
38
39
|
export { ViewTransitionContext as UNSAFE_ViewTransitionContext };
|
|
39
|
-
type FetchersContextObject =
|
|
40
|
-
|
|
41
|
-
register: (key: string) => void;
|
|
42
|
-
unregister: (key: string) => void;
|
|
43
|
-
};
|
|
44
|
-
declare const FetchersContext: React.Context<FetchersContextObject | null>;
|
|
40
|
+
type FetchersContextObject = Map<string, any>;
|
|
41
|
+
declare const FetchersContext: React.Context<FetchersContextObject>;
|
|
45
42
|
export { FetchersContext as UNSAFE_FetchersContext };
|
|
46
43
|
interface ViewTransition {
|
|
47
44
|
finished: Promise<void>;
|
|
@@ -98,6 +95,7 @@ export interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEle
|
|
|
98
95
|
preventScrollReset?: boolean;
|
|
99
96
|
relative?: RelativeRoutingType;
|
|
100
97
|
to: To;
|
|
98
|
+
unstable_flushSync?: boolean;
|
|
101
99
|
unstable_viewTransition?: boolean;
|
|
102
100
|
}
|
|
103
101
|
/**
|
|
@@ -115,7 +113,6 @@ export interface NavLinkProps extends Omit<LinkProps, "className" | "style" | "c
|
|
|
115
113
|
className?: string | ((props: NavLinkRenderProps) => string | undefined);
|
|
116
114
|
end?: boolean;
|
|
117
115
|
style?: React.CSSProperties | ((props: NavLinkRenderProps) => React.CSSProperties | undefined);
|
|
118
|
-
unstable_viewTransition?: boolean;
|
|
119
116
|
}
|
|
120
117
|
/**
|
|
121
118
|
* A `<Link>` wrapper that knows if it's "active" or not.
|
|
@@ -176,6 +173,10 @@ export interface FormProps extends FetcherFormProps {
|
|
|
176
173
|
* State object to add to the history stack entry for this navigation
|
|
177
174
|
*/
|
|
178
175
|
state?: any;
|
|
176
|
+
/**
|
|
177
|
+
* Enable flushSync navigation's staten updates
|
|
178
|
+
*/
|
|
179
|
+
unstable_flushSync?: boolean;
|
|
179
180
|
/**
|
|
180
181
|
* Enable view transitions on this Form navigation
|
|
181
182
|
*/
|
|
@@ -205,12 +206,13 @@ export declare namespace ScrollRestoration {
|
|
|
205
206
|
* you need to create custom `<Link>` components with the same click behavior we
|
|
206
207
|
* use in our exported `<Link>`.
|
|
207
208
|
*/
|
|
208
|
-
export declare function useLinkClickHandler<E extends Element = HTMLAnchorElement>(to: To, { target, replace: replaceProp, state, preventScrollReset, relative, unstable_viewTransition, }?: {
|
|
209
|
+
export declare function useLinkClickHandler<E extends Element = HTMLAnchorElement>(to: To, { target, replace: replaceProp, state, preventScrollReset, relative, unstable_flushSync, unstable_viewTransition, }?: {
|
|
209
210
|
target?: React.HTMLAttributeAnchorTarget;
|
|
210
211
|
replace?: boolean;
|
|
211
212
|
state?: any;
|
|
212
213
|
preventScrollReset?: boolean;
|
|
213
214
|
relative?: RelativeRoutingType;
|
|
215
|
+
unstable_flushSync?: boolean;
|
|
214
216
|
unstable_viewTransition?: boolean;
|
|
215
217
|
}): (event: React.MouseEvent<E, MouseEvent>) => void;
|
|
216
218
|
/**
|
|
@@ -299,8 +301,8 @@ export declare function useBeforeUnload(callback: (event: BeforeUnloadEvent) =>
|
|
|
299
301
|
* very incorrectly in some cases) across browsers if user click addition
|
|
300
302
|
* back/forward navigations while the confirm is open. Use at your own risk.
|
|
301
303
|
*/
|
|
302
|
-
declare function usePrompt({ when, message }: {
|
|
303
|
-
when: boolean;
|
|
304
|
+
declare function usePrompt({ when, message, }: {
|
|
305
|
+
when: boolean | BlockerFunction;
|
|
304
306
|
message: string;
|
|
305
307
|
}): void;
|
|
306
308
|
export { usePrompt as unstable_usePrompt };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React Router DOM v0.0.0-experimental-
|
|
2
|
+
* React Router DOM v0.0.0-experimental-e192105b
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
11
|
import * as React from 'react';
|
|
12
|
-
import
|
|
13
|
-
|
|
12
|
+
import * as ReactDOM from 'react-dom';
|
|
13
|
+
import { UNSAFE_mapRouteProperties, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, Router, UNSAFE_useRoutesImpl, UNSAFE_NavigationContext, useHref, useResolvedPath, useLocation, useNavigate, createPath, UNSAFE_useRouteId, UNSAFE_RouteContext, useMatches, useNavigation, useBlocker } from 'react-router';
|
|
14
|
+
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, Routes, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, UNSAFE_useRouteId, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, resolvePath, useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes } from 'react-router';
|
|
14
15
|
import { stripBasename, UNSAFE_warning, createRouter, createBrowserHistory, createHashHistory, UNSAFE_ErrorResponseImpl, UNSAFE_invariant, joinPaths, IDLE_FETCHER, matchPath } from '@remix-run/router';
|
|
15
16
|
|
|
16
17
|
function _extends() {
|
|
@@ -206,9 +207,9 @@ function getFormSubmissionInfo(target, basename) {
|
|
|
206
207
|
};
|
|
207
208
|
}
|
|
208
209
|
|
|
209
|
-
const _excluded = ["onClick", "relative", "reloadDocument", "replace", "state", "target", "to", "preventScrollReset", "unstable_viewTransition"],
|
|
210
|
+
const _excluded = ["onClick", "relative", "reloadDocument", "replace", "state", "target", "to", "preventScrollReset", "unstable_flushSync", "unstable_viewTransition"],
|
|
210
211
|
_excluded2 = ["aria-current", "caseSensitive", "className", "end", "style", "to", "unstable_viewTransition", "children"],
|
|
211
|
-
_excluded3 = ["fetcherKey", "navigate", "reloadDocument", "replace", "state", "method", "action", "onSubmit", "relative", "preventScrollReset", "unstable_viewTransition"];
|
|
212
|
+
_excluded3 = ["fetcherKey", "navigate", "reloadDocument", "replace", "state", "method", "action", "onSubmit", "relative", "preventScrollReset", "unstable_flushSync", "unstable_viewTransition"];
|
|
212
213
|
function createBrowserRouter(routes, opts) {
|
|
213
214
|
return createRouter({
|
|
214
215
|
basename: opts == null ? void 0 : opts.basename,
|
|
@@ -294,7 +295,7 @@ const ViewTransitionContext = /*#__PURE__*/React.createContext({
|
|
|
294
295
|
if (process.env.NODE_ENV !== "production") {
|
|
295
296
|
ViewTransitionContext.displayName = "ViewTransition";
|
|
296
297
|
}
|
|
297
|
-
const FetchersContext = /*#__PURE__*/React.createContext(
|
|
298
|
+
const FetchersContext = /*#__PURE__*/React.createContext(new Map());
|
|
298
299
|
if (process.env.NODE_ENV !== "production") {
|
|
299
300
|
FetchersContext.displayName = "Fetchers";
|
|
300
301
|
}
|
|
@@ -325,6 +326,8 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
325
326
|
*/
|
|
326
327
|
const START_TRANSITION = "startTransition";
|
|
327
328
|
const startTransitionImpl = React[START_TRANSITION];
|
|
329
|
+
const FLUSH_SYNC = "flushSync";
|
|
330
|
+
const flushSyncImpl = ReactDOM[FLUSH_SYNC];
|
|
328
331
|
function startTransitionSafe(cb) {
|
|
329
332
|
if (startTransitionImpl) {
|
|
330
333
|
startTransitionImpl(cb);
|
|
@@ -332,6 +335,13 @@ function startTransitionSafe(cb) {
|
|
|
332
335
|
cb();
|
|
333
336
|
}
|
|
334
337
|
}
|
|
338
|
+
function flushSyncSafe(cb) {
|
|
339
|
+
if (flushSyncImpl) {
|
|
340
|
+
flushSyncImpl(cb);
|
|
341
|
+
} else {
|
|
342
|
+
cb();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
335
345
|
class Deferred {
|
|
336
346
|
constructor() {
|
|
337
347
|
this.status = "pending";
|
|
@@ -360,10 +370,6 @@ function RouterProvider(_ref) {
|
|
|
360
370
|
router,
|
|
361
371
|
future
|
|
362
372
|
} = _ref;
|
|
363
|
-
let {
|
|
364
|
-
fetcherContext,
|
|
365
|
-
fetcherData
|
|
366
|
-
} = useFetcherDataLayer();
|
|
367
373
|
let [state, setStateImpl] = React.useState(router.state);
|
|
368
374
|
let [pendingState, setPendingState] = React.useState();
|
|
369
375
|
let [vtContext, setVtContext] = React.useState({
|
|
@@ -372,6 +378,7 @@ function RouterProvider(_ref) {
|
|
|
372
378
|
let [renderDfd, setRenderDfd] = React.useState();
|
|
373
379
|
let [transition, setTransition] = React.useState();
|
|
374
380
|
let [interruption, setInterruption] = React.useState();
|
|
381
|
+
let fetcherData = React.useRef(new Map());
|
|
375
382
|
let {
|
|
376
383
|
v7_startTransition
|
|
377
384
|
} = future || {};
|
|
@@ -384,20 +391,66 @@ function RouterProvider(_ref) {
|
|
|
384
391
|
}, [v7_startTransition]);
|
|
385
392
|
let setState = React.useCallback((newState, _ref2) => {
|
|
386
393
|
let {
|
|
394
|
+
deletedFetchers,
|
|
395
|
+
unstable_flushSync: flushSync,
|
|
387
396
|
unstable_viewTransitionOpts: viewTransitionOpts
|
|
388
397
|
} = _ref2;
|
|
398
|
+
deletedFetchers.forEach(key => fetcherData.current.delete(key));
|
|
389
399
|
newState.fetchers.forEach((fetcher, key) => {
|
|
390
400
|
if (fetcher.data !== undefined) {
|
|
391
401
|
fetcherData.current.set(key, fetcher.data);
|
|
392
402
|
}
|
|
393
403
|
});
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
404
|
+
let isViewTransitionUnavailable = router.window == null || typeof router.window.document.startViewTransition !== "function";
|
|
405
|
+
// If this isn't a view transition or it's not available in this browser,
|
|
406
|
+
// just update and be done with it
|
|
407
|
+
if (!viewTransitionOpts || isViewTransitionUnavailable) {
|
|
408
|
+
if (flushSync) {
|
|
409
|
+
flushSyncSafe(() => setStateImpl(newState));
|
|
410
|
+
} else {
|
|
411
|
+
optInStartTransition(() => setStateImpl(newState));
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
// flushSync + startViewTransition
|
|
416
|
+
if (flushSync) {
|
|
417
|
+
// Flush through the context to mark DOM elements as transition=ing
|
|
418
|
+
flushSyncSafe(() => {
|
|
419
|
+
// Cancel any pending transitions
|
|
420
|
+
if (transition) {
|
|
421
|
+
renderDfd && renderDfd.resolve();
|
|
422
|
+
transition.skipTransition();
|
|
423
|
+
}
|
|
424
|
+
setVtContext({
|
|
425
|
+
isTransitioning: true,
|
|
426
|
+
flushSync: true,
|
|
427
|
+
currentLocation: viewTransitionOpts.currentLocation,
|
|
428
|
+
nextLocation: viewTransitionOpts.nextLocation
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
// Update the DOM
|
|
432
|
+
let t = router.window.document.startViewTransition(() => {
|
|
433
|
+
flushSyncSafe(() => setStateImpl(newState));
|
|
434
|
+
});
|
|
435
|
+
// Clean up after the animation completes
|
|
436
|
+
t.finished.finally(() => {
|
|
437
|
+
flushSyncSafe(() => {
|
|
438
|
+
setRenderDfd(undefined);
|
|
439
|
+
setTransition(undefined);
|
|
440
|
+
setPendingState(undefined);
|
|
441
|
+
setVtContext({
|
|
442
|
+
isTransitioning: false
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
flushSyncSafe(() => setTransition(t));
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
// startTransition + startViewTransition
|
|
450
|
+
if (transition) {
|
|
398
451
|
// Interrupting an in-progress transition, cancel and let everything flush
|
|
399
452
|
// out, and then kick off a new transition from the interruption state
|
|
400
|
-
renderDfd.resolve();
|
|
453
|
+
renderDfd && renderDfd.resolve();
|
|
401
454
|
transition.skipTransition();
|
|
402
455
|
setInterruption({
|
|
403
456
|
state: newState,
|
|
@@ -409,6 +462,7 @@ function RouterProvider(_ref) {
|
|
|
409
462
|
setPendingState(newState);
|
|
410
463
|
setVtContext({
|
|
411
464
|
isTransitioning: true,
|
|
465
|
+
flushSync: false,
|
|
412
466
|
currentLocation: viewTransitionOpts.currentLocation,
|
|
413
467
|
nextLocation: viewTransitionOpts.nextLocation
|
|
414
468
|
});
|
|
@@ -420,10 +474,10 @@ function RouterProvider(_ref) {
|
|
|
420
474
|
// When we start a view transition, create a Deferred we can use for the
|
|
421
475
|
// eventual "completed" render
|
|
422
476
|
React.useEffect(() => {
|
|
423
|
-
if (vtContext.isTransitioning) {
|
|
477
|
+
if (vtContext.isTransitioning && !vtContext.flushSync) {
|
|
424
478
|
setRenderDfd(new Deferred());
|
|
425
479
|
}
|
|
426
|
-
}, [vtContext
|
|
480
|
+
}, [vtContext]);
|
|
427
481
|
// Once the deferred is created, kick off startViewTransition() to update the
|
|
428
482
|
// DOM and then wait on the Deferred to resolve (indicating the DOM update has
|
|
429
483
|
// happened)
|
|
@@ -460,6 +514,7 @@ function RouterProvider(_ref) {
|
|
|
460
514
|
setPendingState(interruption.state);
|
|
461
515
|
setVtContext({
|
|
462
516
|
isTransitioning: true,
|
|
517
|
+
flushSync: false,
|
|
463
518
|
currentLocation: interruption.currentLocation,
|
|
464
519
|
nextLocation: interruption.nextLocation
|
|
465
520
|
});
|
|
@@ -500,7 +555,7 @@ function RouterProvider(_ref) {
|
|
|
500
555
|
}, /*#__PURE__*/React.createElement(UNSAFE_DataRouterStateContext.Provider, {
|
|
501
556
|
value: state
|
|
502
557
|
}, /*#__PURE__*/React.createElement(FetchersContext.Provider, {
|
|
503
|
-
value:
|
|
558
|
+
value: fetcherData.current
|
|
504
559
|
}, /*#__PURE__*/React.createElement(ViewTransitionContext.Provider, {
|
|
505
560
|
value: vtContext
|
|
506
561
|
}, /*#__PURE__*/React.createElement(Router, {
|
|
@@ -645,6 +700,7 @@ const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref7, ref) {
|
|
|
645
700
|
target,
|
|
646
701
|
to,
|
|
647
702
|
preventScrollReset,
|
|
703
|
+
unstable_flushSync,
|
|
648
704
|
unstable_viewTransition
|
|
649
705
|
} = _ref7,
|
|
650
706
|
rest = _objectWithoutPropertiesLoose(_ref7, _excluded);
|
|
@@ -685,6 +741,7 @@ const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref7, ref) {
|
|
|
685
741
|
target,
|
|
686
742
|
preventScrollReset,
|
|
687
743
|
relative,
|
|
744
|
+
unstable_flushSync,
|
|
688
745
|
unstable_viewTransition
|
|
689
746
|
});
|
|
690
747
|
function handleClick(event) {
|
|
@@ -742,7 +799,13 @@ const NavLink = /*#__PURE__*/React.forwardRef(function NavLinkWithRef(_ref8, ref
|
|
|
742
799
|
nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null;
|
|
743
800
|
toPathname = toPathname.toLowerCase();
|
|
744
801
|
}
|
|
745
|
-
|
|
802
|
+
// If the `to` has a trailing slash, look at that exact spot. Otherwise,
|
|
803
|
+
// we're looking for a slash _after_ what's in `to`. For example:
|
|
804
|
+
//
|
|
805
|
+
// <NavLink to="/users"> and <NavLink to="/users/">
|
|
806
|
+
// both want to look for a / at index 6 to match URL `/users/matt`
|
|
807
|
+
const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
|
|
808
|
+
let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
|
|
746
809
|
let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === "/");
|
|
747
810
|
let renderProps = {
|
|
748
811
|
isActive,
|
|
@@ -792,6 +855,7 @@ const Form = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
|
792
855
|
onSubmit,
|
|
793
856
|
relative,
|
|
794
857
|
preventScrollReset,
|
|
858
|
+
unstable_flushSync,
|
|
795
859
|
unstable_viewTransition
|
|
796
860
|
} = _ref9,
|
|
797
861
|
props = _objectWithoutPropertiesLoose(_ref9, _excluded3);
|
|
@@ -814,6 +878,7 @@ const Form = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
|
814
878
|
state,
|
|
815
879
|
relative,
|
|
816
880
|
preventScrollReset,
|
|
881
|
+
unstable_flushSync,
|
|
817
882
|
unstable_viewTransition
|
|
818
883
|
});
|
|
819
884
|
};
|
|
@@ -877,36 +942,6 @@ function useDataRouterState(hookName) {
|
|
|
877
942
|
!state ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
|
|
878
943
|
return state;
|
|
879
944
|
}
|
|
880
|
-
function useFetcherDataLayer() {
|
|
881
|
-
let fetcherRefs = React.useRef(new Map());
|
|
882
|
-
let fetcherData = React.useRef(new Map());
|
|
883
|
-
let registerFetcher = React.useCallback(key => {
|
|
884
|
-
let count = fetcherRefs.current.get(key);
|
|
885
|
-
if (count == null) {
|
|
886
|
-
fetcherRefs.current.set(key, 1);
|
|
887
|
-
} else {
|
|
888
|
-
fetcherRefs.current.set(key, count + 1);
|
|
889
|
-
}
|
|
890
|
-
}, [fetcherRefs]);
|
|
891
|
-
let unregisterFetcher = React.useCallback(key => {
|
|
892
|
-
let count = fetcherRefs.current.get(key);
|
|
893
|
-
if (count == null || count <= 1) {
|
|
894
|
-
fetcherRefs.current.delete(key);
|
|
895
|
-
fetcherData.current.delete(key);
|
|
896
|
-
} else {
|
|
897
|
-
fetcherRefs.current.set(key, count - 1);
|
|
898
|
-
}
|
|
899
|
-
}, [fetcherData, fetcherRefs]);
|
|
900
|
-
let fetcherContext = React.useMemo(() => ({
|
|
901
|
-
fetcherData: fetcherData.current,
|
|
902
|
-
register: registerFetcher,
|
|
903
|
-
unregister: unregisterFetcher
|
|
904
|
-
}), [fetcherData, registerFetcher, unregisterFetcher]);
|
|
905
|
-
return {
|
|
906
|
-
fetcherContext,
|
|
907
|
-
fetcherData
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
945
|
// External hooks
|
|
911
946
|
/**
|
|
912
947
|
* Handles the click behavior for router `<Link>` components. This is useful if
|
|
@@ -920,6 +955,7 @@ function useLinkClickHandler(to, _temp) {
|
|
|
920
955
|
state,
|
|
921
956
|
preventScrollReset,
|
|
922
957
|
relative,
|
|
958
|
+
unstable_flushSync,
|
|
923
959
|
unstable_viewTransition
|
|
924
960
|
} = _temp === void 0 ? {} : _temp;
|
|
925
961
|
let navigate = useNavigate();
|
|
@@ -938,10 +974,11 @@ function useLinkClickHandler(to, _temp) {
|
|
|
938
974
|
state,
|
|
939
975
|
preventScrollReset,
|
|
940
976
|
relative,
|
|
977
|
+
unstable_flushSync,
|
|
941
978
|
unstable_viewTransition
|
|
942
979
|
});
|
|
943
980
|
}
|
|
944
|
-
}, [location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, unstable_viewTransition]);
|
|
981
|
+
}, [location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, unstable_flushSync, unstable_viewTransition]);
|
|
945
982
|
}
|
|
946
983
|
/**
|
|
947
984
|
* A convenient wrapper for reading and writing search parameters via the
|
|
@@ -1003,7 +1040,8 @@ function useSubmit() {
|
|
|
1003
1040
|
formData,
|
|
1004
1041
|
body,
|
|
1005
1042
|
formMethod: options.method || method,
|
|
1006
|
-
formEncType: options.encType || encType
|
|
1043
|
+
formEncType: options.encType || encType,
|
|
1044
|
+
unstable_flushSync: options.unstable_flushSync
|
|
1007
1045
|
});
|
|
1008
1046
|
} else {
|
|
1009
1047
|
router.navigate(options.action || action, {
|
|
@@ -1015,6 +1053,7 @@ function useSubmit() {
|
|
|
1015
1053
|
replace: options.replace,
|
|
1016
1054
|
state: options.state,
|
|
1017
1055
|
fromRouteId: currentRouteId,
|
|
1056
|
+
unstable_flushSync: options.unstable_flushSync,
|
|
1018
1057
|
unstable_viewTransition: options.unstable_viewTransition
|
|
1019
1058
|
});
|
|
1020
1059
|
}
|
|
@@ -1037,10 +1076,8 @@ function useFormAction(action, _temp2) {
|
|
|
1037
1076
|
let path = _extends({}, useResolvedPath(action ? action : ".", {
|
|
1038
1077
|
relative
|
|
1039
1078
|
}));
|
|
1040
|
-
//
|
|
1041
|
-
//
|
|
1042
|
-
// the intended behavior of when "." is specifically provided as
|
|
1043
|
-
// the form action, but inconsistent w/ browsers when the action is omitted.
|
|
1079
|
+
// If no action was specified, browsers will persist current search params
|
|
1080
|
+
// when determining the path, so match that behavior
|
|
1044
1081
|
// https://github.com/remix-run/remix/issues/927
|
|
1045
1082
|
let location = useLocation();
|
|
1046
1083
|
if (action == null) {
|
|
@@ -1082,10 +1119,10 @@ function useFetcher(_temp3) {
|
|
|
1082
1119
|
router
|
|
1083
1120
|
} = useDataRouterContext(DataRouterHook.UseFetcher);
|
|
1084
1121
|
let state = useDataRouterState(DataRouterStateHook.UseFetcher);
|
|
1085
|
-
let
|
|
1122
|
+
let fetcherData = React.useContext(FetchersContext);
|
|
1086
1123
|
let route = React.useContext(UNSAFE_RouteContext);
|
|
1087
1124
|
let routeId = (_route$matches = route.matches[route.matches.length - 1]) == null ? void 0 : _route$matches.route.id;
|
|
1088
|
-
!
|
|
1125
|
+
!fetcherData ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher must be used inside a FetchersContext") : UNSAFE_invariant(false) : void 0;
|
|
1089
1126
|
!route ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher must be used inside a RouteContext") : UNSAFE_invariant(false) : void 0;
|
|
1090
1127
|
!(routeId != null) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher can only be used on routes that contain a unique \"id\"") : UNSAFE_invariant(false) : void 0;
|
|
1091
1128
|
// Fetcher key handling
|
|
@@ -1094,26 +1131,19 @@ function useFetcher(_temp3) {
|
|
|
1094
1131
|
setFetcherKey(getUniqueFetcherId());
|
|
1095
1132
|
}
|
|
1096
1133
|
// Registration/cleanup
|
|
1097
|
-
let {
|
|
1098
|
-
fetcherData,
|
|
1099
|
-
register,
|
|
1100
|
-
unregister
|
|
1101
|
-
} = fetchersContext;
|
|
1102
1134
|
React.useEffect(() => {
|
|
1103
|
-
|
|
1135
|
+
router.getFetcher(fetcherKey);
|
|
1104
1136
|
return () => {
|
|
1105
|
-
// Unregister from ref counting for the data layer
|
|
1106
|
-
unregister(fetcherKey);
|
|
1107
1137
|
// Tell the router we've unmounted - if v7_fetcherPersist is enabled this
|
|
1108
1138
|
// will not delete immediately but instead queue up a delete after the
|
|
1109
1139
|
// fetcher returns to an `idle` state
|
|
1110
1140
|
router.deleteFetcher(fetcherKey);
|
|
1111
1141
|
};
|
|
1112
|
-
}, [router, fetcherKey
|
|
1142
|
+
}, [router, fetcherKey]);
|
|
1113
1143
|
// Fetcher additions
|
|
1114
|
-
let load = React.useCallback(href => {
|
|
1144
|
+
let load = React.useCallback((href, opts) => {
|
|
1115
1145
|
!routeId ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "No routeId available for fetcher.load()") : UNSAFE_invariant(false) : void 0;
|
|
1116
|
-
router.fetch(fetcherKey, routeId, href);
|
|
1146
|
+
router.fetch(fetcherKey, routeId, href, opts);
|
|
1117
1147
|
}, [fetcherKey, routeId, router]);
|
|
1118
1148
|
let submitImpl = useSubmit();
|
|
1119
1149
|
let submit = React.useCallback((target, opts) => {
|
|
@@ -1312,7 +1342,7 @@ function usePrompt(_ref12) {
|
|
|
1312
1342
|
when,
|
|
1313
1343
|
message
|
|
1314
1344
|
} = _ref12;
|
|
1315
|
-
let blocker =
|
|
1345
|
+
let blocker = useBlocker(when);
|
|
1316
1346
|
React.useEffect(() => {
|
|
1317
1347
|
if (blocker.state === "blocked") {
|
|
1318
1348
|
let proceed = window.confirm(message);
|