Files
Iris/src/js/components/Link.js

93 lines
2.5 KiB
JavaScript
Executable File

import React from 'react';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import * as helpers from '../helpers';
/**
* Extends react-router's Link but provides the ability to hook in to the navigation event
* which lets us scroll to the top of our <main> for a more traditional navigation experience
**/
class CustomLink extends React.Component{
constructor(props){
super(props);
}
handleClick(e){
// Fetch the current scroll position of our #main element and
// save to our history's state, so clicking 'back' etc will restore
// the previous scroll position.
// Note that this doesn't trigger lazy-load elements (unless scrolling
// exposes the LazyLoader component).
var main = document.getElementById('main');
var state = (this.props.location && this.props.location.state ? this.props.location.state : {});
state.scroll_position = main.scrollTop;
this.props.history.replace({state: state});
// Allow a link to disable auto-scrolling to the top of the page
// on navigation. Useful for tabs, etc.
if (!this.props.retainScroll){
helpers.scrollTo(this.props.scrollTo, (this.props.scrollTo));
}
}
handleContextMenu(e){
if (this.props.onContextMenu){
this.props.onContextMenu(e);
}
}
isLinkActive(link){
// Decode both links
// This handles issues where one link is encoded and the other isn't,
// but they're otherwise identical
link = decodeURIComponent(link);
var current_link = decodeURIComponent(this.props.history.location.pathname);
if (this.props.exact){
return current_link === link;
} else {
return current_link.startsWith(link);
}
}
render(){
var className = "";
if (this.props.className){
className += this.props.className;
}
if (!this.props.to){
return <span className={className}>{this.props.children}</span>;
}
// We have an active detector method
// This is used almost solely by the Sidebar navigation
if (this.props.history !== undefined){
if (this.isLinkActive(this.props.to)){
if (this.props.activeClassName){
className += " "+this.props.activeClassName;
} else {
className += " active";
}
}
}
return (
<Link
onClick={e => this.handleClick(e)}
onContextMenu={e => this.handleContextMenu(e)}
className={className}
to={this.props.to}>
{this.props.children}
</Link>
);
}
}
export default withRouter(CustomLink);