├── .babelrc ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dist ├── commonjs │ ├── BaseLink.js │ ├── RouterProvider.js │ ├── index.js │ ├── routeNode.js │ ├── utils.js │ └── withRoute.js ├── es │ ├── BaseLink.js │ ├── RouterProvider.js │ ├── index.js │ ├── routeNode.js │ ├── utils.js │ └── withRoute.js └── umd │ └── react-router5.js ├── modules ├── BaseLink.js ├── RouterProvider.js ├── index.js ├── routeNode.js ├── utils.js └── withRoute.js ├── package.json ├── rollup.config.js ├── scripts └── release.js ├── test ├── main.js ├── test-helper.js └── utils.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react" 4 | ], 5 | "plugins": [ 6 | "transform-object-rest-spread", 7 | "transform-export-extensions" 8 | ], 9 | "env": { 10 | "development": { 11 | "presets": [ "es2015" ] 12 | }, 13 | "es": { 14 | "presets": [ "es2015-rollup" ] 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | 9 | charset = utf-8 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | // Parser 3 | "parser": "babel-eslint", 4 | // ECMA Features 5 | "ecmaFeatures": { 6 | "arrowFunctions": true, 7 | "blockBindings": true, 8 | "classes": true, 9 | "defaultParams": true, 10 | "destructuring": true, 11 | "modules": true, 12 | "objectLiteralComputedProperties": true, 13 | "templateStrings": true 14 | }, 15 | "rules": { 16 | // Possible Errors 17 | "no-dupe-args": 2, 18 | "no-dupe-keys": 2, 19 | "no-empty": 2, 20 | "no-func-assign": 2, 21 | "no-inner-declarations": 2, 22 | "no-unreachable": 2, 23 | "no-unexpected-multiline": 2, 24 | // Best practices 25 | "consistent-return": 0, 26 | "curly": [2, "multi-line"], 27 | "eqeqeq": 2, 28 | "no-else-return": 2, 29 | "no-multi-spaces": 0, 30 | // Strict mode 31 | "strict": 0, 32 | // Variables 33 | "no-shadow": 0, 34 | "no-unused-vars": 2, 35 | "no-use-before-define": 0, 36 | // Style 37 | "brace-style": [2, "1tbs"], 38 | "comma-spacing": [2, {"before": false, "after": true}], 39 | "comma-style": [2, "last"], 40 | "consistent-this": [2, "that"], 41 | "lines-around-comment": [2, {"allowBlockStart": true}], 42 | "key-spacing": 0, 43 | "new-parens": 0, 44 | "quotes": [2, "single", "avoid-escape"], 45 | "no-underscore-dangle": 0, 46 | "no-unneeded-ternary": 2, 47 | "semi": 2, 48 | // ES6 49 | "no-var": 2, 50 | "no-this-before-super": 2, 51 | "object-shorthand": 2, 52 | }, 53 | "env": { 54 | "node": true, 55 | "browser": true 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | jspm_packages/ 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **/.* 2 | node_modules 3 | npm-debug.log 4 | test 5 | scripts 6 | *.md 7 | *.config.js 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6.0' 4 | script: 5 | - npm run lint 6 | - npm run build 7 | - npm run test 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # [4.3.0](https://github.com/router5/react-router5/compare/v4.2.1...v4.3.0) (2017-06-11) 3 | 4 | 5 | ### Features 6 | 7 | * support onMouseOver event handler in links ([452be83](https://github.com/router5/react-router5/commit/452be83)) 8 | 9 | 10 | 11 | 12 | ## [4.2.1](https://github.com/router5/react-router5/compare/v4.2.0...v4.2.1) (2017-05-17) 13 | 14 | 15 | ### Bug Fixes 16 | 17 | * fix peer dependencies version range ([602f155](https://github.com/router5/react-router5/commit/602f155)) 18 | 19 | 20 | 21 | 22 | # [4.2.0](https://github.com/router5/react-router5/compare/v4.1.0...v4.2.0) (2017-05-16) 23 | 24 | 25 | ### Features 26 | 27 | * support title attribute in links ([678e424](https://github.com/router5/react-router5/commit/678e424)) 28 | 29 | 30 | 31 | 32 | # [4.1.0](https://github.com/router5/react-router5/compare/v4.0.1...v4.1.0) (2017-04-28) 33 | 34 | 35 | 36 | 37 | ## [4.0.1](https://github.com/router5/react-router5/compare/v4.0.0...v4.0.1) (2016-09-18) 38 | 39 | 40 | ### Bug Fixes 41 | 42 | * building a path if browser plugin not in use ([214e8cb](https://github.com/router5/react-router5/commit/214e8cb)) 43 | 44 | 45 | 46 | 47 | # [4.0.0](https://github.com/router5/react-router5/compare/v3.1.0...v4.0.0) (2016-09-05) 48 | 49 | ### BREAKING CHANGES 50 | 51 | * `registerComponent` argument in `routeNode` HOC is no longer supported 52 | * AMD bundle is no longer distributed (use UMD instead) 53 | 54 | 55 | 56 | ## [3.0.1](https://github.com/router5/react-router5/compare/v3.0.0...v3.0.1) (2016-03-25) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * use activeStrict property ([75a58e8](https://github.com/router5/react-router5/commit/75a58e8)) 62 | 63 | 64 | 65 | 66 | # [3.0.0](https://github.com/router5/react-router5/compare/v2.0.2...v3.0.0) (2016-02-28) 67 | 68 | 69 | ### Features 70 | 71 | * make BaseLink grab the router instance from context ([76662e7](https://github.com/router5/react-router5/commit/76662e7)) 72 | 73 | 74 | 75 | 76 | ## [2.0.2](https://github.com/router5/react-router5/compare/v2.0.1...v2.0.2) (2016-02-05) 77 | 78 | 79 | ### Bug Fixes 80 | 81 | * wrong name of event variable in clickHandler ([77990d6](https://github.com/router5/react-router5/commit/77990d6)) 82 | 83 | 84 | 85 | 86 | ## [2.0.1](https://github.com/router5/react-router5/compare/v2.0.0...v2.0.1) (2016-02-01) 87 | 88 | 89 | ### Bug Fixes 90 | 91 | * fix withRoute lifecyle method name ([4f8aee8](https://github.com/router5/react-router5/commit/4f8aee8)) 92 | 93 | 94 | 95 | 96 | # [2.0.0](https://github.com/router5/react-router5/compare/v2.0.0-rc.2...v2.0.0) (2016-01-19) 97 | 98 | 99 | 100 | 101 | 102 | # [2.0.0-rc.1](https://github.com/router5/react-router5/compare/v1.0.1...v2.0.0-rc.1) (2016-01-18) 103 | 104 | 105 | ### Features 106 | 107 | * split Link into LinkBase component and withRoute higher-order component ([81e22ad](https://github.com/router5/react-router5/commit/81e22ad)) 108 | 109 | 110 | 111 | 112 | ## [1.0.1](https://github.com/router5/react-router5/compare/v1.0.0...v1.0.1) (2015-11-26) 113 | 114 | 115 | ### Bug Fixes 116 | 117 | * register node listener in componentDidMount to prevent server rendering issues ([46d4034](https://github.com/router5/react-router5/commit/46d4034)) 118 | 119 | 120 | 121 | 122 | # [1.0.0](https://github.com/router5/react-router5/compare/v0.1.5...v1.0.0) (2015-10-27) 123 | 124 | 125 | 126 | 127 | 128 | ## [0.1.5](https://github.com/router5/react-router5/compare/v0.1.4...v0.1.5) (2015-09-18) 129 | 130 | 131 | ### Features 132 | 133 | * onClick doesn't override main click handler [close #4] ([c7ac405](https://github.com/router5/react-router5/commit/c7ac405)), closes [#4](https://github.com/router5/react-router5/issues/4) 134 | 135 | 136 | 137 | 138 | ## [0.1.4](https://github.com/router5/react-router5/compare/v0.1.3...v0.1.4) (2015-08-28) 139 | 140 | 141 | ### Features 142 | 143 | * improve decision to handle click or not ([5a2ab71](https://github.com/router5/react-router5/commit/5a2ab71)) 144 | 145 | 146 | 147 | 148 | ## [0.1.3](https://github.com/router5/react-router5/compare/v0.1.1...v0.1.3) (2015-08-19) 149 | 150 | 151 | ### Bug Fixes 152 | 153 | * change click handler condition to allow ENTER key ([0e8dbf5](https://github.com/router5/react-router5/commit/0e8dbf5)) 154 | * missing dist files for 0.1.2 ([6092808](https://github.com/router5/react-router5/commit/6092808)) 155 | 156 | 157 | 158 | 159 | ## [0.1.1](https://github.com/router5/react-router5/compare/v0.1.0...v0.1.1) (2015-07-31) 160 | 161 | 162 | ### Bug Fixes 163 | 164 | * detect left click properly on links ([5d344a2](https://github.com/router5/react-router5/commit/5d344a2)) 165 | 166 | 167 | 168 | 169 | # [0.1.0](https://github.com/router5/react-router5/compare/v0.1.0-alpha.7...v0.1.0) (2015-07-30) 170 | 171 | 172 | ### Bug Fixes 173 | 174 | * allow middle click ([511cede](https://github.com/router5/react-router5/commit/511cede)) 175 | 176 | 177 | 178 | 179 | # [0.1.0-alpha.7](https://github.com/router5/react-router5/compare/v0.1.0-alpha.6...v0.1.0-alpha.7) (2015-07-08) 180 | 181 | 182 | ### Bug Fixes 183 | 184 | * use of routeOptions ([618157b](https://github.com/router5/react-router5/commit/618157b)) 185 | 186 | ### Features 187 | 188 | * register listener in mixin only if existing ([8a388fa](https://github.com/router5/react-router5/commit/8a388fa)) 189 | 190 | 191 | 192 | 193 | # [0.1.0-alpha.6](https://github.com/router5/react-router5/compare/v0.1.0-alpha.5...v0.1.0-alpha.6) (2015-07-08) 194 | 195 | 196 | ### Features 197 | 198 | * add activeStrict prop on Link and fix typo ([efe3fbc](https://github.com/router5/react-router5/commit/efe3fbc)) 199 | 200 | 201 | 202 | 203 | # [0.1.0-alpha.5](https://github.com/router5/react-router5/compare/v0.1.0-alpha.4...v0.1.0-alpha.5) (2015-07-07) 204 | 205 | 206 | 207 | 208 | 209 | # [0.1.0-alpha.4](https://github.com/router5/react-router5/compare/v0.1.0-alpha.3...v0.1.0-alpha.4) (2015-07-07) 210 | 211 | 212 | ### Bug Fixes 213 | 214 | * syntax and bugs ([7fd80e3](https://github.com/router5/react-router5/commit/7fd80e3)) 215 | 216 | 217 | 218 | 219 | # [0.1.0-alpha.3](https://github.com/router5/react-router5/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2015-07-07) 220 | 221 | 222 | ### Bug Fixes 223 | 224 | * segment mixin factory export ([51700e0](https://github.com/router5/react-router5/commit/51700e0)) 225 | 226 | 227 | 228 | 229 | # [0.1.0-alpha.2](https://github.com/router5/react-router5/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2015-07-07) 230 | 231 | 232 | ### Bug Fixes 233 | 234 | * bower config ([1474325](https://github.com/router5/react-router5/commit/1474325)) 235 | 236 | 237 | 238 | 239 | # [0.1.0-alpha.1](https://github.com/router5/react-router5/compare/5799da7...v0.1.0-alpha.1) (2015-07-07) 240 | 241 | 242 | ### Bug Fixes 243 | 244 | * syntax ([3140dcd](https://github.com/router5/react-router5/commit/3140dcd)) 245 | 246 | ### Features 247 | 248 | * add first draft of a Link and RouteNodeMixin factories ([5799da7](https://github.com/router5/react-router5/commit/5799da7)) 249 | * add listeners and state to link component, fix mixin ([55db083](https://github.com/router5/react-router5/commit/55db083)) 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Thomas Roch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Moved to router5 repository](https://github.com/router5/router5/tree/master/packages/react-router5) 2 | 3 | [![npm version](https://badge.fury.io/js/react-router5.svg)](https://badge.fury.io/js/react-router5) 4 | 5 | # react-router5 6 | 7 | > Higher-order components and components for React when using [router5](https://github.com/router5/router5). 8 | 9 | 10 | ### Installation 11 | 12 | ```sh 13 | npm install --save react-router5 14 | ``` 15 | 16 | ### Examples 17 | 18 | * [Example project](https://github.com/router5/examples/tree/master/apps/react) 19 | * [Demo](https://router5.github.io/docs/with-react.html#/inbox) 20 | 21 | ### Requirements 22 | 23 | - react >= __0.14.0__ 24 | - router5 >= __2.0.0__ 25 | 26 | ### What does this package export? 27 | 28 | - `RouterProvider`: component 29 | - `Link`: component 30 | - `routeNode`: higher-order component 31 | - `BaseLink`: component 32 | - `withRoute`: higher-order component 33 | 34 | 35 | ### How it works 36 | 37 | ![With React](https://cdn.rawgit.com/router5/router5.github.io/master/img/router-view.png) 38 | 39 | 40 | ### RouterProvider 41 | 42 | It will add your router instance in context. 43 | 44 | ```javascript 45 | import React from 'react'; 46 | import ReactDOM from 'react-dom'; 47 | import { RouterProvider } from 'react-router5'; 48 | import App from './App'; 49 | import router from './router'; 50 | 51 | ReactDOM.render( 52 | , 53 | document.getElementById('app') 54 | ); 55 | ``` 56 | 57 | ### routeNode HOC 58 | 59 | __routeNode(nodeName)__: higher-order component to wrap a route node component. 60 | 61 | - Specify your component node name (`''` if root node) 62 | 63 | __Note:__ your router needs to use `listenersPlugin` from `router5`. 64 | 65 | ```javascript 66 | import React from 'react'; 67 | import { routeNode } from 'react-router5'; 68 | import { UserView, UserList, NotFound } from './components'; 69 | 70 | function Users(props) { 71 | const { previousRoute, route } = props; 72 | 73 | switch (route.name) { 74 | case 'users.list': 75 | return ; 76 | case 'users.view': 77 | return ; 78 | default: 79 | return ; 80 | }; 81 | } 82 | 83 | export default routeNode('users')(Users); 84 | 85 | ``` 86 | 87 | ### Link component 88 | 89 | ```javascript 90 | import React from 'react'; 91 | import { Link } from 'react-router5'; 92 | 93 | function Menu(props) { 94 | return ( 95 | 100 | ); 101 | } 102 | 103 | export default Menu; 104 | ``` 105 | 106 | __The `Link `component is `BaseLink` and `withRoute` composed together__ 107 | 108 | ### BaseLink component 109 | 110 | Same as `Link`, except it won't mark it-self dirty (and re-render) on a route change. `BaseLink` needs to be passed your router instance. 111 | 112 | ### withRoute HOC 113 | 114 | Will create a new component, injecting your router instance (from context) and the current route to the wrapped component. Any route change will trigger a re-render. 115 | 116 | ### Contributing 117 | 118 | Please read [contributing guidelines](https://github.com/router5/router5/blob/master/CONTRIBUTING.md) on router5 repository. 119 | -------------------------------------------------------------------------------- /dist/commonjs/BaseLink.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _react2 = _interopRequireDefault(_react); 12 | 13 | var _propTypes = require('prop-types'); 14 | 15 | var _propTypes2 = _interopRequireDefault(_propTypes); 16 | 17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 18 | 19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20 | 21 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 22 | 23 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 24 | 25 | var BaseLink = function (_Component) { 26 | _inherits(BaseLink, _Component); 27 | 28 | function BaseLink(props, context) { 29 | _classCallCheck(this, BaseLink); 30 | 31 | var _this = _possibleConstructorReturn(this, (BaseLink.__proto__ || Object.getPrototypeOf(BaseLink)).call(this, props, context)); 32 | 33 | _this.router = context.router; 34 | 35 | if (!_this.router.hasPlugin('BROWSER_PLUGIN')) { 36 | console.error('[react-router5][BaseLink] missing browser plugin, href might be build incorrectly'); 37 | }; 38 | 39 | _this.isActive = _this.isActive.bind(_this); 40 | _this.clickHandler = _this.clickHandler.bind(_this); 41 | 42 | _this.state = { active: _this.isActive() }; 43 | return _this; 44 | } 45 | 46 | _createClass(BaseLink, [{ 47 | key: 'buildUrl', 48 | value: function buildUrl(routeName, routeParams) { 49 | if (this.router.buildUrl) { 50 | return this.router.buildUrl(routeName, routeParams); 51 | } 52 | 53 | return this.router.buildPath(routeName, routeParams); 54 | } 55 | }, { 56 | key: 'isActive', 57 | value: function isActive() { 58 | return this.router.isActive(this.props.routeName, this.props.routeParams, this.props.activeStrict); 59 | } 60 | }, { 61 | key: 'clickHandler', 62 | value: function clickHandler(evt) { 63 | if (this.props.onClick) { 64 | this.props.onClick(evt); 65 | 66 | if (evt.defaultPrevented) { 67 | return; 68 | } 69 | } 70 | 71 | var comboKey = evt.metaKey || evt.altKey || evt.ctrlKey || evt.shiftKey; 72 | 73 | if (evt.button === 0 && !comboKey) { 74 | evt.preventDefault(); 75 | this.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions); 76 | } 77 | } 78 | }, { 79 | key: 'render', 80 | value: function render() { 81 | var _props = this.props, 82 | routeName = _props.routeName, 83 | routeParams = _props.routeParams, 84 | className = _props.className, 85 | activeClassName = _props.activeClassName, 86 | children = _props.children, 87 | title = _props.title, 88 | onMouseOver = _props.onMouseOver; 89 | 90 | 91 | var active = this.isActive(); 92 | var href = this.buildUrl(routeName, routeParams); 93 | var linkclassName = (className ? className.split(' ') : []).concat(active ? [activeClassName] : []).join(' '); 94 | 95 | return _react2.default.createElement('a', { 96 | href: href, 97 | className: linkclassName, 98 | onClick: this.clickHandler, 99 | onMouseOver: onMouseOver, 100 | title: title 101 | }, children); 102 | } 103 | }]); 104 | 105 | return BaseLink; 106 | }(_react.Component); 107 | 108 | BaseLink.contextTypes = { 109 | router: _propTypes2.default.object.isRequired 110 | }; 111 | 112 | BaseLink.propTypes = { 113 | routeName: _propTypes2.default.string.isRequired, 114 | routeParams: _propTypes2.default.object, 115 | routeOptions: _propTypes2.default.object, 116 | activeClassName: _propTypes2.default.string, 117 | activeStrict: _propTypes2.default.bool, 118 | onClick: _propTypes2.default.func, 119 | onMouseOver: _propTypes2.default.func 120 | }; 121 | 122 | BaseLink.defaultProps = { 123 | activeClassName: 'active', 124 | activeStrict: false, 125 | routeParams: {}, 126 | routeOptions: {} 127 | }; 128 | 129 | exports.default = BaseLink; -------------------------------------------------------------------------------- /dist/commonjs/RouterProvider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _propTypes = require('prop-types'); 12 | 13 | var _propTypes2 = _interopRequireDefault(_propTypes); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18 | 19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 20 | 21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 22 | 23 | var RouterProvider = function (_Component) { 24 | _inherits(RouterProvider, _Component); 25 | 26 | function RouterProvider(props, context) { 27 | _classCallCheck(this, RouterProvider); 28 | 29 | var _this = _possibleConstructorReturn(this, (RouterProvider.__proto__ || Object.getPrototypeOf(RouterProvider)).call(this, props, context)); 30 | 31 | _this.router = props.router; 32 | return _this; 33 | } 34 | 35 | _createClass(RouterProvider, [{ 36 | key: 'getChildContext', 37 | value: function getChildContext() { 38 | return { router: this.router }; 39 | } 40 | }, { 41 | key: 'componentWillReceiveProps', 42 | value: function componentWillReceiveProps(nextProps) { 43 | if (this.props.router !== nextProps.router) { 44 | console.error('[react-router5][RouterProvider] does not support changing the router object.'); 45 | } 46 | } 47 | }, { 48 | key: 'render', 49 | value: function render() { 50 | var children = this.props.children; 51 | 52 | return _react.Children.only(children); 53 | } 54 | }]); 55 | 56 | return RouterProvider; 57 | }(_react.Component); 58 | 59 | RouterProvider.propTypes = { 60 | router: _propTypes2.default.object.isRequired, 61 | children: _propTypes2.default.element.isRequired 62 | }; 63 | 64 | RouterProvider.childContextTypes = { 65 | router: _propTypes2.default.object.isRequired 66 | }; 67 | 68 | exports.default = RouterProvider; -------------------------------------------------------------------------------- /dist/commonjs/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.Link = exports.withRoute = exports.RouterProvider = exports.routeNode = exports.BaseLink = undefined; 7 | 8 | var _BaseLink = require('./BaseLink'); 9 | 10 | var _BaseLink2 = _interopRequireDefault(_BaseLink); 11 | 12 | var _routeNode = require('./routeNode'); 13 | 14 | var _routeNode2 = _interopRequireDefault(_routeNode); 15 | 16 | var _RouterProvider = require('./RouterProvider'); 17 | 18 | var _RouterProvider2 = _interopRequireDefault(_RouterProvider); 19 | 20 | var _withRoute = require('./withRoute'); 21 | 22 | var _withRoute2 = _interopRequireDefault(_withRoute); 23 | 24 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 25 | 26 | var Link = (0, _withRoute2.default)(_BaseLink2.default); 27 | 28 | exports.BaseLink = _BaseLink2.default; 29 | exports.routeNode = _routeNode2.default; 30 | exports.RouterProvider = _RouterProvider2.default; 31 | exports.withRoute = _withRoute2.default; 32 | exports.Link = Link; -------------------------------------------------------------------------------- /dist/commonjs/routeNode.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | 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; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _utils = require('./utils'); 14 | 15 | var _propTypes = require('prop-types'); 16 | 17 | var _propTypes2 = _interopRequireDefault(_propTypes); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22 | 23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 24 | 25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 26 | 27 | function routeNode(nodeName) { 28 | return function routeNodeWrapper(RouteSegment) { 29 | var RouteNode = function (_Component) { 30 | _inherits(RouteNode, _Component); 31 | 32 | function RouteNode(props, context) { 33 | _classCallCheck(this, RouteNode); 34 | 35 | var _this = _possibleConstructorReturn(this, (RouteNode.__proto__ || Object.getPrototypeOf(RouteNode)).call(this, props, context)); 36 | 37 | _this.router = context.router; 38 | _this.state = { 39 | previousRoute: null, 40 | route: _this.router.getState() 41 | }; 42 | return _this; 43 | } 44 | 45 | _createClass(RouteNode, [{ 46 | key: 'componentDidMount', 47 | value: function componentDidMount() { 48 | var _this2 = this; 49 | 50 | (0, _utils.ifNot)(this.router.hasPlugin('LISTENERS_PLUGIN'), '[react-router5][routeNode] missing listeners plugin'); 51 | 52 | this.nodeListener = function (toState, fromState) { 53 | return _this2.setState({ previousRoute: fromState, route: toState }); 54 | }; 55 | this.router.addNodeListener(nodeName, this.nodeListener); 56 | } 57 | }, { 58 | key: 'componentWillUnmout', 59 | value: function componentWillUnmout() { 60 | this.router.removeNodeListener(nodeName, this.nodeListener); 61 | } 62 | }, { 63 | key: 'render', 64 | value: function render() { 65 | var props = this.props, 66 | router = this.router; 67 | var _state = this.state, 68 | previousRoute = _state.previousRoute, 69 | route = _state.route; 70 | 71 | var component = (0, _react.createElement)(RouteSegment, _extends({}, props, { router: router, previousRoute: previousRoute, route: route })); 72 | 73 | return component; 74 | } 75 | }]); 76 | 77 | return RouteNode; 78 | }(_react.Component); 79 | 80 | RouteNode.contextTypes = { 81 | router: _propTypes2.default.object.isRequired 82 | }; 83 | 84 | RouteNode.displayName = 'RouteNode[' + (0, _utils.getDisplayName)(RouteSegment) + ']'; 85 | 86 | return RouteNode; 87 | }; 88 | } 89 | 90 | exports.default = routeNode; -------------------------------------------------------------------------------- /dist/commonjs/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var getDisplayName = exports.getDisplayName = function getDisplayName(component) { 7 | return component.displayName || component.name || 'Component'; 8 | }; 9 | 10 | var ifNot = exports.ifNot = function ifNot(condition, errorMessage) { 11 | if (!condition) throw new Error(errorMessage); 12 | }; -------------------------------------------------------------------------------- /dist/commonjs/withRoute.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | 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; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _utils = require('./utils'); 14 | 15 | var _propTypes = require('prop-types'); 16 | 17 | var _propTypes2 = _interopRequireDefault(_propTypes); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22 | 23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 24 | 25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 26 | 27 | function withRoute(BaseComponent) { 28 | var ComponentWithRoute = function (_Component) { 29 | _inherits(ComponentWithRoute, _Component); 30 | 31 | function ComponentWithRoute(props, context) { 32 | _classCallCheck(this, ComponentWithRoute); 33 | 34 | var _this = _possibleConstructorReturn(this, (ComponentWithRoute.__proto__ || Object.getPrototypeOf(ComponentWithRoute)).call(this, props, context)); 35 | 36 | _this.router = context.router; 37 | _this.state = { 38 | previousRoute: null, 39 | route: _this.router.getState() 40 | }; 41 | _this.listener = _this.listener.bind(_this); 42 | return _this; 43 | } 44 | 45 | _createClass(ComponentWithRoute, [{ 46 | key: 'componentDidMount', 47 | value: function componentDidMount() { 48 | var _this2 = this; 49 | 50 | (0, _utils.ifNot)(this.router.hasPlugin('LISTENERS_PLUGIN'), '[react-router5][withRoute] missing listeners plugin'); 51 | 52 | this.listener = function (toState, fromState) { 53 | return _this2.setState({ previousRoute: fromState, route: toState }); 54 | }; 55 | this.router.addListener(this.listener); 56 | } 57 | }, { 58 | key: 'componentWillUnmount', 59 | value: function componentWillUnmount() { 60 | this.router.removeListener(this.listener); 61 | } 62 | }, { 63 | key: 'listener', 64 | value: function listener(toState, fromState) { 65 | this.setState({ 66 | previousRoute: fromState, 67 | route: toState 68 | }); 69 | } 70 | }, { 71 | key: 'render', 72 | value: function render() { 73 | (0, _utils.ifNot)(!this.props.router && !this.props.route && !this.props.previousRoute, '[react-router5] prop names `router`, `route` and `previousRoute` are reserved.'); 74 | 75 | return (0, _react.createElement)(BaseComponent, _extends({}, this.props, this.state, { router: this.router })); 76 | } 77 | }]); 78 | 79 | return ComponentWithRoute; 80 | }(_react.Component); 81 | 82 | ComponentWithRoute.contextTypes = { 83 | router: _propTypes2.default.object.isRequired 84 | }; 85 | 86 | ComponentWithRoute.displayName = 'WithRoute[' + (0, _utils.getDisplayName)(BaseComponent) + ']'; 87 | 88 | return ComponentWithRoute; 89 | } 90 | 91 | exports.default = withRoute; -------------------------------------------------------------------------------- /dist/es/BaseLink.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | var BaseLink = function (_Component) { 5 | babelHelpers.inherits(BaseLink, _Component); 6 | 7 | function BaseLink(props, context) { 8 | babelHelpers.classCallCheck(this, BaseLink); 9 | 10 | var _this = babelHelpers.possibleConstructorReturn(this, (BaseLink.__proto__ || Object.getPrototypeOf(BaseLink)).call(this, props, context)); 11 | 12 | _this.router = context.router; 13 | 14 | if (!_this.router.hasPlugin('BROWSER_PLUGIN')) { 15 | console.error('[react-router5][BaseLink] missing browser plugin, href might be build incorrectly'); 16 | }; 17 | 18 | _this.isActive = _this.isActive.bind(_this); 19 | _this.clickHandler = _this.clickHandler.bind(_this); 20 | 21 | _this.state = { active: _this.isActive() }; 22 | return _this; 23 | } 24 | 25 | babelHelpers.createClass(BaseLink, [{ 26 | key: 'buildUrl', 27 | value: function buildUrl(routeName, routeParams) { 28 | if (this.router.buildUrl) { 29 | return this.router.buildUrl(routeName, routeParams); 30 | } 31 | 32 | return this.router.buildPath(routeName, routeParams); 33 | } 34 | }, { 35 | key: 'isActive', 36 | value: function isActive() { 37 | return this.router.isActive(this.props.routeName, this.props.routeParams, this.props.activeStrict); 38 | } 39 | }, { 40 | key: 'clickHandler', 41 | value: function clickHandler(evt) { 42 | if (this.props.onClick) { 43 | this.props.onClick(evt); 44 | 45 | if (evt.defaultPrevented) { 46 | return; 47 | } 48 | } 49 | 50 | var comboKey = evt.metaKey || evt.altKey || evt.ctrlKey || evt.shiftKey; 51 | 52 | if (evt.button === 0 && !comboKey) { 53 | evt.preventDefault(); 54 | this.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions); 55 | } 56 | } 57 | }, { 58 | key: 'render', 59 | value: function render() { 60 | var _props = this.props, 61 | routeName = _props.routeName, 62 | routeParams = _props.routeParams, 63 | className = _props.className, 64 | activeClassName = _props.activeClassName, 65 | children = _props.children, 66 | title = _props.title, 67 | onMouseOver = _props.onMouseOver; 68 | 69 | 70 | var active = this.isActive(); 71 | var href = this.buildUrl(routeName, routeParams); 72 | var linkclassName = (className ? className.split(' ') : []).concat(active ? [activeClassName] : []).join(' '); 73 | 74 | return React.createElement('a', { 75 | href: href, 76 | className: linkclassName, 77 | onClick: this.clickHandler, 78 | onMouseOver: onMouseOver, 79 | title: title 80 | }, children); 81 | } 82 | }]); 83 | return BaseLink; 84 | }(Component); 85 | 86 | BaseLink.contextTypes = { 87 | router: PropTypes.object.isRequired 88 | }; 89 | 90 | BaseLink.propTypes = { 91 | routeName: PropTypes.string.isRequired, 92 | routeParams: PropTypes.object, 93 | routeOptions: PropTypes.object, 94 | activeClassName: PropTypes.string, 95 | activeStrict: PropTypes.bool, 96 | onClick: PropTypes.func, 97 | onMouseOver: PropTypes.func 98 | }; 99 | 100 | BaseLink.defaultProps = { 101 | activeClassName: 'active', 102 | activeStrict: false, 103 | routeParams: {}, 104 | routeOptions: {} 105 | }; 106 | 107 | export default BaseLink; -------------------------------------------------------------------------------- /dist/es/RouterProvider.js: -------------------------------------------------------------------------------- 1 | import { Component, Children } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | var RouterProvider = function (_Component) { 5 | babelHelpers.inherits(RouterProvider, _Component); 6 | 7 | function RouterProvider(props, context) { 8 | babelHelpers.classCallCheck(this, RouterProvider); 9 | 10 | var _this = babelHelpers.possibleConstructorReturn(this, (RouterProvider.__proto__ || Object.getPrototypeOf(RouterProvider)).call(this, props, context)); 11 | 12 | _this.router = props.router; 13 | return _this; 14 | } 15 | 16 | babelHelpers.createClass(RouterProvider, [{ 17 | key: 'getChildContext', 18 | value: function getChildContext() { 19 | return { router: this.router }; 20 | } 21 | }, { 22 | key: 'componentWillReceiveProps', 23 | value: function componentWillReceiveProps(nextProps) { 24 | if (this.props.router !== nextProps.router) { 25 | console.error('[react-router5][RouterProvider] does not support changing the router object.'); 26 | } 27 | } 28 | }, { 29 | key: 'render', 30 | value: function render() { 31 | var children = this.props.children; 32 | 33 | return Children.only(children); 34 | } 35 | }]); 36 | return RouterProvider; 37 | }(Component); 38 | 39 | RouterProvider.propTypes = { 40 | router: PropTypes.object.isRequired, 41 | children: PropTypes.element.isRequired 42 | }; 43 | 44 | RouterProvider.childContextTypes = { 45 | router: PropTypes.object.isRequired 46 | }; 47 | 48 | export default RouterProvider; -------------------------------------------------------------------------------- /dist/es/index.js: -------------------------------------------------------------------------------- 1 | import BaseLink from './BaseLink'; 2 | import routeNode from './routeNode'; 3 | import RouterProvider from './RouterProvider'; 4 | import withRoute from './withRoute'; 5 | 6 | var Link = withRoute(BaseLink); 7 | 8 | export { BaseLink, routeNode, RouterProvider, withRoute, Link }; -------------------------------------------------------------------------------- /dist/es/routeNode.js: -------------------------------------------------------------------------------- 1 | import { Component, createElement } from 'react'; 2 | import { getDisplayName, ifNot } from './utils'; 3 | import PropTypes from 'prop-types'; 4 | 5 | function routeNode(nodeName) { 6 | return function routeNodeWrapper(RouteSegment) { 7 | var RouteNode = function (_Component) { 8 | babelHelpers.inherits(RouteNode, _Component); 9 | 10 | function RouteNode(props, context) { 11 | babelHelpers.classCallCheck(this, RouteNode); 12 | 13 | var _this = babelHelpers.possibleConstructorReturn(this, (RouteNode.__proto__ || Object.getPrototypeOf(RouteNode)).call(this, props, context)); 14 | 15 | _this.router = context.router; 16 | _this.state = { 17 | previousRoute: null, 18 | route: _this.router.getState() 19 | }; 20 | return _this; 21 | } 22 | 23 | babelHelpers.createClass(RouteNode, [{ 24 | key: 'componentDidMount', 25 | value: function componentDidMount() { 26 | var _this2 = this; 27 | 28 | ifNot(this.router.hasPlugin('LISTENERS_PLUGIN'), '[react-router5][routeNode] missing listeners plugin'); 29 | 30 | this.nodeListener = function (toState, fromState) { 31 | return _this2.setState({ previousRoute: fromState, route: toState }); 32 | }; 33 | this.router.addNodeListener(nodeName, this.nodeListener); 34 | } 35 | }, { 36 | key: 'componentWillUnmout', 37 | value: function componentWillUnmout() { 38 | this.router.removeNodeListener(nodeName, this.nodeListener); 39 | } 40 | }, { 41 | key: 'render', 42 | value: function render() { 43 | var props = this.props, 44 | router = this.router; 45 | var _state = this.state, 46 | previousRoute = _state.previousRoute, 47 | route = _state.route; 48 | 49 | var component = createElement(RouteSegment, babelHelpers.extends({}, props, { router: router, previousRoute: previousRoute, route: route })); 50 | 51 | return component; 52 | } 53 | }]); 54 | return RouteNode; 55 | }(Component); 56 | 57 | RouteNode.contextTypes = { 58 | router: PropTypes.object.isRequired 59 | }; 60 | 61 | RouteNode.displayName = 'RouteNode[' + getDisplayName(RouteSegment) + ']'; 62 | 63 | return RouteNode; 64 | }; 65 | } 66 | 67 | export default routeNode; -------------------------------------------------------------------------------- /dist/es/utils.js: -------------------------------------------------------------------------------- 1 | export var getDisplayName = function getDisplayName(component) { 2 | return component.displayName || component.name || 'Component'; 3 | }; 4 | 5 | export var ifNot = function ifNot(condition, errorMessage) { 6 | if (!condition) throw new Error(errorMessage); 7 | }; -------------------------------------------------------------------------------- /dist/es/withRoute.js: -------------------------------------------------------------------------------- 1 | import { Component, createElement } from 'react'; 2 | import { ifNot, getDisplayName } from './utils'; 3 | import PropTypes from 'prop-types'; 4 | 5 | function withRoute(BaseComponent) { 6 | var ComponentWithRoute = function (_Component) { 7 | babelHelpers.inherits(ComponentWithRoute, _Component); 8 | 9 | function ComponentWithRoute(props, context) { 10 | babelHelpers.classCallCheck(this, ComponentWithRoute); 11 | 12 | var _this = babelHelpers.possibleConstructorReturn(this, (ComponentWithRoute.__proto__ || Object.getPrototypeOf(ComponentWithRoute)).call(this, props, context)); 13 | 14 | _this.router = context.router; 15 | _this.state = { 16 | previousRoute: null, 17 | route: _this.router.getState() 18 | }; 19 | _this.listener = _this.listener.bind(_this); 20 | return _this; 21 | } 22 | 23 | babelHelpers.createClass(ComponentWithRoute, [{ 24 | key: 'componentDidMount', 25 | value: function componentDidMount() { 26 | var _this2 = this; 27 | 28 | ifNot(this.router.hasPlugin('LISTENERS_PLUGIN'), '[react-router5][withRoute] missing listeners plugin'); 29 | 30 | this.listener = function (toState, fromState) { 31 | return _this2.setState({ previousRoute: fromState, route: toState }); 32 | }; 33 | this.router.addListener(this.listener); 34 | } 35 | }, { 36 | key: 'componentWillUnmount', 37 | value: function componentWillUnmount() { 38 | this.router.removeListener(this.listener); 39 | } 40 | }, { 41 | key: 'listener', 42 | value: function listener(toState, fromState) { 43 | this.setState({ 44 | previousRoute: fromState, 45 | route: toState 46 | }); 47 | } 48 | }, { 49 | key: 'render', 50 | value: function render() { 51 | ifNot(!this.props.router && !this.props.route && !this.props.previousRoute, '[react-router5] prop names `router`, `route` and `previousRoute` are reserved.'); 52 | 53 | return createElement(BaseComponent, babelHelpers.extends({}, this.props, this.state, { router: this.router })); 54 | } 55 | }]); 56 | return ComponentWithRoute; 57 | }(Component); 58 | 59 | ComponentWithRoute.contextTypes = { 60 | router: PropTypes.object.isRequired 61 | }; 62 | 63 | ComponentWithRoute.displayName = 'WithRoute[' + getDisplayName(BaseComponent) + ']'; 64 | 65 | return ComponentWithRoute; 66 | } 67 | 68 | export default withRoute; -------------------------------------------------------------------------------- /dist/umd/react-router5.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) : 3 | typeof define === 'function' && define.amd ? define('reactRouter5', ['exports', 'react'], factory) : 4 | (factory((global.reactRouter5 = global.reactRouter5 || {}),global.React)); 5 | }(this, (function (exports,React) { 'use strict'; 6 | 7 | var React__default = 'default' in React ? React['default'] : React; 8 | 9 | function createCommonjsModule(fn, module) { 10 | return module = { exports: {} }, fn(module, module.exports), module.exports; 11 | } 12 | 13 | /** 14 | * Copyright (c) 2013-present, Facebook, Inc. 15 | * All rights reserved. 16 | * 17 | * This source code is licensed under the BSD-style license found in the 18 | * LICENSE file in the root directory of this source tree. An additional grant 19 | * of patent rights can be found in the PATENTS file in the same directory. 20 | * 21 | * 22 | */ 23 | 24 | function makeEmptyFunction(arg) { 25 | return function () { 26 | return arg; 27 | }; 28 | } 29 | 30 | /** 31 | * This function accepts and discards inputs; it has no side effects. This is 32 | * primarily useful idiomatically for overridable function endpoints which 33 | * always need to be callable, since JS lacks a null-call idiom ala Cocoa. 34 | */ 35 | var emptyFunction = function emptyFunction() {}; 36 | 37 | emptyFunction.thatReturns = makeEmptyFunction; 38 | emptyFunction.thatReturnsFalse = makeEmptyFunction(false); 39 | emptyFunction.thatReturnsTrue = makeEmptyFunction(true); 40 | emptyFunction.thatReturnsNull = makeEmptyFunction(null); 41 | emptyFunction.thatReturnsThis = function () { 42 | return this; 43 | }; 44 | emptyFunction.thatReturnsArgument = function (arg) { 45 | return arg; 46 | }; 47 | 48 | var emptyFunction_1 = emptyFunction; 49 | 50 | /** 51 | * Copyright (c) 2013-present, Facebook, Inc. 52 | * All rights reserved. 53 | * 54 | * This source code is licensed under the BSD-style license found in the 55 | * LICENSE file in the root directory of this source tree. An additional grant 56 | * of patent rights can be found in the PATENTS file in the same directory. 57 | * 58 | */ 59 | 60 | /** 61 | * Use invariant() to assert state which your program assumes to be true. 62 | * 63 | * Provide sprintf-style format (only %s is supported) and arguments 64 | * to provide information about what broke and what you were 65 | * expecting. 66 | * 67 | * The invariant message will be stripped in production, but the invariant 68 | * will remain to ensure logic does not differ in production. 69 | */ 70 | 71 | var validateFormat = function validateFormat(format) {}; 72 | 73 | if (process.env.NODE_ENV !== 'production') { 74 | validateFormat = function validateFormat(format) { 75 | if (format === undefined) { 76 | throw new Error('invariant requires an error message argument'); 77 | } 78 | }; 79 | } 80 | 81 | function invariant(condition, format, a, b, c, d, e, f) { 82 | validateFormat(format); 83 | 84 | if (!condition) { 85 | var error; 86 | if (format === undefined) { 87 | error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); 88 | } else { 89 | var args = [a, b, c, d, e, f]; 90 | var argIndex = 0; 91 | error = new Error(format.replace(/%s/g, function () { 92 | return args[argIndex++]; 93 | })); 94 | error.name = 'Invariant Violation'; 95 | } 96 | 97 | error.framesToPop = 1; // we don't care about invariant's own frame 98 | throw error; 99 | } 100 | } 101 | 102 | var invariant_1 = invariant; 103 | 104 | /** 105 | * Similar to invariant but only logs a warning if the condition is not met. 106 | * This can be used to log issues in development environments in critical 107 | * paths. Removing the logging code for production environments will keep the 108 | * same logic and follow the same code paths. 109 | */ 110 | 111 | var warning = emptyFunction_1; 112 | 113 | if (process.env.NODE_ENV !== 'production') { 114 | (function () { 115 | var printWarning = function printWarning(format) { 116 | for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 117 | args[_key - 1] = arguments[_key]; 118 | } 119 | 120 | var argIndex = 0; 121 | var message = 'Warning: ' + format.replace(/%s/g, function () { 122 | return args[argIndex++]; 123 | }); 124 | if (typeof console !== 'undefined') { 125 | console.error(message); 126 | } 127 | try { 128 | // --- Welcome to debugging React --- 129 | // This error was thrown as a convenience so that you can use this stack 130 | // to find the callsite that caused this warning to fire. 131 | throw new Error(message); 132 | } catch (x) {} 133 | }; 134 | 135 | warning = function warning(condition, format) { 136 | if (format === undefined) { 137 | throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); 138 | } 139 | 140 | if (format.indexOf('Failed Composite propType: ') === 0) { 141 | return; // Ignore CompositeComponent proptype check. 142 | } 143 | 144 | if (!condition) { 145 | for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { 146 | args[_key2 - 2] = arguments[_key2]; 147 | } 148 | 149 | printWarning.apply(undefined, [format].concat(args)); 150 | } 151 | }; 152 | })(); 153 | } 154 | 155 | var warning_1 = warning; 156 | 157 | /** 158 | * Copyright 2013-present, Facebook, Inc. 159 | * All rights reserved. 160 | * 161 | * This source code is licensed under the BSD-style license found in the 162 | * LICENSE file in the root directory of this source tree. An additional grant 163 | * of patent rights can be found in the PATENTS file in the same directory. 164 | */ 165 | 166 | var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; 167 | 168 | var ReactPropTypesSecret_1 = ReactPropTypesSecret; 169 | 170 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 171 | return typeof obj; 172 | } : function (obj) { 173 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 174 | }; 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | var classCallCheck = function (instance, Constructor) { 187 | if (!(instance instanceof Constructor)) { 188 | throw new TypeError("Cannot call a class as a function"); 189 | } 190 | }; 191 | 192 | var createClass = function () { 193 | function defineProperties(target, props) { 194 | for (var i = 0; i < props.length; i++) { 195 | var descriptor = props[i]; 196 | descriptor.enumerable = descriptor.enumerable || false; 197 | descriptor.configurable = true; 198 | if ("value" in descriptor) descriptor.writable = true; 199 | Object.defineProperty(target, descriptor.key, descriptor); 200 | } 201 | } 202 | 203 | return function (Constructor, protoProps, staticProps) { 204 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 205 | if (staticProps) defineProperties(Constructor, staticProps); 206 | return Constructor; 207 | }; 208 | }(); 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | var _extends = Object.assign || function (target) { 217 | for (var i = 1; i < arguments.length; i++) { 218 | var source = arguments[i]; 219 | 220 | for (var key in source) { 221 | if (Object.prototype.hasOwnProperty.call(source, key)) { 222 | target[key] = source[key]; 223 | } 224 | } 225 | } 226 | 227 | return target; 228 | }; 229 | 230 | 231 | 232 | var inherits = function (subClass, superClass) { 233 | if (typeof superClass !== "function" && superClass !== null) { 234 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 235 | } 236 | 237 | subClass.prototype = Object.create(superClass && superClass.prototype, { 238 | constructor: { 239 | value: subClass, 240 | enumerable: false, 241 | writable: true, 242 | configurable: true 243 | } 244 | }); 245 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 246 | }; 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | var possibleConstructorReturn = function (self, call) { 259 | if (!self) { 260 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 261 | } 262 | 263 | return call && (typeof call === "object" || typeof call === "function") ? call : self; 264 | }; 265 | 266 | if (process.env.NODE_ENV !== 'production') { 267 | var invariant$1 = invariant_1; 268 | var warning$1 = warning_1; 269 | var ReactPropTypesSecret$1 = ReactPropTypesSecret_1; 270 | var loggedTypeFailures = {}; 271 | } 272 | 273 | /** 274 | * Assert that the values match with the type specs. 275 | * Error messages are memorized and will only be shown once. 276 | * 277 | * @param {object} typeSpecs Map of name to a ReactPropType 278 | * @param {object} values Runtime values that need to be type-checked 279 | * @param {string} location e.g. "prop", "context", "child context" 280 | * @param {string} componentName Name of the component for error messages. 281 | * @param {?Function} getStack Returns the component stack. 282 | * @private 283 | */ 284 | function checkPropTypes(typeSpecs, values, location, componentName, getStack) { 285 | if (process.env.NODE_ENV !== 'production') { 286 | for (var typeSpecName in typeSpecs) { 287 | if (typeSpecs.hasOwnProperty(typeSpecName)) { 288 | var error; 289 | // Prop type validation may throw. In case they do, we don't want to 290 | // fail the render phase where it didn't fail before. So we log it. 291 | // After these have been cleaned up, we'll let them throw. 292 | try { 293 | // This is intentionally an invariant that gets caught. It's the same 294 | // behavior as without this statement except with a better message. 295 | invariant$1(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', location, typeSpecName); 296 | error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1); 297 | } catch (ex) { 298 | error = ex; 299 | } 300 | warning$1(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error === 'undefined' ? 'undefined' : _typeof(error)); 301 | if (error instanceof Error && !(error.message in loggedTypeFailures)) { 302 | // Only monitor this failure once because there tends to be a lot of the 303 | // same error. 304 | loggedTypeFailures[error.message] = true; 305 | 306 | var stack = getStack ? getStack() : ''; 307 | 308 | warning$1(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : ''); 309 | } 310 | } 311 | } 312 | } 313 | } 314 | 315 | var checkPropTypes_1 = checkPropTypes; 316 | 317 | var factoryWithTypeCheckers = function factoryWithTypeCheckers(isValidElement, throwOnDirectAccess) { 318 | /* global Symbol */ 319 | var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; 320 | var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. 321 | 322 | /** 323 | * Returns the iterator method function contained on the iterable object. 324 | * 325 | * Be sure to invoke the function with the iterable as context: 326 | * 327 | * var iteratorFn = getIteratorFn(myIterable); 328 | * if (iteratorFn) { 329 | * var iterator = iteratorFn.call(myIterable); 330 | * ... 331 | * } 332 | * 333 | * @param {?object} maybeIterable 334 | * @return {?function} 335 | */ 336 | function getIteratorFn(maybeIterable) { 337 | var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); 338 | if (typeof iteratorFn === 'function') { 339 | return iteratorFn; 340 | } 341 | } 342 | 343 | /** 344 | * Collection of methods that allow declaration and validation of props that are 345 | * supplied to React components. Example usage: 346 | * 347 | * var Props = require('ReactPropTypes'); 348 | * var MyArticle = React.createClass({ 349 | * propTypes: { 350 | * // An optional string prop named "description". 351 | * description: Props.string, 352 | * 353 | * // A required enum prop named "category". 354 | * category: Props.oneOf(['News','Photos']).isRequired, 355 | * 356 | * // A prop named "dialog" that requires an instance of Dialog. 357 | * dialog: Props.instanceOf(Dialog).isRequired 358 | * }, 359 | * render: function() { ... } 360 | * }); 361 | * 362 | * A more formal specification of how these methods are used: 363 | * 364 | * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) 365 | * decl := ReactPropTypes.{type}(.isRequired)? 366 | * 367 | * Each and every declaration produces a function with the same signature. This 368 | * allows the creation of custom validation functions. For example: 369 | * 370 | * var MyLink = React.createClass({ 371 | * propTypes: { 372 | * // An optional string or URI prop named "href". 373 | * href: function(props, propName, componentName) { 374 | * var propValue = props[propName]; 375 | * if (propValue != null && typeof propValue !== 'string' && 376 | * !(propValue instanceof URI)) { 377 | * return new Error( 378 | * 'Expected a string or an URI for ' + propName + ' in ' + 379 | * componentName 380 | * ); 381 | * } 382 | * } 383 | * }, 384 | * render: function() {...} 385 | * }); 386 | * 387 | * @internal 388 | */ 389 | 390 | var ANONYMOUS = '<>'; 391 | 392 | // Important! 393 | // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. 394 | var ReactPropTypes = { 395 | array: createPrimitiveTypeChecker('array'), 396 | bool: createPrimitiveTypeChecker('boolean'), 397 | func: createPrimitiveTypeChecker('function'), 398 | number: createPrimitiveTypeChecker('number'), 399 | object: createPrimitiveTypeChecker('object'), 400 | string: createPrimitiveTypeChecker('string'), 401 | symbol: createPrimitiveTypeChecker('symbol'), 402 | 403 | any: createAnyTypeChecker(), 404 | arrayOf: createArrayOfTypeChecker, 405 | element: createElementTypeChecker(), 406 | instanceOf: createInstanceTypeChecker, 407 | node: createNodeChecker(), 408 | objectOf: createObjectOfTypeChecker, 409 | oneOf: createEnumTypeChecker, 410 | oneOfType: createUnionTypeChecker, 411 | shape: createShapeTypeChecker 412 | }; 413 | 414 | /** 415 | * inlined Object.is polyfill to avoid requiring consumers ship their own 416 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 417 | */ 418 | /*eslint-disable no-self-compare*/ 419 | function is(x, y) { 420 | // SameValue algorithm 421 | if (x === y) { 422 | // Steps 1-5, 7-10 423 | // Steps 6.b-6.e: +0 != -0 424 | return x !== 0 || 1 / x === 1 / y; 425 | } else { 426 | // Step 6.a: NaN == NaN 427 | return x !== x && y !== y; 428 | } 429 | } 430 | /*eslint-enable no-self-compare*/ 431 | 432 | /** 433 | * We use an Error-like object for backward compatibility as people may call 434 | * PropTypes directly and inspect their output. However, we don't use real 435 | * Errors anymore. We don't inspect their stack anyway, and creating them 436 | * is prohibitively expensive if they are created too often, such as what 437 | * happens in oneOfType() for any type before the one that matched. 438 | */ 439 | function PropTypeError(message) { 440 | this.message = message; 441 | this.stack = ''; 442 | } 443 | // Make `instanceof Error` still work for returned errors. 444 | PropTypeError.prototype = Error.prototype; 445 | 446 | function createChainableTypeChecker(validate) { 447 | if (process.env.NODE_ENV !== 'production') { 448 | var manualPropTypeCallCache = {}; 449 | var manualPropTypeWarningCount = 0; 450 | } 451 | function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { 452 | componentName = componentName || ANONYMOUS; 453 | propFullName = propFullName || propName; 454 | 455 | if (secret !== ReactPropTypesSecret_1) { 456 | if (throwOnDirectAccess) { 457 | // New behavior only for users of `prop-types` package 458 | invariant_1(false, 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use `PropTypes.checkPropTypes()` to call them. ' + 'Read more at http://fb.me/use-check-prop-types'); 459 | } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') { 460 | // Old behavior for people using React.PropTypes 461 | var cacheKey = componentName + ':' + propName; 462 | if (!manualPropTypeCallCache[cacheKey] && 463 | // Avoid spamming the console because they are often not actionable except for lib authors 464 | manualPropTypeWarningCount < 3) { 465 | warning_1(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will throw in the standalone `prop-types` package. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', propFullName, componentName); 466 | manualPropTypeCallCache[cacheKey] = true; 467 | manualPropTypeWarningCount++; 468 | } 469 | } 470 | } 471 | if (props[propName] == null) { 472 | if (isRequired) { 473 | if (props[propName] === null) { 474 | return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); 475 | } 476 | return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); 477 | } 478 | return null; 479 | } else { 480 | return validate(props, propName, componentName, location, propFullName); 481 | } 482 | } 483 | 484 | var chainedCheckType = checkType.bind(null, false); 485 | chainedCheckType.isRequired = checkType.bind(null, true); 486 | 487 | return chainedCheckType; 488 | } 489 | 490 | function createPrimitiveTypeChecker(expectedType) { 491 | function validate(props, propName, componentName, location, propFullName, secret) { 492 | var propValue = props[propName]; 493 | var propType = getPropType(propValue); 494 | if (propType !== expectedType) { 495 | // `propValue` being instance of, say, date/regexp, pass the 'object' 496 | // check, but we can offer a more precise error message here rather than 497 | // 'of type `object`'. 498 | var preciseType = getPreciseType(propValue); 499 | 500 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); 501 | } 502 | return null; 503 | } 504 | return createChainableTypeChecker(validate); 505 | } 506 | 507 | function createAnyTypeChecker() { 508 | return createChainableTypeChecker(emptyFunction_1.thatReturnsNull); 509 | } 510 | 511 | function createArrayOfTypeChecker(typeChecker) { 512 | function validate(props, propName, componentName, location, propFullName) { 513 | if (typeof typeChecker !== 'function') { 514 | return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); 515 | } 516 | var propValue = props[propName]; 517 | if (!Array.isArray(propValue)) { 518 | var propType = getPropType(propValue); 519 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); 520 | } 521 | for (var i = 0; i < propValue.length; i++) { 522 | var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret_1); 523 | if (error instanceof Error) { 524 | return error; 525 | } 526 | } 527 | return null; 528 | } 529 | return createChainableTypeChecker(validate); 530 | } 531 | 532 | function createElementTypeChecker() { 533 | function validate(props, propName, componentName, location, propFullName) { 534 | var propValue = props[propName]; 535 | if (!isValidElement(propValue)) { 536 | var propType = getPropType(propValue); 537 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); 538 | } 539 | return null; 540 | } 541 | return createChainableTypeChecker(validate); 542 | } 543 | 544 | function createInstanceTypeChecker(expectedClass) { 545 | function validate(props, propName, componentName, location, propFullName) { 546 | if (!(props[propName] instanceof expectedClass)) { 547 | var expectedClassName = expectedClass.name || ANONYMOUS; 548 | var actualClassName = getClassName(props[propName]); 549 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); 550 | } 551 | return null; 552 | } 553 | return createChainableTypeChecker(validate); 554 | } 555 | 556 | function createEnumTypeChecker(expectedValues) { 557 | if (!Array.isArray(expectedValues)) { 558 | process.env.NODE_ENV !== 'production' ? warning_1(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; 559 | return emptyFunction_1.thatReturnsNull; 560 | } 561 | 562 | function validate(props, propName, componentName, location, propFullName) { 563 | var propValue = props[propName]; 564 | for (var i = 0; i < expectedValues.length; i++) { 565 | if (is(propValue, expectedValues[i])) { 566 | return null; 567 | } 568 | } 569 | 570 | var valuesString = JSON.stringify(expectedValues); 571 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); 572 | } 573 | return createChainableTypeChecker(validate); 574 | } 575 | 576 | function createObjectOfTypeChecker(typeChecker) { 577 | function validate(props, propName, componentName, location, propFullName) { 578 | if (typeof typeChecker !== 'function') { 579 | return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); 580 | } 581 | var propValue = props[propName]; 582 | var propType = getPropType(propValue); 583 | if (propType !== 'object') { 584 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); 585 | } 586 | for (var key in propValue) { 587 | if (propValue.hasOwnProperty(key)) { 588 | var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret_1); 589 | if (error instanceof Error) { 590 | return error; 591 | } 592 | } 593 | } 594 | return null; 595 | } 596 | return createChainableTypeChecker(validate); 597 | } 598 | 599 | function createUnionTypeChecker(arrayOfTypeCheckers) { 600 | if (!Array.isArray(arrayOfTypeCheckers)) { 601 | process.env.NODE_ENV !== 'production' ? warning_1(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; 602 | return emptyFunction_1.thatReturnsNull; 603 | } 604 | 605 | for (var i = 0; i < arrayOfTypeCheckers.length; i++) { 606 | var checker = arrayOfTypeCheckers[i]; 607 | if (typeof checker !== 'function') { 608 | warning_1(false, 'Invalid argument supplid to oneOfType. Expected an array of check functions, but ' + 'received %s at index %s.', getPostfixForTypeWarning(checker), i); 609 | return emptyFunction_1.thatReturnsNull; 610 | } 611 | } 612 | 613 | function validate(props, propName, componentName, location, propFullName) { 614 | for (var i = 0; i < arrayOfTypeCheckers.length; i++) { 615 | var checker = arrayOfTypeCheckers[i]; 616 | if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret_1) == null) { 617 | return null; 618 | } 619 | } 620 | 621 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); 622 | } 623 | return createChainableTypeChecker(validate); 624 | } 625 | 626 | function createNodeChecker() { 627 | function validate(props, propName, componentName, location, propFullName) { 628 | if (!isNode(props[propName])) { 629 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); 630 | } 631 | return null; 632 | } 633 | return createChainableTypeChecker(validate); 634 | } 635 | 636 | function createShapeTypeChecker(shapeTypes) { 637 | function validate(props, propName, componentName, location, propFullName) { 638 | var propValue = props[propName]; 639 | var propType = getPropType(propValue); 640 | if (propType !== 'object') { 641 | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); 642 | } 643 | for (var key in shapeTypes) { 644 | var checker = shapeTypes[key]; 645 | if (!checker) { 646 | continue; 647 | } 648 | var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret_1); 649 | if (error) { 650 | return error; 651 | } 652 | } 653 | return null; 654 | } 655 | return createChainableTypeChecker(validate); 656 | } 657 | 658 | function isNode(propValue) { 659 | switch (typeof propValue === 'undefined' ? 'undefined' : _typeof(propValue)) { 660 | case 'number': 661 | case 'string': 662 | case 'undefined': 663 | return true; 664 | case 'boolean': 665 | return !propValue; 666 | case 'object': 667 | if (Array.isArray(propValue)) { 668 | return propValue.every(isNode); 669 | } 670 | if (propValue === null || isValidElement(propValue)) { 671 | return true; 672 | } 673 | 674 | var iteratorFn = getIteratorFn(propValue); 675 | if (iteratorFn) { 676 | var iterator = iteratorFn.call(propValue); 677 | var step; 678 | if (iteratorFn !== propValue.entries) { 679 | while (!(step = iterator.next()).done) { 680 | if (!isNode(step.value)) { 681 | return false; 682 | } 683 | } 684 | } else { 685 | // Iterator will provide entry [k,v] tuples rather than values. 686 | while (!(step = iterator.next()).done) { 687 | var entry = step.value; 688 | if (entry) { 689 | if (!isNode(entry[1])) { 690 | return false; 691 | } 692 | } 693 | } 694 | } 695 | } else { 696 | return false; 697 | } 698 | 699 | return true; 700 | default: 701 | return false; 702 | } 703 | } 704 | 705 | function isSymbol(propType, propValue) { 706 | // Native Symbol. 707 | if (propType === 'symbol') { 708 | return true; 709 | } 710 | 711 | // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' 712 | if (propValue['@@toStringTag'] === 'Symbol') { 713 | return true; 714 | } 715 | 716 | // Fallback for non-spec compliant Symbols which are polyfilled. 717 | if (typeof Symbol === 'function' && propValue instanceof Symbol) { 718 | return true; 719 | } 720 | 721 | return false; 722 | } 723 | 724 | // Equivalent of `typeof` but with special handling for array and regexp. 725 | function getPropType(propValue) { 726 | var propType = typeof propValue === 'undefined' ? 'undefined' : _typeof(propValue); 727 | if (Array.isArray(propValue)) { 728 | return 'array'; 729 | } 730 | if (propValue instanceof RegExp) { 731 | // Old webkits (at least until Android 4.0) return 'function' rather than 732 | // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ 733 | // passes PropTypes.object. 734 | return 'object'; 735 | } 736 | if (isSymbol(propType, propValue)) { 737 | return 'symbol'; 738 | } 739 | return propType; 740 | } 741 | 742 | // This handles more types than `getPropType`. Only used for error messages. 743 | // See `createPrimitiveTypeChecker`. 744 | function getPreciseType(propValue) { 745 | if (typeof propValue === 'undefined' || propValue === null) { 746 | return '' + propValue; 747 | } 748 | var propType = getPropType(propValue); 749 | if (propType === 'object') { 750 | if (propValue instanceof Date) { 751 | return 'date'; 752 | } else if (propValue instanceof RegExp) { 753 | return 'regexp'; 754 | } 755 | } 756 | return propType; 757 | } 758 | 759 | // Returns a string that is postfixed to a warning about an invalid type. 760 | // For example, "undefined" or "of type array" 761 | function getPostfixForTypeWarning(value) { 762 | var type = getPreciseType(value); 763 | switch (type) { 764 | case 'array': 765 | case 'object': 766 | return 'an ' + type; 767 | case 'boolean': 768 | case 'date': 769 | case 'regexp': 770 | return 'a ' + type; 771 | default: 772 | return type; 773 | } 774 | } 775 | 776 | // Returns class name of the object, if any. 777 | function getClassName(propValue) { 778 | if (!propValue.constructor || !propValue.constructor.name) { 779 | return ANONYMOUS; 780 | } 781 | return propValue.constructor.name; 782 | } 783 | 784 | ReactPropTypes.checkPropTypes = checkPropTypes_1; 785 | ReactPropTypes.PropTypes = ReactPropTypes; 786 | 787 | return ReactPropTypes; 788 | }; 789 | 790 | var factoryWithThrowingShims = function factoryWithThrowingShims() { 791 | function shim(props, propName, componentName, location, propFullName, secret) { 792 | if (secret === ReactPropTypesSecret_1) { 793 | // It is still safe when called from React. 794 | return; 795 | } 796 | invariant_1(false, 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use PropTypes.checkPropTypes() to call them. ' + 'Read more at http://fb.me/use-check-prop-types'); 797 | } 798 | shim.isRequired = shim; 799 | function getShim() { 800 | return shim; 801 | } 802 | // Important! 803 | // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. 804 | var ReactPropTypes = { 805 | array: shim, 806 | bool: shim, 807 | func: shim, 808 | number: shim, 809 | object: shim, 810 | string: shim, 811 | symbol: shim, 812 | 813 | any: shim, 814 | arrayOf: getShim, 815 | element: shim, 816 | instanceOf: getShim, 817 | node: shim, 818 | objectOf: getShim, 819 | oneOf: getShim, 820 | oneOfType: getShim, 821 | shape: getShim 822 | }; 823 | 824 | ReactPropTypes.checkPropTypes = emptyFunction_1; 825 | ReactPropTypes.PropTypes = ReactPropTypes; 826 | 827 | return ReactPropTypes; 828 | }; 829 | 830 | var index = createCommonjsModule(function (module) { 831 | /** 832 | * Copyright 2013-present, Facebook, Inc. 833 | * All rights reserved. 834 | * 835 | * This source code is licensed under the BSD-style license found in the 836 | * LICENSE file in the root directory of this source tree. An additional grant 837 | * of patent rights can be found in the PATENTS file in the same directory. 838 | */ 839 | 840 | if (process.env.NODE_ENV !== 'production') { 841 | var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element') || 0xeac7; 842 | 843 | var isValidElement = function isValidElement(object) { 844 | return (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; 845 | }; 846 | 847 | // By explicitly using `prop-types` you are opting into new development behavior. 848 | // http://fb.me/prop-types-in-prod 849 | var throwOnDirectAccess = true; 850 | module.exports = factoryWithTypeCheckers(isValidElement, throwOnDirectAccess); 851 | } else { 852 | // By explicitly using `prop-types` you are opting into new production behavior. 853 | // http://fb.me/prop-types-in-prod 854 | module.exports = factoryWithThrowingShims(); 855 | } 856 | }); 857 | 858 | var BaseLink = function (_Component) { 859 | inherits(BaseLink, _Component); 860 | 861 | function BaseLink(props, context) { 862 | classCallCheck(this, BaseLink); 863 | 864 | var _this = possibleConstructorReturn(this, (BaseLink.__proto__ || Object.getPrototypeOf(BaseLink)).call(this, props, context)); 865 | 866 | _this.router = context.router; 867 | 868 | if (!_this.router.hasPlugin('BROWSER_PLUGIN')) { 869 | console.error('[react-router5][BaseLink] missing browser plugin, href might be build incorrectly'); 870 | } 871 | 872 | _this.isActive = _this.isActive.bind(_this); 873 | _this.clickHandler = _this.clickHandler.bind(_this); 874 | 875 | _this.state = { active: _this.isActive() }; 876 | return _this; 877 | } 878 | 879 | createClass(BaseLink, [{ 880 | key: 'buildUrl', 881 | value: function buildUrl(routeName, routeParams) { 882 | if (this.router.buildUrl) { 883 | return this.router.buildUrl(routeName, routeParams); 884 | } 885 | 886 | return this.router.buildPath(routeName, routeParams); 887 | } 888 | }, { 889 | key: 'isActive', 890 | value: function isActive() { 891 | return this.router.isActive(this.props.routeName, this.props.routeParams, this.props.activeStrict); 892 | } 893 | }, { 894 | key: 'clickHandler', 895 | value: function clickHandler(evt) { 896 | if (this.props.onClick) { 897 | this.props.onClick(evt); 898 | 899 | if (evt.defaultPrevented) { 900 | return; 901 | } 902 | } 903 | 904 | var comboKey = evt.metaKey || evt.altKey || evt.ctrlKey || evt.shiftKey; 905 | 906 | if (evt.button === 0 && !comboKey) { 907 | evt.preventDefault(); 908 | this.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions); 909 | } 910 | } 911 | }, { 912 | key: 'render', 913 | value: function render() { 914 | var _props = this.props, 915 | routeName = _props.routeName, 916 | routeParams = _props.routeParams, 917 | className = _props.className, 918 | activeClassName = _props.activeClassName, 919 | children = _props.children, 920 | title = _props.title, 921 | onMouseOver = _props.onMouseOver; 922 | 923 | 924 | var active = this.isActive(); 925 | var href = this.buildUrl(routeName, routeParams); 926 | var linkclassName = (className ? className.split(' ') : []).concat(active ? [activeClassName] : []).join(' '); 927 | 928 | return React__default.createElement('a', { 929 | href: href, 930 | className: linkclassName, 931 | onClick: this.clickHandler, 932 | onMouseOver: onMouseOver, 933 | title: title 934 | }, children); 935 | } 936 | }]); 937 | return BaseLink; 938 | }(React.Component); 939 | 940 | BaseLink.contextTypes = { 941 | router: index.object.isRequired 942 | }; 943 | 944 | BaseLink.propTypes = { 945 | routeName: index.string.isRequired, 946 | routeParams: index.object, 947 | routeOptions: index.object, 948 | activeClassName: index.string, 949 | activeStrict: index.bool, 950 | onClick: index.func, 951 | onMouseOver: index.func 952 | }; 953 | 954 | BaseLink.defaultProps = { 955 | activeClassName: 'active', 956 | activeStrict: false, 957 | routeParams: {}, 958 | routeOptions: {} 959 | }; 960 | 961 | var getDisplayName = function getDisplayName(component) { 962 | return component.displayName || component.name || 'Component'; 963 | }; 964 | 965 | var ifNot = function ifNot(condition, errorMessage) { 966 | if (!condition) throw new Error(errorMessage); 967 | }; 968 | 969 | function routeNode(nodeName) { 970 | return function routeNodeWrapper(RouteSegment) { 971 | var RouteNode = function (_Component) { 972 | inherits(RouteNode, _Component); 973 | 974 | function RouteNode(props, context) { 975 | classCallCheck(this, RouteNode); 976 | 977 | var _this = possibleConstructorReturn(this, (RouteNode.__proto__ || Object.getPrototypeOf(RouteNode)).call(this, props, context)); 978 | 979 | _this.router = context.router; 980 | _this.state = { 981 | previousRoute: null, 982 | route: _this.router.getState() 983 | }; 984 | return _this; 985 | } 986 | 987 | createClass(RouteNode, [{ 988 | key: 'componentDidMount', 989 | value: function componentDidMount() { 990 | var _this2 = this; 991 | 992 | ifNot(this.router.hasPlugin('LISTENERS_PLUGIN'), '[react-router5][routeNode] missing listeners plugin'); 993 | 994 | this.nodeListener = function (toState, fromState) { 995 | return _this2.setState({ previousRoute: fromState, route: toState }); 996 | }; 997 | this.router.addNodeListener(nodeName, this.nodeListener); 998 | } 999 | }, { 1000 | key: 'componentWillUnmout', 1001 | value: function componentWillUnmout() { 1002 | this.router.removeNodeListener(nodeName, this.nodeListener); 1003 | } 1004 | }, { 1005 | key: 'render', 1006 | value: function render() { 1007 | var props = this.props, 1008 | router = this.router; 1009 | var _state = this.state, 1010 | previousRoute = _state.previousRoute, 1011 | route = _state.route; 1012 | 1013 | var component = React.createElement(RouteSegment, _extends({}, props, { router: router, previousRoute: previousRoute, route: route })); 1014 | 1015 | return component; 1016 | } 1017 | }]); 1018 | return RouteNode; 1019 | }(React.Component); 1020 | 1021 | RouteNode.contextTypes = { 1022 | router: index.object.isRequired 1023 | }; 1024 | 1025 | RouteNode.displayName = 'RouteNode[' + getDisplayName(RouteSegment) + ']'; 1026 | 1027 | return RouteNode; 1028 | }; 1029 | } 1030 | 1031 | var RouterProvider = function (_Component) { 1032 | inherits(RouterProvider, _Component); 1033 | 1034 | function RouterProvider(props, context) { 1035 | classCallCheck(this, RouterProvider); 1036 | 1037 | var _this = possibleConstructorReturn(this, (RouterProvider.__proto__ || Object.getPrototypeOf(RouterProvider)).call(this, props, context)); 1038 | 1039 | _this.router = props.router; 1040 | return _this; 1041 | } 1042 | 1043 | createClass(RouterProvider, [{ 1044 | key: 'getChildContext', 1045 | value: function getChildContext() { 1046 | return { router: this.router }; 1047 | } 1048 | }, { 1049 | key: 'componentWillReceiveProps', 1050 | value: function componentWillReceiveProps(nextProps) { 1051 | if (this.props.router !== nextProps.router) { 1052 | console.error('[react-router5][RouterProvider] does not support changing the router object.'); 1053 | } 1054 | } 1055 | }, { 1056 | key: 'render', 1057 | value: function render() { 1058 | var children = this.props.children; 1059 | 1060 | return React.Children.only(children); 1061 | } 1062 | }]); 1063 | return RouterProvider; 1064 | }(React.Component); 1065 | 1066 | RouterProvider.propTypes = { 1067 | router: index.object.isRequired, 1068 | children: index.element.isRequired 1069 | }; 1070 | 1071 | RouterProvider.childContextTypes = { 1072 | router: index.object.isRequired 1073 | }; 1074 | 1075 | function withRoute(BaseComponent) { 1076 | var ComponentWithRoute = function (_Component) { 1077 | inherits(ComponentWithRoute, _Component); 1078 | 1079 | function ComponentWithRoute(props, context) { 1080 | classCallCheck(this, ComponentWithRoute); 1081 | 1082 | var _this = possibleConstructorReturn(this, (ComponentWithRoute.__proto__ || Object.getPrototypeOf(ComponentWithRoute)).call(this, props, context)); 1083 | 1084 | _this.router = context.router; 1085 | _this.state = { 1086 | previousRoute: null, 1087 | route: _this.router.getState() 1088 | }; 1089 | _this.listener = _this.listener.bind(_this); 1090 | return _this; 1091 | } 1092 | 1093 | createClass(ComponentWithRoute, [{ 1094 | key: 'componentDidMount', 1095 | value: function componentDidMount() { 1096 | var _this2 = this; 1097 | 1098 | ifNot(this.router.hasPlugin('LISTENERS_PLUGIN'), '[react-router5][withRoute] missing listeners plugin'); 1099 | 1100 | this.listener = function (toState, fromState) { 1101 | return _this2.setState({ previousRoute: fromState, route: toState }); 1102 | }; 1103 | this.router.addListener(this.listener); 1104 | } 1105 | }, { 1106 | key: 'componentWillUnmount', 1107 | value: function componentWillUnmount() { 1108 | this.router.removeListener(this.listener); 1109 | } 1110 | }, { 1111 | key: 'listener', 1112 | value: function listener(toState, fromState) { 1113 | this.setState({ 1114 | previousRoute: fromState, 1115 | route: toState 1116 | }); 1117 | } 1118 | }, { 1119 | key: 'render', 1120 | value: function render() { 1121 | ifNot(!this.props.router && !this.props.route && !this.props.previousRoute, '[react-router5] prop names `router`, `route` and `previousRoute` are reserved.'); 1122 | 1123 | return React.createElement(BaseComponent, _extends({}, this.props, this.state, { router: this.router })); 1124 | } 1125 | }]); 1126 | return ComponentWithRoute; 1127 | }(React.Component); 1128 | 1129 | ComponentWithRoute.contextTypes = { 1130 | router: index.object.isRequired 1131 | }; 1132 | 1133 | ComponentWithRoute.displayName = 'WithRoute[' + getDisplayName(BaseComponent) + ']'; 1134 | 1135 | return ComponentWithRoute; 1136 | } 1137 | 1138 | var Link = withRoute(BaseLink); 1139 | 1140 | exports.BaseLink = BaseLink; 1141 | exports.routeNode = routeNode; 1142 | exports.RouterProvider = RouterProvider; 1143 | exports.withRoute = withRoute; 1144 | exports.Link = Link; 1145 | 1146 | Object.defineProperty(exports, '__esModule', { value: true }); 1147 | 1148 | }))); 1149 | -------------------------------------------------------------------------------- /modules/BaseLink.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class BaseLink extends Component { 5 | constructor(props, context) { 6 | super(props, context); 7 | 8 | this.router = context.router; 9 | 10 | if (!this.router.hasPlugin('BROWSER_PLUGIN')) { 11 | console.error('[react-router5][BaseLink] missing browser plugin, href might be build incorrectly'); 12 | }; 13 | 14 | this.isActive = this.isActive.bind(this); 15 | this.clickHandler = this.clickHandler.bind(this); 16 | 17 | this.state = { active: this.isActive() }; 18 | } 19 | 20 | buildUrl(routeName, routeParams) { 21 | if (this.router.buildUrl) { 22 | return this.router.buildUrl(routeName, routeParams); 23 | } 24 | 25 | return this.router.buildPath(routeName, routeParams); 26 | } 27 | 28 | isActive() { 29 | return this.router.isActive(this.props.routeName, this.props.routeParams, this.props.activeStrict); 30 | } 31 | 32 | clickHandler(evt) { 33 | if (this.props.onClick) { 34 | this.props.onClick(evt); 35 | 36 | if (evt.defaultPrevented) { 37 | return; 38 | } 39 | } 40 | 41 | const comboKey = evt.metaKey || evt.altKey || evt.ctrlKey || evt.shiftKey; 42 | 43 | if (evt.button === 0 && !comboKey) { 44 | evt.preventDefault(); 45 | this.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions); 46 | } 47 | } 48 | 49 | render() { 50 | const { 51 | routeName, 52 | routeParams, 53 | className, 54 | activeClassName, 55 | children, 56 | title, 57 | onMouseOver, 58 | } = this.props; 59 | 60 | const active = this.isActive(); 61 | const href = this.buildUrl(routeName, routeParams); 62 | const linkclassName = (className ? className.split(' ') : []) 63 | .concat(active ? [activeClassName] : []).join(' '); 64 | 65 | return React.createElement( 66 | 'a', 67 | { 68 | href, 69 | className: linkclassName, 70 | onClick: this.clickHandler, 71 | onMouseOver, 72 | title 73 | }, 74 | children 75 | ); 76 | } 77 | } 78 | 79 | BaseLink.contextTypes = { 80 | router: PropTypes.object.isRequired 81 | }; 82 | 83 | BaseLink.propTypes = { 84 | routeName: PropTypes.string.isRequired, 85 | routeParams: PropTypes.object, 86 | routeOptions: PropTypes.object, 87 | activeClassName: PropTypes.string, 88 | activeStrict: PropTypes.bool, 89 | onClick: PropTypes.func, 90 | onMouseOver: PropTypes.func 91 | }; 92 | 93 | BaseLink.defaultProps = { 94 | activeClassName: 'active', 95 | activeStrict: false, 96 | routeParams: {}, 97 | routeOptions: {} 98 | }; 99 | 100 | export default BaseLink; 101 | -------------------------------------------------------------------------------- /modules/RouterProvider.js: -------------------------------------------------------------------------------- 1 | import { Component, Children } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class RouterProvider extends Component { 5 | constructor(props, context) { 6 | super(props, context); 7 | this.router = props.router; 8 | } 9 | 10 | getChildContext() { 11 | return { router: this.router }; 12 | } 13 | 14 | componentWillReceiveProps(nextProps) { 15 | if (this.props.router !== nextProps.router) { 16 | console.error('[react-router5][RouterProvider] does not support changing the router object.'); 17 | } 18 | } 19 | 20 | render() { 21 | const { children } = this.props; 22 | return Children.only(children); 23 | } 24 | } 25 | 26 | RouterProvider.propTypes = { 27 | router: PropTypes.object.isRequired, 28 | children: PropTypes.element.isRequired 29 | }; 30 | 31 | RouterProvider.childContextTypes = { 32 | router: PropTypes.object.isRequired 33 | }; 34 | 35 | export default RouterProvider; 36 | -------------------------------------------------------------------------------- /modules/index.js: -------------------------------------------------------------------------------- 1 | import BaseLink from './BaseLink'; 2 | import routeNode from './routeNode'; 3 | import RouterProvider from './RouterProvider'; 4 | import withRoute from './withRoute'; 5 | 6 | const Link = withRoute(BaseLink); 7 | 8 | export { 9 | BaseLink, 10 | routeNode, 11 | RouterProvider, 12 | withRoute, 13 | Link 14 | }; 15 | -------------------------------------------------------------------------------- /modules/routeNode.js: -------------------------------------------------------------------------------- 1 | import { Component, createElement } from 'react'; 2 | import { getDisplayName, ifNot } from './utils'; 3 | import PropTypes from 'prop-types'; 4 | 5 | function routeNode(nodeName) { 6 | return function routeNodeWrapper(RouteSegment) { 7 | class RouteNode extends Component { 8 | constructor(props, context) { 9 | super(props, context); 10 | this.router = context.router; 11 | this.state = { 12 | previousRoute: null, 13 | route: this.router.getState() 14 | }; 15 | } 16 | 17 | componentDidMount() { 18 | ifNot( 19 | this.router.hasPlugin('LISTENERS_PLUGIN'), 20 | '[react-router5][routeNode] missing listeners plugin' 21 | ); 22 | 23 | this.nodeListener = (toState, fromState) => this.setState({ previousRoute: fromState, route: toState }); 24 | this.router.addNodeListener(nodeName, this.nodeListener); 25 | } 26 | 27 | componentWillUnmout() { 28 | this.router.removeNodeListener(nodeName, this.nodeListener); 29 | } 30 | 31 | render() { 32 | const { props, router } = this; 33 | const { previousRoute, route } = this.state; 34 | const component = createElement( 35 | RouteSegment, 36 | {...props, router, previousRoute, route } 37 | ); 38 | 39 | return component; 40 | } 41 | } 42 | 43 | RouteNode.contextTypes = { 44 | router: PropTypes.object.isRequired 45 | }; 46 | 47 | RouteNode.displayName = 'RouteNode[' + getDisplayName(RouteSegment) + ']'; 48 | 49 | return RouteNode; 50 | }; 51 | } 52 | 53 | export default routeNode; 54 | -------------------------------------------------------------------------------- /modules/utils.js: -------------------------------------------------------------------------------- 1 | export const getDisplayName = component => component.displayName || component.name || 'Component'; 2 | 3 | export const ifNot = (condition, errorMessage) => { 4 | if (!condition) throw new Error(errorMessage); 5 | }; 6 | -------------------------------------------------------------------------------- /modules/withRoute.js: -------------------------------------------------------------------------------- 1 | import { Component, createElement } from 'react'; 2 | import { ifNot, getDisplayName } from './utils'; 3 | import PropTypes from 'prop-types'; 4 | 5 | function withRoute(BaseComponent) { 6 | class ComponentWithRoute extends Component { 7 | constructor(props, context) { 8 | super(props, context); 9 | this.router = context.router; 10 | this.state = { 11 | previousRoute: null, 12 | route: this.router.getState() 13 | }; 14 | this.listener = this.listener.bind(this); 15 | } 16 | 17 | componentDidMount() { 18 | ifNot( 19 | this.router.hasPlugin('LISTENERS_PLUGIN'), 20 | '[react-router5][withRoute] missing listeners plugin' 21 | ); 22 | 23 | this.listener = (toState, fromState) => this.setState({ previousRoute: fromState, route: toState }); 24 | this.router.addListener(this.listener); 25 | } 26 | 27 | componentWillUnmount() { 28 | this.router.removeListener(this.listener); 29 | } 30 | 31 | listener(toState, fromState) { 32 | this.setState({ 33 | previousRoute: fromState, 34 | route: toState 35 | }); 36 | } 37 | 38 | render() { 39 | ifNot( 40 | !this.props.router && !this.props.route && !this.props.previousRoute, 41 | '[react-router5] prop names `router`, `route` and `previousRoute` are reserved.' 42 | ); 43 | 44 | return createElement(BaseComponent, { ...this.props, ...this.state, router: this.router }); 45 | } 46 | } 47 | 48 | ComponentWithRoute.contextTypes = { 49 | router: PropTypes.object.isRequired 50 | }; 51 | 52 | ComponentWithRoute.displayName = 'WithRoute[' + getDisplayName(BaseComponent) + ']'; 53 | 54 | return ComponentWithRoute; 55 | } 56 | 57 | export default withRoute; 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router5", 3 | "version": "4.3.0", 4 | "description": "router5 helpers for React", 5 | "main": "dist/commonjs/index.js", 6 | "jsnext:main": "dist/es/index.js", 7 | "scripts": { 8 | "clean": "rimraf dist", 9 | "build:cjs": "babel modules --out-dir dist/commonjs", 10 | "build:es": "BABEL_ENV=es babel modules --out-dir dist/es", 11 | "build:umd": "rollup -c rollup.config.js -f umd", 12 | "build": "npm run clean && npm run build:cjs && npm run build:es && npm run build:umd", 13 | "test": "mocha --compilers js:babel-core/register --recursive --require ./test/test-helper.js 'test/main.js'", 14 | "clog": "conventional-changelog -p angular -i CHANGELOG.md -s", 15 | "lint": "eslint modules", 16 | "release": "./scripts/release.js" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/router5/react-router5.git" 21 | }, 22 | "keywords": [ 23 | "router", 24 | "html5", 25 | "history", 26 | "tree", 27 | "react", 28 | "functional" 29 | ], 30 | "author": "Thomas Roch", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/router5/react-router5/issues" 34 | }, 35 | "homepage": "http://router5.github.com/router5/react-router5", 36 | "devDependencies": { 37 | "babel-cli": "~6.24.1", 38 | "babel-core": "~6.24.1", 39 | "babel-eslint": "~7.2.3", 40 | "babel-plugin-transform-export-extensions": "~6.22.0", 41 | "babel-plugin-transform-object-rest-spread": "~6.23.0", 42 | "babel-preset-es2015": "~6.24.1", 43 | "babel-preset-es2015-rollup": "~3.0.0", 44 | "babel-preset-react": "~6.24.1", 45 | "chai": "~3.5.0", 46 | "chai-enzyme": "~0.6.1", 47 | "cheerio": "~0.22.0", 48 | "enzyme": "~2.8.2", 49 | "eslint": "~3.19.0", 50 | "jsdom": "~10.1.0", 51 | "mocha": "~3.4.1", 52 | "react": "~15.5.4", 53 | "react-dom": "~15.5.4", 54 | "react-test-renderer": "~15.5.4", 55 | "rimraf": "~2.6.1", 56 | "rollup": "~0.41.6", 57 | "rollup-plugin-babel": "~2.7.1", 58 | "rollup-plugin-commonjs": "~8.0.2", 59 | "rollup-plugin-node-resolve": "~3.0.0", 60 | "router5": "~4.5.2", 61 | "sinon": "~2.2.0", 62 | "sinon-chai": "~2.10.0", 63 | "yargs": "~8.0.1" 64 | }, 65 | "peerDependencies": { 66 | "react": "^0.14.0 || ^15.0.0", 67 | "router5": "^4.5.2" 68 | }, 69 | "dependencies": { 70 | "prop-types": "~15.5.10" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | import nodeResolve from 'rollup-plugin-node-resolve'; 3 | import common from 'rollup-plugin-commonjs'; 4 | 5 | const babelOptions = { 6 | presets: [ 'es2015-rollup' ], 7 | plugins: [ 8 | 'transform-object-rest-spread', 9 | 'transform-export-extensions' 10 | ], 11 | babelrc: false 12 | }; 13 | 14 | export default { 15 | entry: 'modules/index.js', 16 | format: 'umd', 17 | external: [ 'react' ], 18 | plugins: [ common({ include: 'node_modules/**' }), babel(babelOptions), nodeResolve({ jsnext: true }) ], 19 | moduleName: 'reactRouter5', 20 | moduleId: 'reactRouter5', 21 | dest: 'dist/umd/react-router5.js' 22 | }; 23 | -------------------------------------------------------------------------------- /scripts/release.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var exec = require('child_process').execSync; 4 | var argv = require('yargs').argv; 5 | var fs = require('fs'); 6 | var path = require('path'); 7 | 8 | var versionType = argv.major ? 'major' : (argv.minor ? 'minor' : 'patch'); 9 | 10 | run('npm install'); 11 | run('npm prune'); 12 | var VERSION = run('npm --no-git-tag-version version ' + versionType, false); 13 | 14 | run('npm run lint'); 15 | run('npm run build'); 16 | run('npm test'); 17 | run('npm run clog'); 18 | 19 | run('git add -A'); 20 | run('git add dist -f'); 21 | run('git commit -m "chore: ' + VERSION + '"'); 22 | run('git tag ' + VERSION); 23 | run('git push origin master'); 24 | run('git push --tags'); 25 | 26 | run('npm publish'); 27 | 28 | function run(cmd, log) { 29 | log = log === undefined ? true : log; 30 | var res = exec(cmd).toString(); 31 | if (log && res) console.log(res); 32 | return res; 33 | } 34 | -------------------------------------------------------------------------------- /test/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { expect } from 'chai'; 3 | import { Child, createTestRouter, FnChild, renderWithRouter } from './utils'; 4 | import { RouterProvider, withRoute, routeNode, BaseLink } from '../modules'; 5 | import { findRenderedComponentWithType } from 'react-dom/test-utils'; 6 | import { spy } from 'sinon'; 7 | import listenersPlugin from 'router5/plugins/listeners'; 8 | import { mount } from 'enzyme'; 9 | 10 | describe('RouterProvider component', () => { 11 | it('should add the store to the child context', () => { 12 | const router = createTestRouter(); 13 | const tree = renderWithRouter(router)(Child); 14 | 15 | const child = findRenderedComponentWithType(tree, Child); 16 | expect(child.context.router).to.equal(router); 17 | }); 18 | }); 19 | 20 | describe('withRoute hoc', () => { 21 | let router; 22 | 23 | before(() => { 24 | router = createTestRouter(); 25 | }); 26 | 27 | it('should throw an error if router5-plugin-listeners plugin is not used', () => { 28 | const renderTree = () => renderWithRouter(router)(withRoute(() =>
)); 29 | expect(renderTree).to.throw('[react-router5][withRoute] missing listeners plugin'); 30 | }); 31 | 32 | it('should inject the router in the wrapped component props', () => { 33 | const ChildSpy = spy(FnChild); 34 | router.usePlugin(listenersPlugin()); 35 | 36 | const tree = renderWithRouter(router)(withRoute(ChildSpy)); 37 | expect(ChildSpy).to.have.been.calledWith({ router, route: null, previousRoute: null }); 38 | }); 39 | }); 40 | 41 | describe('routeNode hoc', () => { 42 | let router; 43 | 44 | before(() => { 45 | router = createTestRouter(); 46 | }); 47 | 48 | it('should throw an error if router5-plugin-listeners plugin is not used', () => { 49 | const renderTree = () => renderWithRouter(router)(routeNode('')(Child)); 50 | expect(renderTree).to.throw('[react-router5][routeNode] missing listeners plugin'); 51 | }); 52 | 53 | it('should inject the router in the wrapped component props', () => { 54 | const ChildSpy = spy(FnChild); 55 | router.usePlugin(listenersPlugin()); 56 | const tree = renderWithRouter(router)(withRoute(ChildSpy)); 57 | expect(ChildSpy).to.have.been.calledWith({ router, route: null, previousRoute: null }); 58 | }); 59 | }); 60 | 61 | describe('BaseLink component', () => { 62 | let router; 63 | 64 | before(() => { 65 | router = createTestRouter(); 66 | }); 67 | 68 | it('should render an hyperlink element', () => { 69 | router.addNode('home', '/home'); 70 | const output = mount(); 71 | expect(output.find('a')).to.have.attr('href', '/home') 72 | expect(output.find('a')).not.to.have.className('active'); 73 | }); 74 | 75 | it('should have an active class if associated route is active', () => { 76 | router.setOption('defaultRoute', 'home'); 77 | router.start(); 78 | const output = mount(); 79 | expect(output.find('a')).to.have.className('active'); 80 | }); 81 | }); 82 | -------------------------------------------------------------------------------- /test/test-helper.js: -------------------------------------------------------------------------------- 1 | import { JSDOM } from 'jsdom'; 2 | import chai from 'chai'; 3 | import sinonChai from 'sinon-chai'; 4 | import chaiEnzyme from 'chai-enzyme'; 5 | 6 | chai.use(sinonChai); 7 | chai.use(chaiEnzyme()); 8 | 9 | const { window } = new JSDOM('', { 10 | url: 'http://localhost' 11 | }); 12 | 13 | global.document = window.document; 14 | global.window = window; 15 | global.navigator = window.navigator; 16 | -------------------------------------------------------------------------------- /test/utils.js: -------------------------------------------------------------------------------- 1 | import createRouter from 'router5'; 2 | import React, { Component } from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import { RouterProvider } from '../modules'; 5 | import { renderIntoDocument } from 'react-dom/test-utils'; 6 | import browserPlugin from 'router5/plugins/browser'; 7 | 8 | export class Child extends Component { 9 | render() { 10 | return
; 11 | } 12 | } 13 | 14 | Child.contextTypes = { 15 | router: PropTypes.object.isRequired 16 | }; 17 | 18 | export const FnChild = (props) =>
; 19 | 20 | export const createTestRouter = () => createRouter().usePlugin(browserPlugin()); 21 | 22 | export const renderWithRouter = router => BaseComponent => renderIntoDocument( 23 | 24 | 25 | 26 | ); 27 | --------------------------------------------------------------------------------