react-router-dom
Version:
Declarative routing for React web applications
265 lines (224 loc) • 7.98 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { createBrowserHistory, createHashHistory } from 'history';
import { Router, useHref, useNavigate, useLocation, useResolvedLocation, useMatch, useBlocker } from 'react-router';
export { MemoryRouter, Navigate, Outlet, Redirect, Route, Router, Routes, createRoutesFromChildren, generatePath, matchRoutes, resolveLocation, useBlocker, useHref, useLocation, useMatch, useNavigate, useOutlet, useParams, useResolvedLocation, useRoutes } from 'react-router';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
// COMPONENTS
////////////////////////////////////////////////////////////////////////////////
/**
* A <Router> for use in web browsers. Provides the cleanest URLs.
*/
function BrowserRouter(_ref) {
var children = _ref.children,
timeout = _ref.timeout,
window = _ref.window;
var historyRef = React.useRef(null);
if (historyRef.current == null) {
historyRef.current = createBrowserHistory({
window: window
});
}
return React.createElement(Router, {
children: children,
history: historyRef.current,
timeout: timeout
});
}
if (process.env.NODE_ENV !== "production") {
BrowserRouter.displayName = 'BrowserRouter';
BrowserRouter.propTypes = {
children: PropTypes.node,
timeout: PropTypes.number,
window: PropTypes.object
};
}
/**
* 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(_ref2) {
var children = _ref2.children,
timeout = _ref2.timeout,
window = _ref2.window;
var historyRef = React.useRef(null);
if (historyRef.current == null) {
historyRef.current = createHashHistory({
window: window
});
}
return React.createElement(Router, {
children: children,
history: historyRef.current,
timeout: timeout
});
}
if (process.env.NODE_ENV !== "production") {
HashRouter.displayName = 'HashRouter';
HashRouter.propTypes = {
children: PropTypes.node,
timeout: PropTypes.number,
window: PropTypes.object
};
}
/**
* The public API for rendering a history-aware <a>.
*/
var Link = React.forwardRef(function LinkWithRef(_ref3, ref) {
var _ref3$as = _ref3.as,
Component = _ref3$as === void 0 ? 'a' : _ref3$as,
onClick = _ref3.onClick,
_ref3$replace = _ref3.replace,
replaceProp = _ref3$replace === void 0 ? false : _ref3$replace,
state = _ref3.state,
target = _ref3.target,
to = _ref3.to,
rest = _objectWithoutPropertiesLoose(_ref3, ["as", "onClick", "replace", "state", "target", "to"]);
var href = useHref(to);
var navigate = useNavigate();
var location = useLocation();
var toLocation = useResolvedLocation(to);
function handleClick(event) {
if (onClick) onClick(event);
if (!event.defaultPrevented && // onClick prevented default
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();
var isSameLocation = toLocation.pathname === location.pathname && toLocation.search === location.search && toLocation.hash === location.hash; // If the pathname, search, and hash haven't changed, a
// regular <a> will do a REPLACE instead of a PUSH.
var replace = !!replaceProp || isSameLocation;
navigate(to, {
replace: replace,
state: state
});
}
}
return React.createElement(Component, _extends({}, rest, {
href: href,
onClick: handleClick,
ref: ref,
target: target
}));
});
if (process.env.NODE_ENV !== "production") {
Link.displayName = 'Link';
Link.propTypes = {
as: PropTypes.elementType,
onClick: PropTypes.func,
replace: PropTypes.bool,
state: PropTypes.object,
target: PropTypes.string,
to: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
pathname: PropTypes.string,
search: PropTypes.string,
hash: PropTypes.string
})]).isRequired
};
}
function isModifiedEvent(event) {
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
}
/**
* A <Link> wrapper that knows if it's "active" or not.
*/
var NavLink = React.forwardRef(function NavLinkWithRef(_ref4, ref) {
var _ref4$ariaCurrent = _ref4['aria-current'],
ariaCurrentProp = _ref4$ariaCurrent === void 0 ? 'page' : _ref4$ariaCurrent,
_ref4$activeClassName = _ref4.activeClassName,
activeClassName = _ref4$activeClassName === void 0 ? 'active' : _ref4$activeClassName,
_ref4$activeStyle = _ref4.activeStyle,
activeStyle = _ref4$activeStyle === void 0 ? null : _ref4$activeStyle,
_ref4$className = _ref4.className,
classNameProp = _ref4$className === void 0 ? '' : _ref4$className,
_ref4$style = _ref4.style,
styleProp = _ref4$style === void 0 ? null : _ref4$style,
to = _ref4.to,
rest = _objectWithoutPropertiesLoose(_ref4, ["aria-current", "activeClassName", "activeStyle", "className", "style", "to"]);
var match = useMatch(to);
var ariaCurrent = match ? ariaCurrentProp : undefined;
var className = [classNameProp, match ? activeClassName : null].filter(Boolean).join(' ');
var style = _extends({}, styleProp, {}, match ? activeStyle : null);
return React.createElement(Link, _extends({}, rest, {
"aria-current": ariaCurrent,
className: className,
ref: ref,
style: style,
to: to
}));
});
if (process.env.NODE_ENV !== "production") {
NavLink.displayName = 'NavLink';
NavLink.propTypes = _extends({}, Link.propTypes, {
'aria-current': PropTypes.oneOf(['page', 'step', 'location', 'date', 'time', 'true']),
activeClassName: PropTypes.string,
activeStyle: PropTypes.object,
className: PropTypes.string,
style: PropTypes.object,
to: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
pathname: PropTypes.string,
search: PropTypes.string,
hash: PropTypes.string
})]).isRequired
});
}
/**
* A declarative interface for showing a window.confirm dialog with the given
* message when the user tries to navigate away from the current page.
*
* This also serves as a reference implementation for anyone who wants to
* create their own custom prompt component.
*/
function Prompt(_ref5) {
var message = _ref5.message,
when = _ref5.when;
usePrompt(message, when);
return null;
}
if (process.env.NODE_ENV !== "production") {
Prompt.displayName = 'Prompt';
Prompt.propTypes = {
message: PropTypes.string,
when: PropTypes.bool
};
} ////////////////////////////////////////////////////////////////////////////////
// HOOKS
////////////////////////////////////////////////////////////////////////////////
/**
* Prevents navigation away from the current page using a window.confirm prompt
* with the given message.
*/
function usePrompt(message, when) {
var blocker = React.useCallback(function (tx) {
if (window.confirm(message)) tx.retry();
}, [message]);
useBlocker(blocker, when);
}
export { BrowserRouter, HashRouter, Link, NavLink, Prompt, usePrompt };
//# sourceMappingURL=react-router-dom.js.map