Permalink
Please sign in to comment.
Showing
with
639 additions
and 1,805 deletions.
- +0 −4 .eslintignore
- +2 −36 .eslintrc
- +4 −4 CONTRIBUTING.md
- +13 −107 README.md
- BIN assets/thumbnail.png
- +11 −9 karma.conf.js
- +41 −39 package.json
- +0 −70 scripts/bower-prepare.js
- +0 −20 src/ButtonLink.js
- +11 −0 src/IndexLinkContainer.js
- +53 −0 src/LinkContainer.js
- +0 −83 src/LinkMixin.js
- +0 −20 src/ListGroupItemLink.js
- +0 −23 src/MenuItemLink.js
- +0 −20 src/NavItemLink.js
- +0 −20 src/PageItemLink.js
- +0 −7 src/RouterOverlayTrigger.js
- +0 −20 src/ThumbnailLink.js
- +2 −7 src/index.js
- +2 −8 tests/.eslintrc
- +0 −166 tests/ButtonLink.spec.js
- +56 −0 tests/IndexLinkContainer.spec.js
- +223 −0 tests/LinkContainer.spec.js
- +0 −164 tests/ListGroupItemLink.spec.js
- +0 −168 tests/MenuItemLink.spec.js
- +0 −190 tests/NavItemLink.spec.js
- +0 −103 tests/PageItemLink.spec.js
- +0 −13 tests/RouterOverlayTrigger.spec.js
- +0 −31 tests/TestHandlers.js
- +0 −103 tests/ThumbnailLink.spec.js
- +0 −21 tests/bower-imports-module.spec.js
- +3 −18 tests/index.js
- +0 −31 tests/phantom-shims.js
- +0 −2 tests/visual.js
- +40 −31 tests/visual/ButtonVisual.js
- +72 −36 tests/visual/ListGroupItemVisual.js
- +0 −42 tests/visual/MenuItemVisual.js
- +28 −28 tests/visual/NavItemVisual.js
- +0 −28 tests/visual/PageItemVisual.js
- +0 −21 tests/visual/ThumbnailVisual.js
- +0 −29 tests/visual/app.js
- +10 −19 tests/visual/home.js
- +35 −0 tests/visual/index.js
- +11 −39 webpack.config.babel.js
- +5 −18 webpack.test.config.babel.js
- +17 −0 webpack.visual.config.babel.js
- +0 −7 webpack/bower-imports-loader.js
4
.eslintignore
@@ -1,4 +0,0 @@ | ||
-node_modules/ | ||
-lib/ | ||
-amd/ | ||
-karma.conf.js |
38
.eslintrc
@@ -1,41 +1,7 @@ | ||
{ | ||
- "extends": ["eslint-config-airbnb"], | ||
- "env": { | ||
- "browser": true, | ||
- "node": true | ||
- }, | ||
- "ecmaFeatures": { | ||
- "jsx": true | ||
- }, | ||
- "parser": "babel-eslint", | ||
- "plugins": [ | ||
- "react", | ||
- "babel" | ||
- ], | ||
+ "extends": "airbnb", | ||
"rules": { | ||
"comma-dangle": 0, | ||
- "comma-spacing": 1, | ||
- "key-spacing": 0, | ||
- "no-eq-null": 0, | ||
- "no-param-reassign": 0, | ||
- "no-underscore-dangle": 0, | ||
- "no-undef": 2, | ||
- "no-unused-vars": [2, { "vars": "all", "args": "none" }], | ||
- "no-var": 2, | ||
- "babel/object-shorthand": 2, | ||
- "quotes": [1, "single", "avoid-escape"], | ||
- "react/display-name": 0, | ||
- "react/jsx-no-undef": 2, | ||
- "react/jsx-quotes": 0, | ||
- "react/jsx-uses-react": 2, | ||
- "react/no-did-mount-set-state": 2, | ||
- "react/no-did-update-set-state": 2, | ||
- "react/no-multi-comp": 2, | ||
- "react/prop-types": [1, { "ignore": ["children", "className"] }], | ||
- "react/react-in-jsx-scope": 2, | ||
- "react/self-closing-comp": 1, | ||
- "react/wrap-multilines": 2, | ||
- "react/jsx-uses-vars": 1, | ||
- "strict": 0 | ||
+ "no-eq-null": 0 | ||
} | ||
} |
8
CONTRIBUTING.md
@@ -1,7 +1,7 @@ | ||
# Contributing | ||
-As part of the react-bootstrap organization all contributing guidelines can be | ||
-found at: | ||
-https://github.com/react-bootstrap/react-bootstrap/blob/master/CONTRIBUTING.md | ||
+As part of the react-bootstrap organization all contributing guidelines can be found at: https://github.com/react-bootstrap/react-bootstrap/blob/master/CONTRIBUTING.md. | ||
-Note that automated changelog generation has not been setup on this repo yet. | ||
+Use `npm run visual-test` to check the appearance of components in your browser. The page will load at [http://localhost:8080/](http://localhost:8080/). | ||
+ | ||
+Note that automated changelog generation has not been set up on this repo yet. |
120
README.md
@@ -1,127 +1,33 @@ | ||
# react-router-bootstrap | ||
+Integration between [React Router](https://github.com/rackt/react-router) and [React-Bootstrap](https://github.com/react-bootstrap/react-bootstrap). | ||
[![Build Status](https://travis-ci.org/react-bootstrap/react-router-bootstrap.svg?branch=master)](https://travis-ci.org/react-bootstrap/react-router-bootstrap) | ||
+[![npm version](https://badge.fury.io/js/react-router-bootstrap.svg)](http://badge.fury.io/js/react-router-bootstrap) | ||
-Intregation between [react-router](https://github.com/rackt/react-router) and [react-bootstrap](https://github.com/react-bootstrap/react-bootstrap) | ||
- | ||
-This package gives you react-router compatible substitutes for: | ||
- | ||
-- `NavItem` -> `NavItemLink` | ||
-- `Button` -> `ButtonLink` | ||
-- `MenuItem` -> `MenuItemLink` | ||
-- `ListGroupItem` -> `ListGroupItemLink` | ||
-- `PageItem` -> `PageItemLink` | ||
-- `Thumbnail` -> `ThumbnailLink` | ||
- | ||
-Turning this: | ||
+## Usage | ||
-```jsx | ||
-React.createClass({ | ||
- mixins: [State, Navigation], | ||
+Wrap your React-Bootstrap element in a `LinkContainer` to make it behave like a React Router `Link`: | ||
- render: function() { | ||
- var href = this.makeHref('destination', {some: 'params'}, {some: 'query param'}); | ||
- var isActive = this.isActive('destination', {some: 'params'}, {some: 'query param'}); | ||
- return <Button href={href} active={isActive}>; | ||
- } | ||
-}); | ||
+```js | ||
+<LinkContainer to="/foo" query={{bar: "baz"}}> | ||
+ <Button>Foo</Button> | ||
+</LinkContainer> | ||
``` | ||
-Into this | ||
- | ||
-```jsx | ||
-React.createClass({ | ||
- render: function() { | ||
- return <ButtonLink to="destination" params={{ some: 'params' }} query={{some: 'query param'}}>; | ||
- } | ||
-}); | ||
-``` | ||
+To disable the element and the link, set the `disabled` prop on the `LinkContainer`. For the equivalent of `IndexLink`, use `IndexLinkContainer`. | ||
## Installation | ||
``` | ||
-npm install --save react-router-bootstrap | ||
+npm install react-router-bootstrap | ||
``` | ||
-You will also (if you haven't already) want to install `react-router` and `react-bootstrap` | ||
+You will also want to have React Router and React-Bootstrap. | ||
``` | ||
-npm install --save react-router react-bootstrap | ||
-``` | ||
- | ||
-## Usage | ||
- | ||
-A simple example | ||
- | ||
-```jsx | ||
-var Router = require('react-router') | ||
- , RouteHandler = Router.RouteHandler | ||
- , Route = Router.Route; | ||
- | ||
-var ReactBootstrap = require('react-bootstrap') | ||
- , Nav = ReactBootstrap.Nav | ||
- , ListGroup = ReactBootstrap.ListGroup; | ||
- | ||
-var ReactRouterBootstrap = require('react-router-bootstrap') | ||
- , NavItemLink = ReactRouterBootstrap.NavItemLink | ||
- , ButtonLink = ReactRouterBootstrap.ButtonLink | ||
- , ListGroupItemLink = ReactRouterBootstrap.ListGroupItemLink; | ||
- | ||
-var App = React.createClass({ | ||
- render: function() { | ||
- return ( | ||
- <div> | ||
- NavItemLink<br /> | ||
- <Nav> | ||
- <NavItemLink | ||
- to="destination" | ||
- params={{ someparam: 'hello' }}> | ||
- Linky! | ||
- </NavItemLink> | ||
- </Nav> | ||
- <br /> | ||
- ButtonLink<br /> | ||
- <ButtonLink | ||
- to="destination" | ||
- params={{ someparam: 'hello' }}> | ||
- Linky! | ||
- </ButtonLink> | ||
- <br /> | ||
- <ListGroup> | ||
- <ListGroupItemLink | ||
- to="destination" | ||
- params={{ someparam: 'hello' }}> | ||
- Linky! | ||
- </ListGroupItemLink> | ||
- </ListGroup> | ||
- <RouteHandler /> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-var Destination = React.createClass({ | ||
- render: function() { | ||
- return <div>You made it!</div>; | ||
- } | ||
-}); | ||
- | ||
-var routes = ( | ||
- <Route handler={App} path="/"> | ||
- <Route name="destination" path="destination/:someparam" handler={Destination} /> | ||
- </Route> | ||
-); | ||
- | ||
-Router.run(routes, function (Handler) { | ||
- React.render(<Handler/>, document.body); | ||
-}); | ||
- | ||
+npm install react-router react-bootstrap | ||
``` | ||
## Contributing | ||
-See [CONTRIBUTING](CONTRIBUTING.md) | ||
- | ||
-Use `npm run visual-test` command to check components appearance in browser. It will open browser with a blank page. Then after `webpack-server` finishes its bundling, the browser automatically will refresh the page. | ||
- | ||
-URL for it: http://localhost:8080/public/visual#/ | ||
+See [CONTRIBUTING](CONTRIBUTING.md). |
BIN
assets/thumbnail.png
Deleted file not rendered
20
karma.conf.js
80
package.json
70
scripts/bower-prepare.js
@@ -1,70 +0,0 @@ | ||
-/* globals cat, config, cp, mkdir, rm, test */ | ||
-/* eslint curly: 0, no-console: 0 */ | ||
-import 'colors'; | ||
-import 'shelljs/global'; | ||
-import path from 'path'; | ||
-import _ from 'lodash'; | ||
-import yargs from 'yargs'; | ||
- | ||
-// do not die on errors | ||
-config.fatal = false; | ||
- | ||
-//------------------------------------------------------------------------------ | ||
-// constants | ||
-const repoRoot = path.resolve(__dirname, '../'); | ||
-const libFolder = path.join(repoRoot, 'lib'); | ||
-const bowerRoot = path.join(repoRoot, 'amd'); | ||
-const bowerTemplate = path.join(repoRoot, 'bower.template.json'); | ||
-const license = path.join(repoRoot, 'LICENSE'); | ||
- | ||
- | ||
-//------------------------------------------------------------------------------ | ||
-// command line options | ||
-const argv = yargs | ||
- .usage('Usage: $0 [--verbose]') | ||
- .example('$0', 'Prepare bower package for releasing') | ||
- .option('verbose', { | ||
- demand: false, | ||
- default: false, | ||
- describe: 'Increased debug output' | ||
- }) | ||
- .argv; | ||
- | ||
-if (argv.dryRun) console.log('DRY RUN'.magenta); | ||
- | ||
-config.silent = !argv.verbose; | ||
- | ||
- | ||
-//------------------------------------------------------------------------------ | ||
-// functions | ||
-function bower() { | ||
- console.log('Creating: '.cyan + 'bower package'.green); | ||
- | ||
- rm('-rf', bowerRoot); | ||
- mkdir('-p', bowerRoot); | ||
- | ||
- // generate bower.json from template | ||
- const pkg = JSON.parse(cat(path.join(repoRoot, 'package.json'))); | ||
- const template = _.template(cat(bowerTemplate)); | ||
- const bowerConfigObject = template({ pkg }); | ||
- const json = JSON.stringify(JSON.parse(bowerConfigObject), null, 2); // proper formatting hack | ||
- json.to(path.join(bowerRoot, 'bower.json')); | ||
- | ||
- // copy readme and license | ||
- const readmeBower = path.join(repoRoot, 'README.bower.md'); | ||
- const readme = path.join(repoRoot, 'README.md'); | ||
- if (test('-e', readmeBower)) { | ||
- cp(readmeBower, path.join(bowerRoot, 'README.md')); | ||
- } else { | ||
- cp(readme, bowerRoot); | ||
- } | ||
- if (test('-e', license)) cp(license, bowerRoot); | ||
- | ||
- // copy distr files | ||
- cp('-r', libFolder, bowerRoot); | ||
- | ||
- console.log('Created: '.cyan + 'bower package'.green); | ||
-} | ||
- | ||
-//------------------------------------------------------------------------------ | ||
-bower(); |
20
src/ButtonLink.js
@@ -1,20 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import Button from 'react-bootstrap/lib/Button'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const ButtonLink = React.createClass({ | ||
- mixins: [ | ||
- LinkMixin | ||
- ], | ||
- | ||
- render() { | ||
- return ( | ||
- <Button {...this.getLinkProps()} ref='button'> | ||
- {this.props.children} | ||
- </Button> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default ButtonLink; |
11
src/IndexLinkContainer.js
@@ -0,0 +1,11 @@ | ||
+import React from 'react'; | ||
+ | ||
+import LinkContainer from './LinkContainer'; | ||
+ | ||
+export default class IndexLinkContainer extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer {...this.props} onlyActiveOnIndex /> | ||
+ ); | ||
+ } | ||
+} |
53
src/LinkContainer.js
@@ -0,0 +1,53 @@ | ||
+// This is largely taken from react-router/lib/Link. | ||
+ | ||
+import React from 'react'; | ||
+import {Link} from 'react-router'; | ||
+ | ||
+export default class LinkContainer extends React.Component { | ||
+ constructor(props, context) { | ||
+ super(props, context); | ||
+ | ||
+ this.onClick = this.onClick.bind(this); | ||
+ } | ||
+ | ||
+ onClick(event) { | ||
+ if (this.props.disabled) { | ||
+ event.preventDefault(); | ||
+ return; | ||
+ } | ||
+ | ||
+ Link.prototype.handleClick.call(this, event); | ||
+ } | ||
+ | ||
+ render() { | ||
+ const {history} = this.context; | ||
+ const {onlyActiveOnIndex, to, query, children, ...props} = this.props; | ||
+ | ||
+ delete props.state; | ||
+ delete props.onClick; | ||
+ props.onClick = this.onClick; | ||
+ props.href = history.createHref(to, query); | ||
+ props.active = history.isActive(to, query, onlyActiveOnIndex); | ||
+ | ||
+ return React.cloneElement(React.Children.only(children), props); | ||
+ } | ||
+} | ||
+ | ||
+LinkContainer.propTypes = { | ||
+ onlyActiveOnIndex: React.PropTypes.bool.isRequired, | ||
+ to: React.PropTypes.string.isRequired, | ||
+ query: React.PropTypes.object, | ||
+ state: React.PropTypes.object, | ||
+ onClick: React.PropTypes.func, | ||
+ disabled: React.PropTypes.bool.isRequired, | ||
+ children: React.PropTypes.node.isRequired | ||
+}; | ||
+ | ||
+LinkContainer.contextTypes = { | ||
+ history: React.PropTypes.object.isRequired | ||
+}; | ||
+ | ||
+LinkContainer.defaultProps = { | ||
+ onlyActiveOnIndex: false, | ||
+ disabled: false | ||
+}; |
83
src/LinkMixin.js
@@ -1,83 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-function isLeftClickEvent(event) { | ||
- return event.button === 0; | ||
-} | ||
- | ||
-function isModifiedEvent(event) { | ||
- return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); | ||
-} | ||
- | ||
-export default { | ||
- propTypes: { | ||
- active: React.PropTypes.bool, | ||
- activeClassName: React.PropTypes.string.isRequired, | ||
- disabled: React.PropTypes.bool, | ||
- to: React.PropTypes.string.isRequired, | ||
- params: React.PropTypes.object, | ||
- query: React.PropTypes.object, | ||
- onClick: React.PropTypes.func | ||
- }, | ||
- contextTypes: { | ||
- router: React.PropTypes.func.isRequired | ||
- }, | ||
- | ||
- getDefaultProps() { | ||
- return { | ||
- activeClassName: 'active' | ||
- }; | ||
- }, | ||
- | ||
- /** | ||
- * Returns props except those used by this Mixin | ||
- * Gets "active" from router if needed. | ||
- * Gets the value of the "href" attribute to use on the DOM element. | ||
- * Sets "onClick" to "handleRouteTo". | ||
- */ | ||
- getLinkProps() { | ||
- const { | ||
- to, | ||
- params, | ||
- query, | ||
- ...props | ||
- } = this.props; | ||
- | ||
- if (this.props.active === undefined) { | ||
- props.active = this.context.router.isActive(to, params, query); | ||
- } | ||
- | ||
- props.href = this.context.router.makeHref(to, params, query); | ||
- | ||
- props.onClick = this.handleRouteTo; | ||
- | ||
- return props; | ||
- }, | ||
- | ||
- handleRouteTo(event) { | ||
- let allowTransition = true; | ||
- let clickResult; | ||
- | ||
- if (this.props.disabled) { | ||
- event.preventDefault(); | ||
- return; | ||
- } | ||
- | ||
- if (this.props.onClick) { | ||
- clickResult = this.props.onClick(event); | ||
- } | ||
- | ||
- if (isModifiedEvent(event) || !isLeftClickEvent(event)) { | ||
- return; | ||
- } | ||
- | ||
- if (clickResult === false || event.defaultPrevented === true) { | ||
- allowTransition = false; | ||
- } | ||
- | ||
- event.preventDefault(); | ||
- | ||
- if (allowTransition) { | ||
- this.context.router.transitionTo(this.props.to, this.props.params, this.props.query); | ||
- } | ||
- } | ||
-}; |
20
src/ListGroupItemLink.js
@@ -1,20 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import ListGroupItem from 'react-bootstrap/lib/ListGroupItem'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const LinkGroupItemLink = React.createClass({ | ||
- mixins: [ | ||
- LinkMixin | ||
- ], | ||
- | ||
- render() { | ||
- return ( | ||
- <ListGroupItem {...this.getLinkProps()} ref='listGroupItem'> | ||
- {this.props.children} | ||
- </ListGroupItem> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default LinkGroupItemLink; |
23
src/MenuItemLink.js
@@ -1,23 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import MenuItem from 'react-bootstrap/lib/MenuItem'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const MenuItemLink = React.createClass({ | ||
- mixins: [ | ||
- LinkMixin | ||
- ], | ||
- | ||
- render() { | ||
- const props = this.getLinkProps(); | ||
- delete props.onSelect; // this is done on the copy of this.props | ||
- | ||
- return ( | ||
- <MenuItem {...props} ref="menuItem"> | ||
- {this.props.children} | ||
- </MenuItem> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default MenuItemLink; |
20
src/NavItemLink.js
@@ -1,20 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import NavItem from 'react-bootstrap/lib/NavItem'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const NavItemLink = React.createClass({ | ||
- mixins: [ | ||
- LinkMixin | ||
- ], | ||
- | ||
- render() { | ||
- return ( | ||
- <NavItem {...this.getLinkProps()} ref="navItem"> | ||
- {this.props.children} | ||
- </NavItem> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default NavItemLink; |
20
src/PageItemLink.js
@@ -1,20 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import PageItem from 'react-bootstrap/lib/PageItem'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const PageItemLink = React.createClass({ | ||
- mixins: [ | ||
- LinkMixin | ||
- ], | ||
- | ||
- render() { | ||
- return ( | ||
- <PageItem {...this.getLinkProps()} ref='pageItem'> | ||
- {this.props.children} | ||
- </PageItem> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default PageItemLink; |
7
src/RouterOverlayTrigger.js
@@ -1,7 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; | ||
- | ||
-export default OverlayTrigger.withContext({ | ||
- router: React.PropTypes.func | ||
-}); |
20
src/ThumbnailLink.js
@@ -1,20 +0,0 @@ | ||
-import React from 'react'; | ||
- | ||
-import Thumbnail from 'react-bootstrap/lib/Thumbnail'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const ThumbnailLink = React.createClass({ | ||
- mixins: [ | ||
- LinkMixin | ||
- ], | ||
- | ||
- render() { | ||
- return ( | ||
- <Thumbnail {...this.getLinkProps()} ref='thumbnail'> | ||
- {this.props.children} | ||
- </Thumbnail> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default ThumbnailLink; |
9
src/index.js
@@ -1,7 +1,2 @@ | ||
-export ButtonLink from './ButtonLink'; | ||
-export ListGroupItemLink from './ListGroupItemLink'; | ||
-export MenuItemLink from './MenuItemLink'; | ||
-export NavItemLink from './NavItemLink'; | ||
-export PageItemLink from './PageItemLink'; | ||
-export RouterOverlayTrigger from './RouterOverlayTrigger'; | ||
-export ThumbnailLink from './ThumbnailLink'; | ||
+export IndexLinkContainer from './IndexLinkContainer'; | ||
+export LinkContainer from './LinkContainer'; |
10
tests/.eslintrc
166
tests/ButtonLink.spec.js
@@ -1,166 +0,0 @@ | ||
-/* globals describe, it, assert, expect */ | ||
- | ||
-import React from 'react/addons'; | ||
-import ButtonLink from '../src/ButtonLink'; | ||
-import Router, { Route, RouteHandler } from 'react-router'; | ||
-import { Foo, Bar } from './TestHandlers'; | ||
-import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
-const { click } = React.addons.TestUtils.Simulate; | ||
- | ||
-describe('A ButtonLink', function() { | ||
- describe('with params and a query', function() { | ||
- it('knows how to make its href', function() { | ||
- const ButtonLinkHandler = React.createClass({ | ||
- render() { | ||
- return <ButtonLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>ButtonLink</ButtonLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
- <Route name="link" handler={ButtonLinkHandler} /> | ||
- ]; | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when its route is active', function() { | ||
- it('has an active class name', function(done) { | ||
- const ButtonLinkHandler = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <ButtonLink | ||
- to='foo' | ||
- className='dontKillMe' | ||
- bsStyle='primary' | ||
- bsSize='small' | ||
- >ButtonLink</ButtonLink> | ||
- <RouteHandler/> | ||
- </div> | ||
- ); | ||
- } | ||
- }); | ||
- | ||
- const routes = ( | ||
- <Route path="/" handler={ButtonLinkHandler}> | ||
- <Route name="foo" handler={Foo} /> | ||
- <Route name="bar" handler={Bar} /> | ||
- </Route> | ||
- ); | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/foo']; | ||
- const steps = []; | ||
- | ||
- function assertActive() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.className.split(' ').sort().join(' ')).to.equal('active btn btn-primary btn-sm dontKillMe'); | ||
- } | ||
- | ||
- function assertInactive() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.className.split(' ').sort().join(' ')).to.equal('btn btn-primary btn-sm dontKillMe'); | ||
- } | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- testLocation.push('/bar'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertInactive(); | ||
- testLocation.push('/foo'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, () => { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when clicked', function() { | ||
- it('calls a user defined click handler', function(done) { | ||
- const ButtonLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- assert.ok(true); | ||
- done(); | ||
- }, | ||
- | ||
- render() { | ||
- return <ButtonLink to="foo" onClick={this.handleClick}>ButtonLink</ButtonLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={ButtonLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('transitions to the correct route', function(done) { | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- const ButtonLinkHandler = React.createClass({ | ||
- handleClick() { | ||
- // just here to make sure click handlers don't prevent it from happening | ||
- }, | ||
- | ||
- render() { | ||
- return <ButtonLink to="foo" onClick={this.handleClick}>ButtonLink</ButtonLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={ButtonLinkHandler} /> | ||
- ]; | ||
- | ||
- const steps = []; | ||
- | ||
- steps.push(function() { | ||
- click(div.querySelector('a'), {button: 0}); | ||
- }); | ||
- | ||
- steps.push(function() { | ||
- expect(div.innerHTML).to.match(/Foo/); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
-}); |
56
tests/IndexLinkContainer.spec.js
@@ -0,0 +1,56 @@ | ||
+import createMemoryHistory from 'history/lib/createMemoryHistory'; | ||
+import React from 'react'; | ||
+import ReactTestUtils from 'react/lib/ReactTestUtils'; | ||
+import * as ReactBootstrap from 'react-bootstrap'; | ||
+import ReactDOM from 'react-dom'; | ||
+import {IndexRoute, Route, Router} from 'react-router'; | ||
+ | ||
+import IndexLinkContainer from '../src/IndexLinkContainer'; | ||
+ | ||
+describe('IndexLinkContainer', () => { | ||
+ [ | ||
+ 'Button', | ||
+ 'NavItem', | ||
+ 'ListGroupItem' | ||
+ ].forEach(name => { | ||
+ describe(name, () => { | ||
+ const Component = ReactBootstrap[name]; | ||
+ | ||
+ describe('active state', () => { | ||
+ function renderComponent(location) { | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <IndexLinkContainer to="/"> | ||
+ <Component>Root</Component> | ||
+ </IndexLinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ const router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory(location)}> | ||
+ <Route path="/" component={LinkWrapper}> | ||
+ <IndexRoute /> | ||
+ <Route path="foo" /> | ||
+ </Route> | ||
+ </Router> | ||
+ ); | ||
+ | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ return ReactDOM.findDOMNode(component); | ||
+ } | ||
+ | ||
+ it('should be active on the index route', () => { | ||
+ expect(renderComponent('/').className).to.match(/\bactive\b/); | ||
+ }); | ||
+ | ||
+ it('should not be active on a child route', () => { | ||
+ expect(renderComponent('/foo').className).to.not.match(/\bactive\b/); | ||
+ }); | ||
+ }); | ||
+ }); | ||
+ }); | ||
+}); |
223
tests/LinkContainer.spec.js
@@ -0,0 +1,223 @@ | ||
+import createMemoryHistory from 'history/lib/createMemoryHistory'; | ||
+import React from 'react'; | ||
+import ReactTestUtils from 'react/lib/ReactTestUtils'; | ||
+import * as ReactBootstrap from 'react-bootstrap'; | ||
+import ReactDOM from 'react-dom'; | ||
+import {Route, Router} from 'react-router'; | ||
+ | ||
+import LinkContainer from '../src/LinkContainer'; | ||
+ | ||
+describe('LinkContainer', () => { | ||
+ ['Button', | ||
+ 'NavItem', | ||
+ 'ListGroupItem' | ||
+ ].forEach(name => { | ||
+ describe(name, () => { | ||
+ const Component = ReactBootstrap[name]; | ||
+ | ||
+ it('should make the correct href', () => { | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer to="/foo" query={{bar: 'baz'}}> | ||
+ <Component>Foo</Component> | ||
+ </LinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ const router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory('/')}> | ||
+ <Route path="/" component={LinkWrapper} /> | ||
+ </Router> | ||
+ ); | ||
+ | ||
+ const anchor = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
+ router, 'A' | ||
+ ); | ||
+ expect(anchor.getAttribute('href')).to.equal('/foo?bar=baz'); | ||
+ }); | ||
+ | ||
+ it('should not add extra DOM nodes', () => { | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer to="/foo" query={{bar: 'baz'}}> | ||
+ <Component>Foo</Component> | ||
+ </LinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ const router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory('/')}> | ||
+ <Route path="/" component={LinkWrapper} /> | ||
+ </Router> | ||
+ ); | ||
+ | ||
+ const container = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, LinkContainer | ||
+ ); | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ | ||
+ expect(ReactDOM.findDOMNode(container)) | ||
+ .to.equal(ReactDOM.findDOMNode(component)); | ||
+ }); | ||
+ | ||
+ describe('when clicked', () => { | ||
+ it('should transition to the correct route', () => { | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer to="/target"> | ||
+ <Component>Target</Component> | ||
+ </LinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ class Target extends React.Component { | ||
+ render() { | ||
+ return <div className="target" />; | ||
+ } | ||
+ } | ||
+ | ||
+ const router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory('/')}> | ||
+ <Route path="/" component={LinkWrapper} /> | ||
+ <Route path="/target" component={Target} /> | ||
+ </Router> | ||
+ ); | ||
+ | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(component), | ||
+ {button: 0} | ||
+ ); | ||
+ | ||
+ const target = ReactTestUtils.findRenderedDOMComponentWithClass( | ||
+ router, 'target' | ||
+ ); | ||
+ expect(target).to.exist; | ||
+ }); | ||
+ | ||
+ it('should call a user defined click handler', () => { | ||
+ const onClick = sinon.spy(); | ||
+ | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer to="/foo" onClick={onClick}> | ||
+ <Component>Foo</Component> | ||
+ </LinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ const router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory('/')}> | ||
+ <Route path="/" component={LinkWrapper} /> | ||
+ </Router> | ||
+ ); | ||
+ | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(component)); | ||
+ | ||
+ expect(onClick).to.have.been.called; | ||
+ }); | ||
+ }); | ||
+ | ||
+ describe('active state', () => { | ||
+ function renderComponent(location) { | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer to="/foo"> | ||
+ <Component>Foo</Component> | ||
+ </LinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ const router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory(location)}> | ||
+ <Route component={LinkWrapper}> | ||
+ <Route path="/foo" /> | ||
+ <Route path="/bar" /> | ||
+ </Route> | ||
+ </Router> | ||
+ ); | ||
+ | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ return ReactDOM.findDOMNode(component); | ||
+ } | ||
+ | ||
+ it('should be active when on the target route', () => { | ||
+ expect(renderComponent('/foo').className).to.match(/\bactive\b/); | ||
+ }); | ||
+ | ||
+ it('should not be active when on a different route', () => { | ||
+ expect(renderComponent('/bar').className).to.not.match(/\bactive\b/); | ||
+ }); | ||
+ }); | ||
+ | ||
+ describe('disabled state', () => { | ||
+ let router; | ||
+ | ||
+ beforeEach(() => { | ||
+ class LinkWrapper extends React.Component { | ||
+ render() { | ||
+ return ( | ||
+ <LinkContainer to="/target" disabled> | ||
+ <Component>Target</Component> | ||
+ </LinkContainer> | ||
+ ); | ||
+ } | ||
+ } | ||
+ | ||
+ class Target extends React.Component { | ||
+ render() { | ||
+ return <div className="target" />; | ||
+ } | ||
+ } | ||
+ | ||
+ router = ReactTestUtils.renderIntoDocument( | ||
+ <Router history={createMemoryHistory('/')}> | ||
+ <Route path="/" component={LinkWrapper} /> | ||
+ <Route path="/target" component={Target} /> | ||
+ </Router> | ||
+ ); | ||
+ }); | ||
+ | ||
+ it('should not transition on click', () => { | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(component), | ||
+ {button: 0} | ||
+ ); | ||
+ | ||
+ const target = ReactTestUtils.scryRenderedDOMComponentsWithClass( | ||
+ router, 'target' | ||
+ ); | ||
+ expect(target).to.be.empty; | ||
+ }); | ||
+ | ||
+ it('should render with disabled class', () => { | ||
+ const component = ReactTestUtils.findRenderedComponentWithType( | ||
+ router, Component | ||
+ ); | ||
+ expect(ReactDOM.findDOMNode(component).className) | ||
+ .to.match(/\bdisabled\b/); | ||
+ }); | ||
+ }); | ||
+ }); | ||
+ }); | ||
+}); |
164
tests/ListGroupItemLink.spec.js
@@ -1,164 +0,0 @@ | ||
-/* globals describe, it, assert, expect */ | ||
- | ||
-import React from 'react/addons'; | ||
-import ListGroupItemLink from '../src/ListGroupItemLink'; | ||
-import Router, { Route, RouteHandler } from 'react-router'; | ||
-import { Foo, Bar } from './TestHandlers'; | ||
-import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
-const { click } = React.addons.TestUtils.Simulate; | ||
- | ||
-describe('A ListGroupItemLink', function() { | ||
- describe('with params and a query', function() { | ||
- it('knows how to make its href', function() { | ||
- const ListGroupItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return <ListGroupItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>ListGroupItemLink</ListGroupItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
- <Route name="link" handler={ListGroupItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when its route is active', function() { | ||
- it('has an active class name', function(done) { | ||
- const ListGroupItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <ListGroupItemLink | ||
- to="foo" | ||
- className="dontKillMe" | ||
- >ListGroupItemLink</ListGroupItemLink> | ||
- <RouteHandler/> | ||
- </div> | ||
- ); | ||
- } | ||
- }); | ||
- | ||
- const routes = ( | ||
- <Route path="/" handler={ListGroupItemLinkHandler}> | ||
- <Route name="foo" handler={Foo} /> | ||
- <Route name="bar" handler={Bar} /> | ||
- </Route> | ||
- ); | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/foo']; | ||
- const steps = []; | ||
- | ||
- function assertActive() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.className.split(' ').sort().join(' ')).to.equal('active dontKillMe list-group-item'); | ||
- } | ||
- | ||
- function assertInactive() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.className).to.equal('dontKillMe list-group-item'); | ||
- } | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- testLocation.push('/bar'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertInactive(); | ||
- testLocation.push('/foo'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, () => { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when clicked', function() { | ||
- it('calls a user defined click handler', function(done) { | ||
- const ListGroupItemLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- assert.ok(true); | ||
- done(); | ||
- }, | ||
- | ||
- render() { | ||
- return <ListGroupItemLink to="foo" onClick={this.handleClick}>ListGroupItemLink</ListGroupItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={ListGroupItemLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('transitions to the correct route', function(done) { | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- const ListGroupItemLinkHandler = React.createClass({ | ||
- handleClick() { | ||
- // just here to make sure click handlers don't prevent it from happening | ||
- }, | ||
- | ||
- render() { | ||
- return <ListGroupItemLink to="foo" onClick={this.handleClick}>ListGroupItemLink</ListGroupItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={ListGroupItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const steps = []; | ||
- | ||
- steps.push(function() { | ||
- click(div.querySelector('a'), {button: 0}); | ||
- }); | ||
- | ||
- steps.push(function() { | ||
- expect(div.innerHTML).to.match(/Foo/); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
-}); |
168
tests/MenuItemLink.spec.js
@@ -1,168 +0,0 @@ | ||
-/* globals describe, it, assert, expect */ | ||
- | ||
-import React from 'react/addons'; | ||
-import MenuItemLink from '../src/MenuItemLink'; | ||
-import Router, { Route, RouteHandler } from 'react-router'; | ||
-import { Foo, Bar } from './TestHandlers'; | ||
-import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
-const { click } = React.addons.TestUtils.Simulate; | ||
- | ||
-describe('A MenuItemLink', function() { | ||
- describe('with params and a query', function() { | ||
- it('knows how to make its href', function() { | ||
- const MenuItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return <MenuItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>MenuItemLink</MenuItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
- <Route name="link" handler={MenuItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when its route is active', function() { | ||
- it('has an active class name', function(done) { | ||
- const MenuItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <MenuItemLink | ||
- to="foo" | ||
- className="dontKillMe" | ||
- >MenuItemLink</MenuItemLink> | ||
- <RouteHandler/> | ||
- </div> | ||
- ); | ||
- } | ||
- }); | ||
- | ||
- const routes = ( | ||
- <Route path="/" handler={MenuItemLinkHandler}> | ||
- <Route name="foo" handler={Foo} /> | ||
- <Route name="bar" handler={Bar} /> | ||
- </Route> | ||
- ); | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/foo']; | ||
- const steps = []; | ||
- | ||
- function assertActive() { | ||
- const li = div.querySelector('li'); | ||
- expect(li.className.split(' ').sort().join(' ')).to.equal('active dontKillMe'); | ||
- const a = div.querySelector('a'); | ||
- expect(a.className.split(' ').sort().join(' ')).to.equal(''); | ||
- } | ||
- | ||
- function assertInactive() { | ||
- const li = div.querySelector('li'); | ||
- expect(li.className.split(' ').sort().join(' ')).to.equal('dontKillMe'); | ||
- const a = div.querySelector('a'); | ||
- expect(a.className.split(' ').sort().join(' ')).to.equal(''); | ||
- } | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- testLocation.push('/bar'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertInactive(); | ||
- testLocation.push('/foo'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, () => { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when clicked', function() { | ||
- it('calls a user defined click handler', function(done) { | ||
- const MenuItemLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- assert.ok(true); | ||
- done(); | ||
- }, | ||
- | ||
- render() { | ||
- return <MenuItemLink to="foo" onClick={this.handleClick}>MenuItemLink</MenuItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={MenuItemLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('transitions to the correct route', function(done) { | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- const MenuItemLinkHandler = React.createClass({ | ||
- handleClick() { | ||
- // just here to make sure click handlers don't prevent it from happening | ||
- }, | ||
- | ||
- render() { | ||
- return <MenuItemLink to="foo" onClick={this.handleClick}>MenuItemLink</MenuItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={MenuItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const steps = []; | ||
- | ||
- steps.push(function() { | ||
- click(div.querySelector('a'), {button: 0}); | ||
- }); | ||
- | ||
- steps.push(function() { | ||
- expect(div.innerHTML).to.match(/Foo/); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
-}); |
190
tests/NavItemLink.spec.js
@@ -1,190 +0,0 @@ | ||
-/* globals describe, it, assert, expect */ | ||
- | ||
-import React from 'react/addons'; | ||
-import NavItemLink from '../src/NavItemLink'; | ||
-import Router, { Route, RouteHandler } from 'react-router'; | ||
-import { Foo, Bar } from './TestHandlers'; | ||
-import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
-const { click } = React.addons.TestUtils.Simulate; | ||
- | ||
-describe('A NavItemLink', function() { | ||
- describe('with params and a query', function() { | ||
- it('knows how to make its href', function() { | ||
- const NavItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return <NavItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>NavItemLink</NavItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
- <Route name="link" handler={NavItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when its route is active', function() { | ||
- it('has an active class name', function(done) { | ||
- const NavItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <NavItemLink | ||
- to="foo" | ||
- className="dontKillMe" | ||
- >NavItemLink</NavItemLink> | ||
- <RouteHandler/> | ||
- </div> | ||
- ); | ||
- } | ||
- }); | ||
- | ||
- const routes = ( | ||
- <Route path="/" handler={NavItemLinkHandler}> | ||
- <Route name="foo" handler={Foo} /> | ||
- <Route name="bar" handler={Bar} /> | ||
- </Route> | ||
- ); | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/foo']; | ||
- const steps = []; | ||
- | ||
- function assertActive() { | ||
- const a = div.querySelector('li'); | ||
- expect(a.className.split(' ').sort().join(' ')).to.equal('active dontKillMe'); | ||
- } | ||
- | ||
- function assertInactive() { | ||
- const a = div.querySelector('li'); | ||
- expect(a.className).to.equal('dontKillMe'); | ||
- } | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- testLocation.push('/bar'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertInactive(); | ||
- testLocation.push('/foo'); | ||
- }); | ||
- | ||
- steps.push(() => { | ||
- assertActive(); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, () => { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when clicked', function() { | ||
- it('calls a user defined click handler', function(done) { | ||
- const NavItemLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- assert.ok(true); | ||
- done(); | ||
- }, | ||
- | ||
- render() { | ||
- return <NavItemLink to="foo" onClick={this.handleClick}>NavItemLink</NavItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={NavItemLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('when disabled does not proceed', function() { | ||
- const NavItemLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- throw new Error('click should not be called'); | ||
- }, | ||
- | ||
- render() { | ||
- return <NavItemLink to="foo" disabled onClick={this.handleClick}>NavItemLink</NavItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={NavItemLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('transitions to the correct route', function(done) { | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- const NavItemLinkHandler = React.createClass({ | ||
- handleClick() { | ||
- // just here to make sure click handlers don't prevent it from happening | ||
- }, | ||
- | ||
- render() { | ||
- return <NavItemLink to="foo" onClick={this.handleClick}>NavItemLink</NavItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={NavItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const steps = []; | ||
- | ||
- steps.push(function() { | ||
- click(div.querySelector('a'), {button: 0}); | ||
- }); | ||
- | ||
- steps.push(function() { | ||
- expect(div.innerHTML).to.match(/Foo/); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
-}); |
103
tests/PageItemLink.spec.js
@@ -1,103 +0,0 @@ | ||
-/* globals describe, it, assert, expect */ | ||
- | ||
-import React from 'react/addons'; | ||
-import PageItemLink from '../src/PageItemLink'; | ||
-import Router, { Route } from 'react-router'; | ||
-import { Foo } from './TestHandlers'; | ||
-import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
-const { click } = React.addons.TestUtils.Simulate; | ||
- | ||
-describe('A PageItemLink', function() { | ||
- describe('with params and a query', function() { | ||
- it('knows how to make its href', function() { | ||
- const PageItemLinkHandler = React.createClass({ | ||
- render() { | ||
- return <PageItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>PageItemLink</PageItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
- <Route name="link" handler={PageItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when clicked', function() { | ||
- it('calls a user defined click handler', function(done) { | ||
- const PageItemLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- assert.ok(true); | ||
- done(); | ||
- }, | ||
- | ||
- render() { | ||
- return <PageItemLink to="foo" onClick={this.handleClick}>PageItemLink</PageItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={PageItemLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('transitions to the correct route', function(done) { | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- const PageItemLinkHandler = React.createClass({ | ||
- handleClick() { | ||
- // just here to make sure click handlers don't prevent it from happening | ||
- }, | ||
- | ||
- render() { | ||
- return <PageItemLink to="foo" onClick={this.handleClick}>PageItemLink</PageItemLink>; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={PageItemLinkHandler} /> | ||
- ]; | ||
- | ||
- const steps = []; | ||
- | ||
- steps.push(function() { | ||
- click(div.querySelector('a'), {button: 0}); | ||
- }); | ||
- | ||
- steps.push(function() { | ||
- expect(div.innerHTML).to.match(/Foo/); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
-}); |
13
tests/RouterOverlayTrigger.spec.js
@@ -1,13 +0,0 @@ | ||
-/* globals describe, it, expect */ | ||
- | ||
-import React from 'react'; | ||
- | ||
-import RouterOverlayTrigger from '../src/RouterOverlayTrigger'; | ||
- | ||
-describe('A RouterOverlayTrigger', function() { | ||
- it('has the right contextTypes', function() { | ||
- expect(RouterOverlayTrigger.contextTypes).to.eql({ | ||
- router: React.PropTypes.func | ||
- }); | ||
- }); | ||
-}); |
31
tests/TestHandlers.js
@@ -1,31 +0,0 @@ | ||
-import React from 'react'; | ||
-import { RouteHandler } from 'react-router'; | ||
- | ||
-exports.Nested = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <h1 className="Nested">Nested</h1> | ||
- <RouteHandler /> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-exports.Foo = React.createClass({ | ||
- render() { | ||
- return <div className="Foo">Foo</div>; | ||
- } | ||
-}); | ||
- | ||
-exports.Bar = React.createClass({ | ||
- render() { | ||
- return <div className="Bar">Bar</div>; | ||
- } | ||
-}); | ||
- | ||
-exports.Baz = React.createClass({ | ||
- render() { | ||
- return <div className="Baz">Baz</div>; | ||
- } | ||
-}); |
103
tests/ThumbnailLink.spec.js
@@ -1,103 +0,0 @@ | ||
-/* globals describe, it, assert, expect */ | ||
- | ||
-import React from 'react/addons'; | ||
-import ThumbnailLink from '../src/ThumbnailLink'; | ||
-import Router, { Route } from 'react-router'; | ||
-import { Foo } from './TestHandlers'; | ||
-import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
-const { click } = React.addons.TestUtils.Simulate; | ||
- | ||
-describe('A ThumbnailLink', function() { | ||
- describe('with params and a query', function() { | ||
- it('knows how to make its href', function() { | ||
- const ThumbnailLinkHandler = React.createClass({ | ||
- render() { | ||
- return <ThumbnailLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}} />; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
- <Route name="link" handler={ThumbnailLinkHandler} /> | ||
- ]; | ||
- | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- const a = div.querySelector('a'); | ||
- expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- describe('when clicked', function() { | ||
- it('calls a user defined click handler', function(done) { | ||
- const ThumbnailLinkHandler = React.createClass({ | ||
- handleClick(event) { | ||
- assert.ok(true); | ||
- done(); | ||
- }, | ||
- | ||
- render() { | ||
- return <ThumbnailLink to="foo" onClick={this.handleClick} />; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={ThumbnailLinkHandler} /> | ||
- ]; | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- click(div.querySelector('a')); | ||
- }); | ||
- }); | ||
- }); | ||
- | ||
- it('transitions to the correct route', function(done) { | ||
- const div = document.createElement('div'); | ||
- const testLocation = new TestLocation(); | ||
- testLocation.history = ['/link']; | ||
- | ||
- const ThumbnailLinkHandler = React.createClass({ | ||
- handleClick() { | ||
- // just here to make sure click handlers don't prevent it from happening | ||
- }, | ||
- | ||
- render() { | ||
- return <ThumbnailLink to="foo" onClick={this.handleClick} />; | ||
- } | ||
- }); | ||
- | ||
- const routes = [ | ||
- <Route name="foo" handler={Foo} />, | ||
- <Route name="link" handler={ThumbnailLinkHandler} /> | ||
- ]; | ||
- | ||
- const steps = []; | ||
- | ||
- steps.push(function() { | ||
- click(div.querySelector('a'), {button: 0}); | ||
- }); | ||
- | ||
- steps.push(function() { | ||
- expect(div.innerHTML).to.match(/Foo/); | ||
- done(); | ||
- }); | ||
- | ||
- Router.run(routes, testLocation, function(Handler) { | ||
- React.render(<Handler/>, div, function() { | ||
- steps.shift()(); | ||
- }); | ||
- }); | ||
- }); | ||
- }); | ||
-}); |
21
tests/bower-imports-module.spec.js
@@ -1,21 +0,0 @@ | ||
-import loader from '../webpack/bower-imports-loader'; | ||
- | ||
-describe('bower-imports-loader', function() { | ||
- it('replaces react-bootstrap/lib/* imports to work with bower dependency', function() { | ||
- const input = `import React from 'react'; | ||
- | ||
-import Button from 'react-bootstrap/lib/Button'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const ButtonLink = React.createClass({`; | ||
- | ||
- const expected = `import React from 'react'; | ||
- | ||
-import {Button} from 'react-bootstrap'; | ||
-import LinkMixin from './LinkMixin'; | ||
- | ||
-const ButtonLink = React.createClass({`; | ||
- | ||
- loader(input).should.equal(expected); | ||
- }); | ||
-}); |
21
tests/index.js
@@ -1,19 +1,4 @@ | ||
-import './phantom-shims'; | ||
-import 'mocha'; | ||
+import 'es5-shim'; | ||
-const chai = require('chai'); | ||
-chai.should(); | ||
- | ||
-global.expect = chai.expect; | ||
-global.assert = chai.assert; | ||
- | ||
-global.TestUtils = require('react/addons').addons.TestUtils; | ||
- | ||
-import './ButtonLink.spec.js'; | ||
-import './ListGroupItemLink.spec.js'; | ||
-import './MenuItemLink.spec.js'; | ||
-import './NavItemLink.spec.js'; | ||
-import './PageItemLink.spec.js'; | ||
-import './RouterOverlayTrigger.spec.js'; | ||
-import './ThumbnailLink.spec.js'; | ||
-import './bower-imports-module.spec.js'; | ||
+const testsContext = require.context('.', true, /\.spec\.js$/); | ||
+testsContext.keys().forEach(testsContext); |
31
tests/phantom-shims.js
@@ -1,31 +0,0 @@ | ||
-const Ap = Array.prototype; | ||
-const slice = Ap.slice; | ||
-const Fp = Function.prototype; | ||
- | ||
-if (!Fp.bind) { | ||
- // PhantomJS doesn't support Function.prototype.bind natively, so | ||
- // polyfill it whenever this module is required. | ||
- Fp.bind = function(context) { | ||
- const func = this; | ||
- const args = slice.call(arguments, 1); | ||
- | ||
- function bound() { | ||
- const invokedAsConstructor = func.prototype && (this instanceof func); | ||
- return func.apply( | ||
- // Ignore the context parameter when invoking the bound function | ||
- // as a constructor. Note that this includes not only constructor | ||
- // invocations using the new keyword but also calls to base class | ||
- // constructors such as BaseClass.call(this, ...) or super(...). | ||
- !invokedAsConstructor && context || this, | ||
- args.concat(slice.call(arguments)) | ||
- ); | ||
- } | ||
- | ||
- // The bound function must share the .prototype of the unbound | ||
- // function so that any object created by one constructor will count | ||
- // as an instance of both constructors. | ||
- bound.prototype = func.prototype; | ||
- | ||
- return bound; | ||
- }; | ||
-} |
2
tests/visual.js
@@ -1,2 +0,0 @@ | ||
-import 'bootstrap/less/bootstrap.less'; | ||
-import './visual/app'; |
71
tests/visual/ButtonVisual.js
@@ -1,36 +1,45 @@ | ||
import React from 'react'; | ||
-import {Link} from 'react-router'; | ||
import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar'; | ||
import Button from 'react-bootstrap/lib/Button'; | ||
-import ButtonLink from '../../src/ButtonLink'; | ||
+import {Link} from 'react-router'; | ||
+ | ||
+import LinkContainer from '../../src/LinkContainer'; | ||
+ | ||
+export default () => ( | ||
+ <div> | ||
+ <Link to="home">Back to Index</Link> | ||
+ <h2>Button</h2> | ||
-const ButtonVisual = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <Link to='home'><-- Back to Index</Link> | ||
- <h2>ButtonLink</h2> | ||
- <h3>Baseline (Raw React-Bootstrap)</h3> | ||
- <ButtonToolbar> | ||
- <Button>Default</Button> | ||
- <Button bsStyle="success">Success</Button> | ||
- <Button bsStyle="info">Info</Button> | ||
- <Button bsStyle="warning">Warning</Button> | ||
- <Button bsStyle="danger">Danger</Button> | ||
- <Button bsStyle="link">Link</Button> | ||
- </ButtonToolbar> | ||
- <h3>ButtonLink</h3> | ||
- <ButtonToolbar> | ||
- <ButtonLink to='home'>Default</ButtonLink> | ||
- <ButtonLink to='home' bsStyle="success">Success</ButtonLink> | ||
- <ButtonLink to='home' bsStyle="info">Info</ButtonLink> | ||
- <ButtonLink to='home' bsStyle="warning">Warning</ButtonLink> | ||
- <ButtonLink to='home' bsStyle="danger">Danger</ButtonLink> | ||
- <ButtonLink to='home' bsStyle="link">Link</ButtonLink> | ||
- </ButtonToolbar> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
+ <h3>Baseline</h3> | ||
+ <ButtonToolbar> | ||
+ <Button>Default</Button> | ||
+ <Button bsStyle="success">Success</Button> | ||
+ <Button bsStyle="info">Info</Button> | ||
+ <Button bsStyle="warning">Warning</Button> | ||
+ <Button bsStyle="danger">Danger</Button> | ||
+ <Button bsStyle="link">Link</Button> | ||
+ </ButtonToolbar> | ||
-export default ButtonVisual; | ||
+ <h3>LinkContainer</h3> | ||
+ <ButtonToolbar> | ||
+ <LinkContainer to="/home"> | ||
+ <Button>Default</Button> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <Button bsStyle="success">Success</Button> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <Button bsStyle="info">Info</Button> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <Button bsStyle="warning">Warning</Button> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <Button bsStyle="danger">Danger</Button> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <Button bsStyle="link">Link</Button> | ||
+ </LinkContainer> | ||
+ </ButtonToolbar> | ||
+ </div> | ||
+); |
108
tests/visual/ListGroupItemVisual.js
@@ -1,41 +1,77 @@ | ||
import React from 'react'; | ||
-import {Link} from 'react-router'; | ||
import ListGroup from 'react-bootstrap/lib/ListGroup'; | ||
import ListGroupItem from 'react-bootstrap/lib/ListGroupItem'; | ||
-import ListGroupItemLink from '../../src/ListGroupItemLink'; | ||
+import {Link} from 'react-router'; | ||
+ | ||
+import LinkContainer from '../../src/LinkContainer'; | ||
+ | ||
+export default () => ( | ||
+ <div> | ||
+ <Link to="/home">Back to Index</Link> | ||
+ <h2>ListGroupItem</h2> | ||
-const NavItemVisual = React.createClass({ | ||
- handleSelect(selectedKey) { | ||
- window.alert('selected ' + selectedKey); | ||
- }, | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <Link to='home'><-- Back to Index</Link> | ||
- <h2>ListGroupItemLink</h2> | ||
- <h3>Baseline (Raw React-Bootstrap)</h3> | ||
- <ListGroup> | ||
- <ListGroupItem eventKey={1} href="/home" header="ListGroupItem 1 Heading">ListGroupItem 1 content</ListGroupItem> | ||
- <ListGroupItem eventKey={2} header="ListGroupItem 2 Heading">ListGroupItem 2 content</ListGroupItem> | ||
- <ListGroupItem eventKey={3} disabled={true}>ListGroupItem 3 content disabled</ListGroupItem> | ||
- <ListGroupItem eventKey={4} bsStyle="success">ListGroupItem 4 content success</ListGroupItem> | ||
- <ListGroupItem eventKey={5} bsStyle="info">ListGroupItem 5 content info</ListGroupItem> | ||
- <ListGroupItem eventKey={6} bsStyle="warning">ListGroupItem 6 content warning</ListGroupItem> | ||
- <ListGroupItem eventKey={7} bsStyle="danger">ListGroupItem 7 content danger</ListGroupItem> | ||
- </ListGroup> | ||
- <h3>ListGroupItemLink</h3> | ||
- <ListGroup> | ||
- <ListGroupItemLink to="list-group-item" header="ListGroupItemLink 1 Heading">ListGroupItemLink 1 content</ListGroupItemLink> | ||
- <ListGroupItemLink to="home" header="ListGroupItemLink 2 Heading">ListGroupItemLink 2 content</ListGroupItemLink> | ||
- <ListGroupItemLink to="home" disabled={true}>ListGroupItemLink 3 content disabled</ListGroupItemLink> | ||
- <ListGroupItemLink to="home" bsStyle="success">ListGroupItemLink 4 content success</ListGroupItemLink> | ||
- <ListGroupItemLink to="home" bsStyle="info">ListGroupItemLink 5 content info</ListGroupItemLink> | ||
- <ListGroupItemLink to="home" bsStyle="warning">ListGroupItemLink 6 content warning</ListGroupItemLink> | ||
- <ListGroupItemLink to="home" bsStyle="danger">ListGroupItemLink 7 content danger</ListGroupItemLink> | ||
- </ListGroup> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
+ <h3>Baseline</h3> | ||
+ <ListGroup> | ||
+ <ListGroupItem href="#/home" active header="ListGroupItem 1 Heading"> | ||
+ ListGroupItem 1 content | ||
+ </ListGroupItem> | ||
+ <ListGroupItem header="ListGroupItem 2 Heading"> | ||
+ ListGroupItem 2 content | ||
+ </ListGroupItem> | ||
+ <ListGroupItem disabled> | ||
+ ListGroupItem 3 content disabled | ||
+ </ListGroupItem> | ||
+ <ListGroupItem bsStyle="success"> | ||
+ ListGroupItem 4 content success | ||
+ </ListGroupItem> | ||
+ <ListGroupItem bsStyle="info"> | ||
+ ListGroupItem 5 content info | ||
+ </ListGroupItem> | ||
+ <ListGroupItem bsStyle="warning"> | ||
+ ListGroupItem 6 content warning | ||
+ </ListGroupItem> | ||
+ <ListGroupItem bsStyle="danger"> | ||
+ ListGroupItem 7 content danger | ||
+ </ListGroupItem> | ||
+ </ListGroup> | ||
-export default NavItemVisual; | ||
+ <h3>LinkContainer</h3> | ||
+ <ListGroup> | ||
+ <LinkContainer to="/list-group-item"> | ||
+ <ListGroupItem header="ListGroupItem 1 Heading"> | ||
+ ListGroupItem 1 content | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <ListGroupItem header="ListGroupItem 2 Heading"> | ||
+ ListGroupItem 2 content | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home" disabled> | ||
+ <ListGroupItem> | ||
+ ListGroupItem 3 content disabled | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <ListGroupItem bsStyle="success"> | ||
+ ListGroupItem 4 content success | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <ListGroupItem bsStyle="info"> | ||
+ ListGroupItem 5 content info | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <ListGroupItem bsStyle="warning"> | ||
+ ListGroupItem 6 content warning | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <ListGroupItem bsStyle="danger"> | ||
+ ListGroupItem 7 content danger | ||
+ </ListGroupItem> | ||
+ </LinkContainer> | ||
+ </ListGroup> | ||
+ </div> | ||
+); |
42
tests/visual/MenuItemVisual.js
@@ -1,42 +0,0 @@ | ||
-import React from 'react'; | ||
-import {Link} from 'react-router'; | ||
-import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar'; | ||
-import SplitButton from 'react-bootstrap/lib/SplitButton'; | ||
-import MenuItem from 'react-bootstrap/lib/MenuItem'; | ||
-import MenuItemLink from '../../src/MenuItemLink'; | ||
- | ||
-const MenuItemVisual = React.createClass({ | ||
- handleSelect(selectedKey) { | ||
- window.alert('selected ' + selectedKey); | ||
- }, | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <Link to='home'><-- Back to Index</Link> | ||
- <h2>MenuItemLink</h2> | ||
- <h3>Baseline (Raw React-Bootstrap)</h3> | ||
- <ButtonToolbar> | ||
- <SplitButton title="Dropdown"> | ||
- <MenuItem eventKey="1">Action</MenuItem> | ||
- <MenuItem eventKey="2">Another action</MenuItem> | ||
- <MenuItem eventKey="3">Something else here</MenuItem> | ||
- <MenuItem divider /> | ||
- <MenuItem eventKey="4">Separated link</MenuItem> | ||
- </SplitButton> | ||
- </ButtonToolbar> | ||
- <h3>MenuItemLink</h3> | ||
- <ButtonToolbar> | ||
- <SplitButton title="Dropdown"> | ||
- <MenuItemLink to='menu-item'>Action</MenuItemLink> | ||
- <MenuItemLink to='home'>Another action</MenuItemLink> | ||
- <MenuItemLink to='home'>Something else here</MenuItemLink> | ||
- <MenuItem divider /> | ||
- <MenuItemLink to='home'>Separated link</MenuItemLink> | ||
- </SplitButton> | ||
- </ButtonToolbar> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default MenuItemVisual; |
56
tests/visual/NavItemVisual.js
@@ -1,33 +1,33 @@ | ||
import React from 'react'; | ||
-import {Link} from 'react-router'; | ||
import Nav from 'react-bootstrap/lib/Nav'; | ||
import NavItem from 'react-bootstrap/lib/NavItem'; | ||
-import NavItemLink from '../../src/NavItemLink'; | ||
+import {Link} from 'react-router'; | ||
+ | ||
+import LinkContainer from '../../src/LinkContainer'; | ||
+ | ||
+export default () => ( | ||
+ <div> | ||
+ <Link to="/home">Back to Index</Link> | ||
+ <h2>NavItem</h2> | ||
-const NavItemVisual = React.createClass({ | ||
- handleSelect(selectedKey) { | ||
- window.alert('selected ' + selectedKey); | ||
- }, | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <Link to='home'><-- Back to Index</Link> | ||
- <h2>NavItemLink</h2> | ||
- <h3>Baseline (Raw React-Bootstrap)</h3> | ||
- <Nav bsStyle="pills" activeKey={1} onSelect={this.handleSelect}> | ||
- <NavItem eventKey={1} href="/home">NavItem 1 content</NavItem> | ||
- <NavItem eventKey={2} title="Item">NavItem 2 content</NavItem> | ||
- <NavItem eventKey={3} disabled={true}>NavItem 3 content</NavItem> | ||
- </Nav> | ||
- <h3>NavItemLink</h3> | ||
- <Nav bsStyle="pills"> | ||
- <NavItemLink to='nav-item'>NavItemLink 1 content</NavItemLink> | ||
- <NavItemLink to='home'>NavItemLink 2 content</NavItemLink> | ||
- <NavItemLink to='home' disabled={true}>NavItemLink 3 content</NavItemLink> | ||
- </Nav> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
+ <h3>Baseline</h3> | ||
+ <Nav bsStyle="pills" activeKey={1}> | ||
+ <NavItem eventKey={1}>NavItem 1 content</NavItem> | ||
+ <NavItem eventKey={2}>NavItem 2 content</NavItem> | ||
+ <NavItem eventKey={3} disabled>NavItem 3 content</NavItem> | ||
+ </Nav> | ||
-export default NavItemVisual; | ||
+ <h3>LinkContainer</h3> | ||
+ <Nav bsStyle="pills"> | ||
+ <LinkContainer to="/nav-item"> | ||
+ <NavItem>NavItem 1 content</NavItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home"> | ||
+ <NavItem>NavItem 2 content</NavItem> | ||
+ </LinkContainer> | ||
+ <LinkContainer to="/home" disabled> | ||
+ <NavItem>NavItem 3 content</NavItem> | ||
+ </LinkContainer> | ||
+ </Nav> | ||
+ </div> | ||
+); |
28
tests/visual/PageItemVisual.js
@@ -1,28 +0,0 @@ | ||
-import React from 'react'; | ||
-import {Link} from 'react-router'; | ||
-import Pager from 'react-bootstrap/lib/Pager'; | ||
-import PageItem from 'react-bootstrap/lib/PageItem'; | ||
-import PageItemLink from '../../src/PageItemLink'; | ||
- | ||
-const PageItemVisual = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <Link to='home'><-- Back to Index</Link> | ||
- <h2>PageItemLink</h2> | ||
- <h3>Baseline (Raw React-Bootstrap)</h3> | ||
- <Pager> | ||
- <PageItem previous>← Previous Page</PageItem> | ||
- <PageItem next>Next Page →</PageItem> | ||
- </Pager> | ||
- <h3>PageItemLink</h3> | ||
- <Pager> | ||
- <PageItemLink previous to='home'>← Previous Page</PageItemLink> | ||
- <PageItemLink next to='home'>Next Page →</PageItemLink> | ||
- </Pager> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default PageItemVisual; |
21
tests/visual/ThumbnailVisual.js
@@ -1,21 +0,0 @@ | ||
-import React from 'react'; | ||
-import {Link} from 'react-router'; | ||
-import Thumbnail from 'react-bootstrap/lib/Thumbnail'; | ||
-import ThumbnailLink from '../../src/ThumbnailLink'; | ||
- | ||
-const ThumbnailVisual = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <Link to='home'><-- Back to Index</Link> | ||
- <h2>Thumbnailink</h2> | ||
- <h3>Baseline (Raw React-Bootstrap)</h3> | ||
- <Thumbnail alt='171x180' src='/assets/thumbnail.png' /> | ||
- <h3>ThumbnailLink</h3> | ||
- <ThumbnailLink to='home' alt='171x180' src='/assets/thumbnail.png' /> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default ThumbnailVisual; |
29
tests/visual/app.js
@@ -1,29 +0,0 @@ | ||
-import React from 'react'; | ||
-import Router, { Route, RouteHandler } from 'react-router'; | ||
- | ||
-const App = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <h1>React-Router-Bootstrap Module Visual Test</h1> | ||
- <RouteHandler /> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-const routes = ( | ||
- <Route handler={App} path="/"> | ||
- <Route name='home' path='/' handler={require('./home')} /> | ||
- <Route name='button' handler={require('./ButtonVisual')} /> | ||
- <Route name='nav-item' handler={require('./NavItemVisual')} /> | ||
- <Route name='menu-item' handler={require('./MenuItemVisual')} /> | ||
- <Route name='list-group-item' handler={require('./ListGroupItemVisual')} /> | ||
- <Route name='page-item' handler={require('./PageItemVisual')} /> | ||
- <Route name='thumbnail' handler={require('./ThumbnailVisual')} /> | ||
- </Route> | ||
-); | ||
- | ||
-Router.run(routes, function(Handler) { | ||
- React.render(<Handler/>, document.body); | ||
-}); |
29
tests/visual/home.js
@@ -1,22 +1,13 @@ | ||
import React from 'react'; | ||
import {Link} from 'react-router'; | ||
-const Home = React.createClass({ | ||
- render() { | ||
- return ( | ||
- <div> | ||
- <h2>Index</h2> | ||
- <ul> | ||
- <li><Link to='button'>ButtonLink</Link></li> | ||
- <li><Link to='nav-item'>NavItemLink</Link></li> | ||
- <li><Link to='menu-item'>MenuItemLink</Link></li> | ||
- <li><Link to='list-group-item'>ListGroupItemLink</Link></li> | ||
- <li><Link to='page-item'>PageItemLink</Link></li> | ||
- <li><Link to='thumbnail'>ThumbnailLink</Link></li> | ||
- </ul> | ||
- </div> | ||
- ); | ||
- } | ||
-}); | ||
- | ||
-export default Home; | ||
+export default () => ( | ||
+ <div> | ||
+ <h2>Index</h2> | ||
+ <ul> | ||
+ <li><Link to="/button">Button</Link></li> | ||
+ <li><Link to="/nav-item">NavItem</Link></li> | ||
+ <li><Link to="/list-group-item">ListGroupItem</Link></li> | ||
+ </ul> | ||
+ </div> | ||
+); |
35
tests/visual/index.js
@@ -0,0 +1,35 @@ | ||
+import React from 'react'; | ||
+import Grid from 'react-bootstrap/lib/Grid'; | ||
+import ReactDOM from 'react-dom'; | ||
+import {IndexRoute, Route, Router} from 'react-router'; | ||
+ | ||
+import ButtonVisual from './ButtonVisual'; | ||
+import Home from './Home'; | ||
+import ListGroupItemVisual from './ListGroupItemVisual'; | ||
+import NavItemVisual from './NavItemVisual'; | ||
+ | ||
+import 'bootstrap/less/bootstrap.less'; | ||
+ | ||
+const App = ({children}) => ( | ||
+ <Grid> | ||
+ <h1>React-Router-Bootstrap Module Visual Test</h1> | ||
+ {children} | ||
+ </Grid> | ||
+); | ||
+ | ||
+const mountNode = document.createElement('div'); | ||
+document.body.appendChild(mountNode); | ||
+ | ||
+ReactDOM.render( | ||
+ <Router> | ||
+ <Route path="/" component={App}> | ||
+ <IndexRoute onEnter={(_, replaceWith) => replaceWith(null, '/home')} /> | ||
+ <Route path="home" component={Home} /> | ||
+ | ||
+ <Route path="button" component={ButtonVisual} /> | ||
+ <Route path="nav-item" component={NavItemVisual} /> | ||
+ <Route path="list-group-item" component={ListGroupItemVisual} /> | ||
+ </Route> | ||
+ </Router>, | ||
+ mountNode | ||
+); |
50
webpack.config.babel.js
23
webpack.test.config.babel.js
@@ -1,24 +1,11 @@ | ||
-import path from 'path'; | ||
- | ||
-module.exports = { | ||
- entry: { | ||
- visual: ['./tests/visual.js'] | ||
- }, | ||
- | ||
- devtool: 'inline-source-map', | ||
- | ||
+export default { | ||
output: { | ||
- path: path.join(__dirname, 'tests-served/'), | ||
- publicPath: '/public/', | ||
- filename: '[name].js' | ||
+ pathinfo: true | ||
}, | ||
- | ||
module: { | ||
loaders: [ | ||
- {test: /\.js/, loader: 'babel', exclude: /node_modules/}, | ||
- {test: /\.less$/, loader: 'style!css!less'}, | ||
- {test:/\.woff|\.woff2$/, loader: 'url?prefix=font/&limit=5000'}, | ||
- {test:/\.eot$|\.ttf$|\.svg$/, loader: 'file?prefix=font/'} | ||
+ {test: /\.js/, loader: 'babel', exclude: /node_modules/} | ||
] | ||
- } | ||
+ }, | ||
+ devtool: 'inline-source-map' | ||
}; |
17
webpack.visual.config.babel.js
@@ -0,0 +1,17 @@ | ||
+import HtmlWebpackPlugin from 'html-webpack-plugin'; | ||
+ | ||
+export default { | ||
+ entry: './tests/visual', | ||
+ module: { | ||
+ loaders: [ | ||
+ {test: /\.js/, loader: 'babel', exclude: /node_modules/}, | ||
+ {test: /\.less$/, loader: 'style!css!less'}, | ||
+ {test: /\.woff|\.woff2$/, loader: 'url?prefix=font/&limit=5000'}, | ||
+ {test: /\.eot$|\.ttf$|\.svg$/, loader: 'file?prefix=font/'} | ||
+ ] | ||
+ }, | ||
+ plugins: [ | ||
+ new HtmlWebpackPlugin() | ||
+ ], | ||
+ devtool: 'eval-source-map' | ||
+}; |
7
webpack/bower-imports-loader.js
@@ -1,7 +0,0 @@ | ||
-export default function bowerImportsLoader(source) { | ||
- const rgx = /^import (.*) from 'react-bootstrap\/lib\/.*';/; | ||
- | ||
- return source.split('\n') | ||
- .map(line => line.replace(rgx, "import {$1} from 'react-bootstrap';")) | ||
- .join('\n'); | ||
-} |
0 comments on commit
ac500c8