react-concurrent-router
Version:
Performant routing embracing React concurrent UI patterns
70 lines (67 loc) • 2.17 kB
JavaScript
import _extends from '@babel/runtime/helpers/esm/extends';
import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';
import React, { useContext, useCallback } from 'react';
import { R as RouterContext } from './RouterContext-Bf2jDrm9.js';
const _excluded = ["activeClassName", "exact", "target", "to", "onClick"];
const shouldNavigate = event => !event.defaultPrevented && event.button === 0 && (!event.target.target || event.target.target === '_self') && !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
const Link = React.forwardRef((_ref, ref) => {
let {
activeClassName,
exact,
target,
to,
onClick
} = _ref,
props = _objectWithoutPropertiesLoose(_ref, _excluded);
const {
isActive,
preloadCode,
warmRoute,
history
} = useContext(RouterContext);
const toIsActive = isActive(to, {
exact
});
const handleClick = useCallback(event => {
if (onClick) onClick(event);
if (!shouldNavigate(event)) return;
event.preventDefault();
const navigationMethod = isActive(to, {
exact: true
}) ? 'replace' : 'push';
history[navigationMethod](to);
}, [onClick, isActive, to, history]);
const handlePreloadCode = useCallback(() => {
preloadCode(to);
}, [preloadCode, to]);
const handleWarmRoute = useCallback(({
type,
key,
code,
keyCode
}) => {
if (type === 'mousedown' || type === 'keydown' && (key === 'Enter' || code === 'Enter' || code === 'NumpadEnter' || keyCode === 13)) {
warmRoute(to);
}
}, [warmRoute, to]);
const elementProps = _extends({}, props, {
target,
ref,
href: to,
onClick: handleClick,
onMouseOver: handlePreloadCode,
onFocus: handlePreloadCode,
onMouseDown: handleWarmRoute,
onKeyDown: handleWarmRoute
}, toIsActive && {
className: props.className ? `${props.className} ${activeClassName}` : activeClassName,
'aria-current': 'page'
});
return React.createElement("a", elementProps);
});
Link.defaultProps = {
activeClassName: 'active',
exact: false
};
Link.displayName = 'Link';
export { Link as default };