File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
/**
* React Router DOM v6.3.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
import { useRef, useState, useLayoutEffect, createElement, forwardRef, useCallback, useMemo } from 'react';
import { createBrowserHistory, createHashHistory } from 'history';
import { Router, useHref, createPath, useLocation, useResolvedPath, useNavigate } from 'react-router';
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';
/**
* NOTE: If you refactor this to split up the modules into separate files,
* you'll need to update the rollup config for react-router-dom-v5-compat.
*/
function warning(cond, message) {
if (!cond) {
// eslint-disable-next-line no-console
if (typeof console !== "undefined") console.warn(message);
try {
// Welcome to debugging React Router!
//
// This error is thrown as a convenience so you can more easily
// find the source for a warning that appears in the console by
// enabling "pause on exceptions" in your JavaScript debugger.
throw new Error(message); // eslint-disable-next-line no-empty
} catch (e) {}
}
} ////////////////////////////////////////////////////////////////////////////////
// COMPONENTS
////////////////////////////////////////////////////////////////////////////////
/**
* A `<Router>` for use in web browsers. Provides the cleanest URLs.
*/
function BrowserRouter({
basename,
children,
window
}) {
let historyRef = useRef();
if (historyRef.current == null) {
historyRef.current = createBrowserHistory({
window
});
}
let history = historyRef.current;
let [state, setState] = useState({
action: history.action,
location: history.location
});
useLayoutEffect(() => history.listen(setState), [history]);
return /*#__PURE__*/createElement(Router, {
basename: basename,
children: children,
location: state.location,
navigationType: state.action,
navigator: history
});
}
/**
* A `<Router>` for use in web browsers. Stores the location in the hash
* portion of the URL so it is not sent to the server.
*/
function HashRouter({
basename,
children,
window
}) {
let historyRef = useRef();
if (historyRef.current == null) {
historyRef.current = createHashHistory({
window
});
}
let history = historyRef.current;
let [state, setState] = useState({
action: history.action,
location: history.location
});
useLayoutEffect(() => history.listen(setState), [history]);
return /*#__PURE__*/createElement(Router, {
basename: basename,
children: children,
location: state.location,
navigationType: state.action,
navigator: history
});
}
/**
* A `<Router>` that accepts a pre-instantiated history object. It's important
* to note that using your own history object is highly discouraged and may add
* two versions of the history library to your bundles unless you use the same
* version of the history library that React Router uses internally.
*/
function HistoryRouter({
basename,
children,
history
}) {
const [state, setState] = useState({
action: history.action,
location: history.location
});
useLayoutEffect(() => history.listen(setState), [history]);
return /*#__PURE__*/createElement(Router, {
basename: basename,
children: children,
location: state.location,
navigationType: state.action,
navigator: history
});
}
{
HistoryRouter.displayName = "unstable_HistoryRouter";
}
function isModifiedEvent(event) {
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
}
/**
* The public API for rendering a history-aware <a>.
*/
const Link = /*#__PURE__*/forwardRef(function LinkWithRef({
onClick,
reloadDocument,
replace = false,
state,
target,
to,
...rest
}, ref) {
let href = useHref(to);
let internalOnClick = useLinkClickHandler(to, {
replace,
state,
target
});
function handleClick(event) {
if (onClick) onClick(event);
if (!event.defaultPrevented && !reloadDocument) {
internalOnClick(event);
}
}
return (
/*#__PURE__*/
// eslint-disable-next-line jsx-a11y/anchor-has-content
createElement("a", Object.assign({}, rest, {
href: href,
onClick: handleClick,
ref: ref,
target: target
}))
);
});
{
Link.displayName = "Link";
}
/**
* A <Link> wrapper that knows if it's "active" or not.
*/
const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef({
"aria-current": ariaCurrentProp = "page",
caseSensitive = false,
className: classNameProp = "",
end = false,
style: styleProp,
to,
children,
...rest
}, ref) {
let location = useLocation();
let path = useResolvedPath(to);
let locationPathname = location.pathname;
let toPathname = path.pathname;
if (!caseSensitive) {
locationPathname = locationPathname.toLowerCase();
toPathname = toPathname.toLowerCase();
}
let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(toPathname.length) === "/";
let ariaCurrent = isActive ? ariaCurrentProp : undefined;
let className;
if (typeof classNameProp === "function") {
className = classNameProp({
isActive
});
} else {
// If the className prop is not a function, we use a default `active`
// class for <NavLink />s that are active. In v5 `active` was the default
// value for `activeClassName`, but we are removing that API and can still
// use the old default behavior for a cleaner upgrade path and keep the
// simple styling rules working as they currently do.
className = [classNameProp, isActive ? "active" : null].filter(Boolean).join(" ");
}
let style = typeof styleProp === "function" ? styleProp({
isActive
}) : styleProp;
return /*#__PURE__*/createElement(Link, Object.assign({}, rest, {
"aria-current": ariaCurrent,
className: className,
ref: ref,
style: style,
to: to
}), typeof children === "function" ? children({
isActive
}) : children);
});
{
NavLink.displayName = "NavLink";
} ////////////////////////////////////////////////////////////////////////////////
// HOOKS
////////////////////////////////////////////////////////////////////////////////
/**
* Handles the click behavior for router `<Link>` components. This is useful if
* you need to create custom `<Link>` components with the same click behavior we
* use in our exported `<Link>`.
*/
function useLinkClickHandler(to, {
target,
replace: replaceProp,
state
} = {}) {
let navigate = useNavigate();
let location = useLocation();
let path = useResolvedPath(to);
return useCallback(event => {
if (event.button === 0 && ( // Ignore everything but left clicks
!target || target === "_self") && // Let browser handle "target=_blank" etc.
!isModifiedEvent(event) // Ignore clicks with modifier keys
) {
event.preventDefault(); // If the URL hasn't changed, a regular <a> will do a replace instead of
// a push, so do the same here.
let replace = !!replaceProp || createPath(location) === createPath(path);
navigate(to, {
replace,
state
});
}
}, [location, navigate, path, replaceProp, state, target, to]);
}
/**
* A convenient wrapper for reading and writing search parameters via the
* URLSearchParams interface.
*/
function useSearchParams(defaultInit) {
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.`) ;
let defaultSearchParamsRef = useRef(createSearchParams(defaultInit));
let location = useLocation();
let searchParams = useMemo(() => {
let searchParams = createSearchParams(location.search);
for (let key of defaultSearchParamsRef.current.keys()) {
if (!searchParams.has(key)) {
defaultSearchParamsRef.current.getAll(key).forEach(value => {
searchParams.append(key, value);
});
}
}
return searchParams;
}, [location.search]);
let navigate = useNavigate();
let setSearchParams = useCallback((nextInit, navigateOptions) => {
navigate("?" + createSearchParams(nextInit), navigateOptions);
}, [navigate]);
return [searchParams, setSearchParams];
}
/**
* Creates a URLSearchParams object using the given initializer.
*
* This is identical to `new URLSearchParams(init)` except it also
* supports arrays as values in the object form of the initializer
* instead of just strings. This is convenient when you need multiple
* values for a given key, but don't want to use an array initializer.
*
* For example, instead of:
*
* let searchParams = new URLSearchParams([
* ['sort', 'name'],
* ['sort', 'price']
* ]);
*
* you can do:
*
* let searchParams = createSearchParams({
* sort: ['name', 'price']
* });
*/
function createSearchParams(init = "") {
return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
let value = init[key];
return memo.concat(Array.isArray(value) ? value.map(v => [key, v]) : [[key, value]]);
}, []));
}
export { BrowserRouter, HashRouter, Link, NavLink, createSearchParams, HistoryRouter as unstable_HistoryRouter, useLinkClickHandler, useSearchParams };
//# sourceMappingURL=react-router-dom.development.js.map