-
Notifications
You must be signed in to change notification settings - Fork 162
/
Copy pathLinkContainer.js
116 lines (101 loc) · 2.79 KB
/
LinkContainer.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';
const isModifiedEvent = (event) =>
!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
export default class LinkContainer extends Component {
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired,
createHref: PropTypes.func.isRequired,
}).isRequired,
}).isRequired,
};
static propTypes = {
children: PropTypes.element.isRequired,
onClick: PropTypes.func,
replace: PropTypes.bool,
to: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object,
]).isRequired,
exact: PropTypes.bool,
strict: PropTypes.bool,
className: PropTypes.string,
activeClassName: PropTypes.string,
style: PropTypes.object,
activeStyle: PropTypes.object,
isActive: PropTypes.func,
};
static defaultProps = {
replace: false,
exact: false,
strict: false,
activeClassName: 'active',
};
handleClick = (event) => {
const { children, onClick } = this.props;
if (children.props.onClick) {
children.props.onClick(event);
}
if (onClick) {
onClick(event);
}
if (
!event.defaultPrevented && // onClick prevented default
event.button === 0 && // ignore right clicks
!isModifiedEvent(event) // ignore clicks with modifier keys
) {
event.preventDefault();
const { history } = this.context.router;
const { replace, to } = this.props;
if (replace) {
history.replace(to);
} else {
history.push(to);
}
}
}
render() {
const {
children,
replace, // eslint-disable-line no-unused-vars
to,
exact,
strict,
activeClassName,
className,
activeStyle,
style,
isActive: getIsActive,
...props,
} = this.props;
const href = this.context.router.history.createHref(
typeof to === 'string' ? { pathname: to } : to
);
const child = React.Children.only(children);
return (
<Route
path={typeof to === 'object' ? to.pathname : to}
exact={exact}
strict={strict}
children={({ location, match }) => {
const isActive = !!(getIsActive ? getIsActive(match, location) : match);
return React.cloneElement(
child,
{
...props,
className: [className, child.props.className, isActive ? activeClassName : null]
.join(' ').trim(),
style: isActive ? { ...style, ...activeStyle } : style,
href,
onClick: this.handleClick,
}
);
}}
/>
);
}
}