/** * 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 `` 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 `` 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 `` 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 . */ 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 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 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 `` components. This is useful if * you need to create custom `` components with the same click behavior we * use in our exported ``. */ 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 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