react-router-dom-v5-compat 6.3.0 → 6.4.0-pre.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/LICENSE.md +1 -1
- package/index.d.ts +1 -1
- package/index.js +344 -106
- package/index.js.map +1 -1
- package/lib/components.d.ts +1 -1
- package/main.js +1 -1
- package/package.json +2 -2
- package/react-router-dom/dom.d.ts +68 -0
- package/react-router-dom/index.d.ts +114 -29
- package/umd/react-router-dom-v5-compat.development.js +354 -119
- package/umd/react-router-dom-v5-compat.development.js.map +1 -1
- package/umd/react-router-dom-v5-compat.production.min.js +2 -2
- package/umd/react-router-dom-v5-compat.production.min.js.map +1 -1
package/LICENSE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) React Training 2015-2019
|
|
4
|
-
Copyright (c) Remix Software 2020-
|
|
4
|
+
Copyright (c) Remix Software 2020-2022
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
package/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* - TSC needs to generate the types, and it has to derive the output paths from
|
|
26
26
|
* the import paths. If we have a weird require *outside of this package* to
|
|
27
27
|
* "../../react-router-dom" it's going to generate types from the common root
|
|
28
|
-
* of all module paths (Which makes sense
|
|
28
|
+
* of all module paths (Which makes sense because what else would it do? It
|
|
29
29
|
* needs to write the type files next to the source files so that typescript
|
|
30
30
|
* can resolve the types for tooling in the same location as the modules).
|
|
31
31
|
* Because tsc isn't as flexible as rollup, we have no control over this
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React Router DOM v5 Compat v6.
|
|
2
|
+
* React Router DOM v5 Compat v6.4.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
import { useRef, useState, useLayoutEffect, createElement, forwardRef, useCallback, useMemo } from 'react';
|
|
12
|
-
import {
|
|
13
|
-
import { Router, useHref, createPath, useLocation, useResolvedPath, useNavigate, Routes, Route } from 'react-router';
|
|
11
|
+
import { useRef, useState, useLayoutEffect, createElement, forwardRef, useCallback, useContext, useMemo } from 'react';
|
|
12
|
+
import { Router, useHref, createPath, useResolvedPath, useMatch, UNSAFE_DataRouterStateContext, useNavigate, useLocation, UNSAFE_DataRouterContext, UNSAFE_RouteContext, Routes, Route } from 'react-router';
|
|
14
13
|
export { MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, Routes, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, createPath, createRoutesFromChildren, generatePath, matchPath, matchRoutes, parsePath, renderMatches, resolvePath, useHref, useInRouterContext, useLocation, useMatch, useNavigate, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes } from 'react-router';
|
|
14
|
+
import { createBrowserHistory, createHashHistory, matchPath, invariant } from '@remix-run/router';
|
|
15
|
+
import { parsePath, Action, createPath as createPath$1 } from 'history';
|
|
15
16
|
import { Route as Route$1, useHistory } from 'react-router-dom';
|
|
16
17
|
|
|
17
18
|
function _extends() {
|
|
@@ -47,41 +48,175 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
47
48
|
return target;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
const
|
|
51
|
-
|
|
51
|
+
const defaultMethod = "get";
|
|
52
|
+
const defaultEncType = "application/x-www-form-urlencoded";
|
|
53
|
+
function isHtmlElement(object) {
|
|
54
|
+
return object != null && typeof object.tagName === "string";
|
|
55
|
+
}
|
|
56
|
+
function isButtonElement(object) {
|
|
57
|
+
return isHtmlElement(object) && object.tagName.toLowerCase() === "button";
|
|
58
|
+
}
|
|
59
|
+
function isFormElement(object) {
|
|
60
|
+
return isHtmlElement(object) && object.tagName.toLowerCase() === "form";
|
|
61
|
+
}
|
|
62
|
+
function isInputElement(object) {
|
|
63
|
+
return isHtmlElement(object) && object.tagName.toLowerCase() === "input";
|
|
64
|
+
}
|
|
52
65
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (typeof console !== "undefined") console.warn(message);
|
|
66
|
+
function isModifiedEvent(event) {
|
|
67
|
+
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
|
68
|
+
}
|
|
57
69
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
function shouldProcessLinkClick(event, target) {
|
|
71
|
+
return event.button === 0 && ( // Ignore everything but left clicks
|
|
72
|
+
!target || target === "_self") && // Let browser handle "target=_blank" etc.
|
|
73
|
+
!isModifiedEvent(event) // Ignore clicks with modifier keys
|
|
74
|
+
;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a URLSearchParams object using the given initializer.
|
|
79
|
+
*
|
|
80
|
+
* This is identical to `new URLSearchParams(init)` except it also
|
|
81
|
+
* supports arrays as values in the object form of the initializer
|
|
82
|
+
* instead of just strings. This is convenient when you need multiple
|
|
83
|
+
* values for a given key, but don't want to use an array initializer.
|
|
84
|
+
*
|
|
85
|
+
* For example, instead of:
|
|
86
|
+
*
|
|
87
|
+
* let searchParams = new URLSearchParams([
|
|
88
|
+
* ['sort', 'name'],
|
|
89
|
+
* ['sort', 'price']
|
|
90
|
+
* ]);
|
|
91
|
+
*
|
|
92
|
+
* you can do:
|
|
93
|
+
*
|
|
94
|
+
* let searchParams = createSearchParams({
|
|
95
|
+
* sort: ['name', 'price']
|
|
96
|
+
* });
|
|
97
|
+
*/
|
|
98
|
+
function createSearchParams(init) {
|
|
99
|
+
if (init === void 0) {
|
|
100
|
+
init = "";
|
|
66
101
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
102
|
+
|
|
103
|
+
return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
|
|
104
|
+
let value = init[key];
|
|
105
|
+
return memo.concat(Array.isArray(value) ? value.map(v => [key, v]) : [[key, value]]);
|
|
106
|
+
}, []));
|
|
107
|
+
}
|
|
108
|
+
function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
|
|
109
|
+
let searchParams = createSearchParams(locationSearch);
|
|
110
|
+
|
|
111
|
+
for (let key of defaultSearchParams.keys()) {
|
|
112
|
+
if (!searchParams.has(key)) {
|
|
113
|
+
defaultSearchParams.getAll(key).forEach(value => {
|
|
114
|
+
searchParams.append(key, value);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return searchParams;
|
|
120
|
+
}
|
|
121
|
+
function getFormSubmissionInfo(target, defaultAction, options) {
|
|
122
|
+
let method;
|
|
123
|
+
let action;
|
|
124
|
+
let encType;
|
|
125
|
+
let formData;
|
|
126
|
+
|
|
127
|
+
if (isFormElement(target)) {
|
|
128
|
+
let submissionTrigger = options.submissionTrigger;
|
|
129
|
+
method = options.method || target.getAttribute("method") || defaultMethod;
|
|
130
|
+
action = options.action || target.getAttribute("action") || defaultAction;
|
|
131
|
+
encType = options.encType || target.getAttribute("enctype") || defaultEncType;
|
|
132
|
+
formData = new FormData(target);
|
|
133
|
+
|
|
134
|
+
if (submissionTrigger && submissionTrigger.name) {
|
|
135
|
+
formData.append(submissionTrigger.name, submissionTrigger.value);
|
|
136
|
+
}
|
|
137
|
+
} else if (isButtonElement(target) || isInputElement(target) && (target.type === "submit" || target.type === "image")) {
|
|
138
|
+
let form = target.form;
|
|
139
|
+
|
|
140
|
+
if (form == null) {
|
|
141
|
+
throw new Error("Cannot submit a <button> or <input type=\"submit\"> without a <form>");
|
|
142
|
+
} // <button>/<input type="submit"> may override attributes of <form>
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
method = options.method || target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod;
|
|
146
|
+
action = options.action || target.getAttribute("formaction") || form.getAttribute("action") || defaultAction;
|
|
147
|
+
encType = options.encType || target.getAttribute("formenctype") || form.getAttribute("enctype") || defaultEncType;
|
|
148
|
+
formData = new FormData(form); // Include name + value from a <button>
|
|
149
|
+
|
|
150
|
+
if (target.name) {
|
|
151
|
+
formData.set(target.name, target.value);
|
|
152
|
+
}
|
|
153
|
+
} else if (isHtmlElement(target)) {
|
|
154
|
+
throw new Error("Cannot submit element that is not <form>, <button>, or " + "<input type=\"submit|image\">");
|
|
155
|
+
} else {
|
|
156
|
+
method = options.method || defaultMethod;
|
|
157
|
+
action = options.action || defaultAction;
|
|
158
|
+
encType = options.encType || defaultEncType;
|
|
159
|
+
|
|
160
|
+
if (target instanceof FormData) {
|
|
161
|
+
formData = target;
|
|
162
|
+
} else {
|
|
163
|
+
formData = new FormData();
|
|
164
|
+
|
|
165
|
+
if (target instanceof URLSearchParams) {
|
|
166
|
+
for (let [name, value] of target) {
|
|
167
|
+
formData.append(name, value);
|
|
168
|
+
}
|
|
169
|
+
} else if (target != null) {
|
|
170
|
+
for (let name of Object.keys(target)) {
|
|
171
|
+
formData.append(name, target[name]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let {
|
|
178
|
+
protocol,
|
|
179
|
+
host
|
|
180
|
+
} = window.location;
|
|
181
|
+
let url = new URL(action, protocol + "//" + host);
|
|
182
|
+
|
|
183
|
+
if (method.toLowerCase() === "get") {
|
|
184
|
+
for (let [name, value] of formData) {
|
|
185
|
+
if (typeof value === "string") {
|
|
186
|
+
url.searchParams.append(name, value);
|
|
187
|
+
} else {
|
|
188
|
+
throw new Error("Cannot submit binary form data using GET");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
url,
|
|
195
|
+
method,
|
|
196
|
+
encType,
|
|
197
|
+
formData
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const _excluded = ["onClick", "reloadDocument", "replace", "state", "target", "to", "resetScroll"],
|
|
202
|
+
_excluded2 = ["aria-current", "caseSensitive", "className", "end", "style", "to", "children"],
|
|
203
|
+
_excluded3 = ["replace", "method", "action", "onSubmit", "fetcherKey"];
|
|
70
204
|
|
|
71
205
|
/**
|
|
72
206
|
* A `<Router>` for use in web browsers. Provides the cleanest URLs.
|
|
73
207
|
*/
|
|
74
|
-
function BrowserRouter(
|
|
208
|
+
function BrowserRouter(_ref3) {
|
|
75
209
|
let {
|
|
76
210
|
basename,
|
|
77
211
|
children,
|
|
78
212
|
window
|
|
79
|
-
} =
|
|
213
|
+
} = _ref3;
|
|
80
214
|
let historyRef = useRef();
|
|
81
215
|
|
|
82
216
|
if (historyRef.current == null) {
|
|
83
217
|
historyRef.current = createBrowserHistory({
|
|
84
|
-
window
|
|
218
|
+
window,
|
|
219
|
+
v5Compat: true
|
|
85
220
|
});
|
|
86
221
|
}
|
|
87
222
|
|
|
@@ -104,17 +239,18 @@ function BrowserRouter(_ref) {
|
|
|
104
239
|
* A `<Router>` for use in web browsers. Stores the location in the hash
|
|
105
240
|
* portion of the URL so it is not sent to the server.
|
|
106
241
|
*/
|
|
107
|
-
function HashRouter(
|
|
242
|
+
function HashRouter(_ref4) {
|
|
108
243
|
let {
|
|
109
244
|
basename,
|
|
110
245
|
children,
|
|
111
246
|
window
|
|
112
|
-
} =
|
|
247
|
+
} = _ref4;
|
|
113
248
|
let historyRef = useRef();
|
|
114
249
|
|
|
115
250
|
if (historyRef.current == null) {
|
|
116
251
|
historyRef.current = createHashHistory({
|
|
117
|
-
window
|
|
252
|
+
window,
|
|
253
|
+
v5Compat: true
|
|
118
254
|
});
|
|
119
255
|
}
|
|
120
256
|
|
|
@@ -139,12 +275,12 @@ function HashRouter(_ref2) {
|
|
|
139
275
|
* two versions of the history library to your bundles unless you use the same
|
|
140
276
|
* version of the history library that React Router uses internally.
|
|
141
277
|
*/
|
|
142
|
-
function HistoryRouter(
|
|
278
|
+
function HistoryRouter(_ref5) {
|
|
143
279
|
let {
|
|
144
280
|
basename,
|
|
145
281
|
children,
|
|
146
282
|
history
|
|
147
|
-
} =
|
|
283
|
+
} = _ref5;
|
|
148
284
|
const [state, setState] = useState({
|
|
149
285
|
action: history.action,
|
|
150
286
|
location: history.location
|
|
@@ -163,29 +299,27 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
163
299
|
HistoryRouter.displayName = "unstable_HistoryRouter";
|
|
164
300
|
}
|
|
165
301
|
|
|
166
|
-
function isModifiedEvent(event) {
|
|
167
|
-
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
302
|
/**
|
|
171
303
|
* The public API for rendering a history-aware <a>.
|
|
172
304
|
*/
|
|
173
|
-
const Link = /*#__PURE__*/forwardRef(function LinkWithRef(
|
|
305
|
+
const Link = /*#__PURE__*/forwardRef(function LinkWithRef(_ref6, ref) {
|
|
174
306
|
let {
|
|
175
307
|
onClick,
|
|
176
308
|
reloadDocument,
|
|
177
309
|
replace = false,
|
|
178
310
|
state,
|
|
179
311
|
target,
|
|
180
|
-
to
|
|
181
|
-
|
|
182
|
-
|
|
312
|
+
to,
|
|
313
|
+
resetScroll
|
|
314
|
+
} = _ref6,
|
|
315
|
+
rest = _objectWithoutPropertiesLoose(_ref6, _excluded);
|
|
183
316
|
|
|
184
317
|
let href = useHref(to);
|
|
185
318
|
let internalOnClick = useLinkClickHandler(to, {
|
|
186
319
|
replace,
|
|
187
320
|
state,
|
|
188
|
-
target
|
|
321
|
+
target,
|
|
322
|
+
resetScroll
|
|
189
323
|
});
|
|
190
324
|
|
|
191
325
|
function handleClick(event) {
|
|
@@ -215,7 +349,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
215
349
|
/**
|
|
216
350
|
* A <Link> wrapper that knows if it's "active" or not.
|
|
217
351
|
*/
|
|
218
|
-
const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef(
|
|
352
|
+
const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef(_ref7, ref) {
|
|
219
353
|
let {
|
|
220
354
|
"aria-current": ariaCurrentProp = "page",
|
|
221
355
|
caseSensitive = false,
|
|
@@ -224,26 +358,32 @@ const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef(_ref5, ref) {
|
|
|
224
358
|
style: styleProp,
|
|
225
359
|
to,
|
|
226
360
|
children
|
|
227
|
-
} =
|
|
228
|
-
rest = _objectWithoutPropertiesLoose(
|
|
361
|
+
} = _ref7,
|
|
362
|
+
rest = _objectWithoutPropertiesLoose(_ref7, _excluded2);
|
|
229
363
|
|
|
230
|
-
let location = useLocation();
|
|
231
364
|
let path = useResolvedPath(to);
|
|
232
|
-
let
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
let
|
|
365
|
+
let match = useMatch({
|
|
366
|
+
path: path.pathname,
|
|
367
|
+
end,
|
|
368
|
+
caseSensitive
|
|
369
|
+
});
|
|
370
|
+
let routerState = useContext(UNSAFE_DataRouterStateContext);
|
|
371
|
+
let nextLocation = routerState == null ? void 0 : routerState.navigation.location;
|
|
372
|
+
let nextPath = useResolvedPath(nextLocation || "");
|
|
373
|
+
let nextMatch = useMemo(() => nextLocation ? matchPath({
|
|
374
|
+
path: path.pathname,
|
|
375
|
+
end,
|
|
376
|
+
caseSensitive
|
|
377
|
+
}, nextPath.pathname) : null, [nextLocation, path.pathname, caseSensitive, end, nextPath.pathname]);
|
|
378
|
+
let isPending = nextMatch != null;
|
|
379
|
+
let isActive = match != null;
|
|
241
380
|
let ariaCurrent = isActive ? ariaCurrentProp : undefined;
|
|
242
381
|
let className;
|
|
243
382
|
|
|
244
383
|
if (typeof classNameProp === "function") {
|
|
245
384
|
className = classNameProp({
|
|
246
|
-
isActive
|
|
385
|
+
isActive,
|
|
386
|
+
isPending
|
|
247
387
|
});
|
|
248
388
|
} else {
|
|
249
389
|
// If the className prop is not a function, we use a default `active`
|
|
@@ -251,11 +391,12 @@ const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef(_ref5, ref) {
|
|
|
251
391
|
// value for `activeClassName`, but we are removing that API and can still
|
|
252
392
|
// use the old default behavior for a cleaner upgrade path and keep the
|
|
253
393
|
// simple styling rules working as they currently do.
|
|
254
|
-
className = [classNameProp, isActive ? "active" : null].filter(Boolean).join(" ");
|
|
394
|
+
className = [classNameProp, isActive ? "active" : null, isPending ? "pending" : null].filter(Boolean).join(" ");
|
|
255
395
|
}
|
|
256
396
|
|
|
257
397
|
let style = typeof styleProp === "function" ? styleProp({
|
|
258
|
-
isActive
|
|
398
|
+
isActive,
|
|
399
|
+
isPending
|
|
259
400
|
}) : styleProp;
|
|
260
401
|
return /*#__PURE__*/createElement(Link, _extends({}, rest, {
|
|
261
402
|
"aria-current": ariaCurrent,
|
|
@@ -264,14 +405,71 @@ const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef(_ref5, ref) {
|
|
|
264
405
|
style: style,
|
|
265
406
|
to: to
|
|
266
407
|
}), typeof children === "function" ? children({
|
|
267
|
-
isActive
|
|
408
|
+
isActive,
|
|
409
|
+
isPending
|
|
268
410
|
}) : children);
|
|
269
411
|
});
|
|
270
412
|
|
|
271
413
|
if (process.env.NODE_ENV !== "production") {
|
|
272
414
|
NavLink.displayName = "NavLink";
|
|
273
|
-
}
|
|
274
|
-
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* A `@remix-run/router`-aware `<form>`. It behaves like a normal form except
|
|
419
|
+
* that the interaction with the server is with `fetch` instead of new document
|
|
420
|
+
* requests, allowing components to add nicer UX to the page as the form is
|
|
421
|
+
* submitted and returns with data.
|
|
422
|
+
*/
|
|
423
|
+
const Form = /*#__PURE__*/forwardRef((props, ref) => {
|
|
424
|
+
return /*#__PURE__*/createElement(FormImpl, _extends({}, props, {
|
|
425
|
+
ref: ref
|
|
426
|
+
}));
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
if (process.env.NODE_ENV !== "production") {
|
|
430
|
+
Form.displayName = "Form";
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const FormImpl = /*#__PURE__*/forwardRef((_ref8, forwardedRef) => {
|
|
434
|
+
let {
|
|
435
|
+
replace,
|
|
436
|
+
method = defaultMethod,
|
|
437
|
+
action = ".",
|
|
438
|
+
onSubmit,
|
|
439
|
+
fetcherKey
|
|
440
|
+
} = _ref8,
|
|
441
|
+
props = _objectWithoutPropertiesLoose(_ref8, _excluded3);
|
|
442
|
+
|
|
443
|
+
let submit = useSubmitImpl(fetcherKey);
|
|
444
|
+
let formMethod = method.toLowerCase() === "get" ? "get" : "post";
|
|
445
|
+
let formAction = useFormAction(action);
|
|
446
|
+
|
|
447
|
+
let submitHandler = event => {
|
|
448
|
+
onSubmit && onSubmit(event);
|
|
449
|
+
if (event.defaultPrevented) return;
|
|
450
|
+
event.preventDefault();
|
|
451
|
+
let submitter = event.nativeEvent.submitter;
|
|
452
|
+
submit(submitter || event.currentTarget, {
|
|
453
|
+
method,
|
|
454
|
+
replace
|
|
455
|
+
});
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
return /*#__PURE__*/createElement("form", _extends({
|
|
459
|
+
ref: forwardedRef,
|
|
460
|
+
method: formMethod,
|
|
461
|
+
action: formAction,
|
|
462
|
+
onSubmit: submitHandler
|
|
463
|
+
}, props));
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
if (process.env.NODE_ENV !== "production") {
|
|
467
|
+
Form.displayName = "Form";
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (process.env.NODE_ENV !== "production") ; //#endregion
|
|
471
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
472
|
+
//#region Hooks
|
|
275
473
|
////////////////////////////////////////////////////////////////////////////////
|
|
276
474
|
|
|
277
475
|
/**
|
|
@@ -285,26 +483,32 @@ function useLinkClickHandler(to, _temp) {
|
|
|
285
483
|
let {
|
|
286
484
|
target,
|
|
287
485
|
replace: replaceProp,
|
|
288
|
-
state
|
|
486
|
+
state,
|
|
487
|
+
resetScroll
|
|
289
488
|
} = _temp === void 0 ? {} : _temp;
|
|
290
489
|
let navigate = useNavigate();
|
|
291
490
|
let location = useLocation();
|
|
292
491
|
let path = useResolvedPath(to);
|
|
293
492
|
return useCallback(event => {
|
|
294
|
-
if (event
|
|
295
|
-
!target || target === "_self") && // Let browser handle "target=_blank" etc.
|
|
296
|
-
!isModifiedEvent(event) // Ignore clicks with modifier keys
|
|
297
|
-
) {
|
|
493
|
+
if (shouldProcessLinkClick(event, target)) {
|
|
298
494
|
event.preventDefault(); // If the URL hasn't changed, a regular <a> will do a replace instead of
|
|
299
495
|
// a push, so do the same here.
|
|
300
496
|
|
|
301
497
|
let replace = !!replaceProp || createPath(location) === createPath(path);
|
|
498
|
+
let newState = state;
|
|
499
|
+
|
|
500
|
+
if (resetScroll === false) {
|
|
501
|
+
newState = _extends({}, state, {
|
|
502
|
+
__resetScrollPosition: false
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
|
|
302
506
|
navigate(to, {
|
|
303
507
|
replace,
|
|
304
|
-
state
|
|
508
|
+
state: newState
|
|
305
509
|
});
|
|
306
510
|
}
|
|
307
|
-
}, [location, navigate, path, replaceProp, state, target, to]);
|
|
511
|
+
}, [location, navigate, path, replaceProp, state, target, to, resetScroll]);
|
|
308
512
|
}
|
|
309
513
|
/**
|
|
310
514
|
* A convenient wrapper for reading and writing search parameters via the
|
|
@@ -315,19 +519,7 @@ function useSearchParams(defaultInit) {
|
|
|
315
519
|
process.env.NODE_ENV !== "production" ? warning(typeof URLSearchParams !== "undefined", "You cannot use the `useSearchParams` hook in a browser that does not " + "support the URLSearchParams API. If you need to support Internet " + "Explorer 11, we recommend you load a polyfill such as " + "https://github.com/ungap/url-search-params\n\n" + "If you're unsure how to load polyfills, we recommend you check out " + "https://polyfill.io/v3/ which provides some recommendations about how " + "to load polyfills only for users that need them, instead of for every " + "user.") : void 0;
|
|
316
520
|
let defaultSearchParamsRef = useRef(createSearchParams(defaultInit));
|
|
317
521
|
let location = useLocation();
|
|
318
|
-
let searchParams = useMemo(() =>
|
|
319
|
-
let searchParams = createSearchParams(location.search);
|
|
320
|
-
|
|
321
|
-
for (let key of defaultSearchParamsRef.current.keys()) {
|
|
322
|
-
if (!searchParams.has(key)) {
|
|
323
|
-
defaultSearchParamsRef.current.getAll(key).forEach(value => {
|
|
324
|
-
searchParams.append(key, value);
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return searchParams;
|
|
330
|
-
}, [location.search]);
|
|
522
|
+
let searchParams = useMemo(() => getSearchParamsForLocation(location.search, defaultSearchParamsRef.current), [location.search]);
|
|
331
523
|
let navigate = useNavigate();
|
|
332
524
|
let setSearchParams = useCallback((nextInit, navigateOptions) => {
|
|
333
525
|
navigate("?" + createSearchParams(nextInit), navigateOptions);
|
|
@@ -335,37 +527,83 @@ function useSearchParams(defaultInit) {
|
|
|
335
527
|
return [searchParams, setSearchParams];
|
|
336
528
|
}
|
|
337
529
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
530
|
+
function useSubmitImpl(fetcherKey) {
|
|
531
|
+
let router = useContext(UNSAFE_DataRouterContext);
|
|
532
|
+
let defaultAction = useFormAction();
|
|
533
|
+
return useCallback(function (target, options) {
|
|
534
|
+
if (options === void 0) {
|
|
535
|
+
options = {};
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
!(router != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "useSubmit() must be used within a <DataRouter>") : invariant(false) : void 0;
|
|
539
|
+
|
|
540
|
+
if (typeof document === "undefined") {
|
|
541
|
+
throw new Error("You are calling submit during the server render. " + "Try calling submit within a `useEffect` or callback instead.");
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
let {
|
|
545
|
+
method,
|
|
546
|
+
encType,
|
|
547
|
+
formData,
|
|
548
|
+
url
|
|
549
|
+
} = getFormSubmissionInfo(target, defaultAction, options);
|
|
550
|
+
let href = url.pathname + url.search;
|
|
551
|
+
let opts = {
|
|
552
|
+
// If replace is not specified, we'll default to false for GET and
|
|
553
|
+
// true otherwise
|
|
554
|
+
replace: options.replace != null ? options.replace === true : method !== "get",
|
|
555
|
+
formData,
|
|
556
|
+
formMethod: method,
|
|
557
|
+
formEncType: encType
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
if (fetcherKey) {
|
|
561
|
+
router.fetch(fetcherKey, href, opts);
|
|
562
|
+
} else {
|
|
563
|
+
router.navigate(href, opts);
|
|
564
|
+
}
|
|
565
|
+
}, [defaultAction, router, fetcherKey]);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function useFormAction(action) {
|
|
569
|
+
if (action === void 0) {
|
|
570
|
+
action = ".";
|
|
362
571
|
}
|
|
363
572
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
573
|
+
let routeContext = useContext(UNSAFE_RouteContext);
|
|
574
|
+
!routeContext ? process.env.NODE_ENV !== "production" ? invariant(false, "useLoaderData must be used inside a RouteContext") : invariant(false) : void 0;
|
|
575
|
+
let [match] = routeContext.matches.slice(-1);
|
|
576
|
+
let {
|
|
577
|
+
pathname,
|
|
578
|
+
search
|
|
579
|
+
} = useResolvedPath(action);
|
|
580
|
+
|
|
581
|
+
if (action === "." && match.route.index) {
|
|
582
|
+
search = search ? search.replace(/^\?/, "?index&") : "?index";
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return pathname + search;
|
|
368
586
|
}
|
|
587
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
588
|
+
//#region Utils
|
|
589
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
function warning(cond, message) {
|
|
593
|
+
if (!cond) {
|
|
594
|
+
// eslint-disable-next-line no-console
|
|
595
|
+
if (typeof console !== "undefined") console.warn(message);
|
|
596
|
+
|
|
597
|
+
try {
|
|
598
|
+
// Welcome to debugging React Router!
|
|
599
|
+
//
|
|
600
|
+
// This error is thrown as a convenience so you can more easily
|
|
601
|
+
// find the source for a warning that appears in the console by
|
|
602
|
+
// enabling "pause on exceptions" in your JavaScript debugger.
|
|
603
|
+
throw new Error(message); // eslint-disable-next-line no-empty
|
|
604
|
+
} catch (e) {}
|
|
605
|
+
}
|
|
606
|
+
} //#endregion
|
|
369
607
|
|
|
370
608
|
// but not worried about that for now.
|
|
371
609
|
|
|
@@ -405,7 +643,7 @@ function CompatRouter(_ref) {
|
|
|
405
643
|
}
|
|
406
644
|
|
|
407
645
|
/**
|
|
408
|
-
* A <Router> that may not
|
|
646
|
+
* A <Router> that may not navigate to any other location. This is useful
|
|
409
647
|
* on the server where there is no stateful UI.
|
|
410
648
|
*/
|
|
411
649
|
function StaticRouter(_ref2) {
|