UNPKG

react-router

Version:

A complete routing library for React

163 lines (129 loc) 5.19 kB
var _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; }; function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } import React from 'react'; import warning from './routerWarning'; import invariant from 'invariant'; import { routerShape } from './PropTypes'; var _React$PropTypes = React.PropTypes; var bool = _React$PropTypes.bool; var object = _React$PropTypes.object; var string = _React$PropTypes.string; var func = _React$PropTypes.func; var oneOfType = _React$PropTypes.oneOfType; function isLeftClickEvent(event) { return event.button === 0; } function isModifiedEvent(event) { return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); } // TODO: De-duplicate against hasAnyProperties in createTransitionManager. function isEmptyObject(object) { for (var p in object) { if (Object.prototype.hasOwnProperty.call(object, p)) return false; }return true; } function createLocationDescriptor(to, _ref) { var query = _ref.query; var hash = _ref.hash; var state = _ref.state; if (query || hash || state) { return { pathname: to, query: query, hash: hash, state: state }; } return to; } /** * A <Link> is used to create an <a> element that links to a route. * When that route is active, the link gets the value of its * activeClassName prop. * * For example, assuming you have the following route: * * <Route path="/posts/:postID" component={Post} /> * * You could use the following component to link to that route: * * <Link to={`/posts/${post.id}`} /> * * Links may pass along location state and/or query string parameters * in the state/query props, respectively. * * <Link ... query={{ show: true }} state={{ the: 'state' }} /> */ var Link = React.createClass({ displayName: 'Link', contextTypes: { router: routerShape }, propTypes: { to: oneOfType([string, object]).isRequired, query: object, hash: string, state: object, activeStyle: object, activeClassName: string, onlyActiveOnIndex: bool.isRequired, onClick: func, target: string }, getDefaultProps: function getDefaultProps() { return { onlyActiveOnIndex: false, style: {} }; }, handleClick: function handleClick(event) { !this.context.router ? process.env.NODE_ENV !== 'production' ? invariant(false, '<Link>s rendered outside of a router context cannot handle clicks.') : invariant(false) : void 0; var allowTransition = true; if (this.props.onClick) this.props.onClick(event); if (isModifiedEvent(event) || !isLeftClickEvent(event)) return; if (event.defaultPrevented === true) allowTransition = false; // If target prop is set (e.g. to "_blank") let browser handle link. /* istanbul ignore if: untestable with Karma */ if (this.props.target) { if (!allowTransition) event.preventDefault(); return; } event.preventDefault(); if (allowTransition) { var _props = this.props; var to = _props.to; var query = _props.query; var hash = _props.hash; var state = _props.state; var location = createLocationDescriptor(to, { query: query, hash: hash, state: state }); this.context.router.push(location); } }, render: function render() { var _props2 = this.props; var to = _props2.to; var query = _props2.query; var hash = _props2.hash; var state = _props2.state; var activeClassName = _props2.activeClassName; var activeStyle = _props2.activeStyle; var onlyActiveOnIndex = _props2.onlyActiveOnIndex; var props = _objectWithoutProperties(_props2, ['to', 'query', 'hash', 'state', 'activeClassName', 'activeStyle', 'onlyActiveOnIndex']); process.env.NODE_ENV !== 'production' ? warning(!(query || hash || state), 'the `query`, `hash`, and `state` props on `<Link>` are deprecated, use `<Link to={{ pathname, query, hash, state }}/>. http://tiny.cc/router-isActivedeprecated') : void 0; // Ignore if rendered outside the context of router, simplifies unit testing. var router = this.context.router; if (router) { var location = createLocationDescriptor(to, { query: query, hash: hash, state: state }); props.href = router.createHref(location); if (activeClassName || activeStyle != null && !isEmptyObject(activeStyle)) { if (router.isActive(location, onlyActiveOnIndex)) { if (activeClassName) { if (props.className) { props.className += ' ' + activeClassName; } else { props.className = activeClassName; } } if (activeStyle) props.style = _extends({}, props.style, activeStyle); } } } return React.createElement('a', _extends({}, props, { onClick: this.handleClick })); } }); export default Link;