-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
/
NavLink.js
86 lines (76 loc) · 1.94 KB
/
NavLink.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import React from "react";
import { Route } from "react-router";
import PropTypes from "prop-types";
import Link from "./Link";
function joinClassnames(...classnames) {
return classnames.filter(i => i).join(" ");
}
/**
* A <Link> wrapper that knows if it's "active" or not.
*/
function NavLink({
"aria-current": ariaCurrent = "page",
activeClassName = "active",
activeStyle,
className: classNameProp,
exact,
isActive: isActiveProp,
location,
strict,
style: styleProp,
to,
...rest
}) {
const path = typeof to === "object" ? to.pathname : to;
// Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202
const escapedPath = path && path.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
return (
<Route
path={escapedPath}
exact={exact}
strict={strict}
location={location}
children={({ location, match }) => {
const isActive = !!(isActiveProp
? isActiveProp(match, location)
: match);
const className = isActive
? joinClassnames(classNameProp, activeClassName)
: classNameProp;
const style = isActive ? { ...styleProp, ...activeStyle } : styleProp;
return (
<Link
aria-current={(isActive && ariaCurrent) || null}
className={className}
style={style}
to={to}
{...rest}
/>
);
}}
/>
);
}
if (__DEV__) {
const ariaCurrentType = PropTypes.oneOf([
"page",
"step",
"location",
"date",
"time",
"true"
]);
NavLink.propTypes = {
"aria-current": ariaCurrentType,
activeClassName: PropTypes.string,
activeStyle: PropTypes.object,
className: PropTypes.string,
exact: Route.propTypes.exact,
isActive: PropTypes.func,
location: PropTypes.object,
strict: Route.propTypes.strict,
style: PropTypes.object,
to: Link.propTypes.to
};
}
export default NavLink;