UNPKG

react-router

Version:

A complete routing library for React

179 lines (136 loc) 5.65 kB
'use strict'; exports.__esModule = true; 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; }; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _routerWarning = require('./routerWarning'); var _routerWarning2 = _interopRequireDefault(_routerWarning); var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); var _PropTypes = require('./PropTypes'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } var _React$PropTypes = _react2.default.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 = _react2.default.createClass({ displayName: 'Link', contextTypes: { router: _PropTypes.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' ? (0, _invariant2.default)(false, '<Link>s rendered outside of a router context cannot handle clicks.') : (0, _invariant2.default)(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' ? (0, _routerWarning2.default)(!(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 _react2.default.createElement('a', _extends({}, props, { onClick: this.handleClick })); } }); exports.default = Link; module.exports = exports['default'];