Skip to content

Commit

Permalink
[changed] Replace everything with LinkContainer
Browse files Browse the repository at this point in the history
taion committed Sep 15, 2015
1 parent 888fc56 commit ac500c8
Showing 47 changed files with 639 additions and 1,805 deletions.
4 changes: 0 additions & 4 deletions .eslintignore

This file was deleted.

38 changes: 2 additions & 36 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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 changes: 13 additions & 107 deletions README.md
Original file line number Diff line number Diff line change
@@ -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).
Binary file removed assets/thumbnail.png
Binary file not shown.
20 changes: 11 additions & 9 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -4,26 +4,28 @@ delete webpackConfig.entry;

module.exports = function (config) {
config.set({

basePath: '',

frameworks: [ 'mocha' ],
frameworks: [
'mocha',
'sinon-chai'
],

files: [
'./tests/index.js'
],

exclude: [],

preprocessors: {
'./tests/index.js': [ 'webpack' ]
'./tests/index.js': ['webpack', 'sourcemap']
},

webpack: [ webpackConfig ],
webpack: webpackConfig,

webpackMiddleware: { },
webpackMiddleware: {
noInfo: true
},

reporters: [ 'mocha' ],
reporters: ['mocha'],

port: 9876,

@@ -33,7 +35,7 @@ module.exports = function (config) {

autoWatch: true,

browsers: [ 'PhantomJS' ],
browsers: ['PhantomJS'],

captureTimeout: 60000,
browserDisconnectTimeout: 7000,
80 changes: 41 additions & 39 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
{
"name": "react-router-bootstrap",
"version": "0.18.1",
"description": "react-router and react-bootstrap compatible components",
"description": "Integration between React Router and React-Bootstrap",
"main": "./lib/index.js",
"scripts": {
"prepublish": "npm run build",
"build": "babel src --out-dir=lib && webpack && COMPRESS=1 webpack && npm run bower-prepare",
"build": "babel src --out-dir=lib && webpack && webpack -p",
"test": "npm run lint && karma start --single-run",
"tdd": "karma start",
"visual-test": "open http://localhost:8080/public/visual#/ && webpack-dev-server --config webpack.test.config.babel.js",
"lint": "eslint ./",
"bower-prepare": "babel-node scripts/bower-prepare.js",
"patch": "release patch",
"minor": "release minor",
"major": "release major"
"visual-test": "open http://localhost:8080/ && webpack-dev-server --config webpack.visual.config.babel.js",
"lint": "eslint *.babel.js src tests",
"release": "release"
},
"repository": {
"type": "git",
@@ -34,48 +31,53 @@
},
"homepage": "https://github.com/react-bootstrap/react-router-bootstrap",
"peerDependencies": {
"react-bootstrap": ">=0.22.4",
"react-router": ">=0.13.1"
"react": ">=0.13.0 || >=0.14.0-rc1",
"react-router": ">=1.0.0-rc1"
},
"devDependencies": {
"babel": "^5.5.6",
"babel-core": "^5.5.6",
"babel-eslint": "^4.0.5",
"babel-loader": "^5.1.4",
"bootstrap": "^3.3.1",
"chai": "^3.0.0",
"colors": "^1.1.2",
"css-loader": "^0.15.3",
"eslint": "^1.0.0",
"eslint-config-airbnb": "0.0.7",
"eslint-plugin-babel": "^1.0.0",
"eslint-plugin-mocha": "^0.4.0",
"eslint-plugin-react": "^3.1.0",
"karma": "^0.13.3",
"babel": "^5.8.23",
"babel-core": "^5.8.24",
"babel-eslint": "^4.1.2",
"babel-loader": "^5.3.2",
"bootstrap": "^3.3.5",
"css-loader": "^0.18.0",
"es5-shim": "^4.1.13",
"eslint": "1.3.x",
"eslint-config-airbnb": "0.0.8",
"eslint-plugin-babel": "^2.1.1",
"eslint-plugin-mocha": "^0.5.1",
"eslint-plugin-react": "^3.3.2",
"file-loader": "^0.8.4",
"history": "^1.9.1",
"html-webpack-plugin": "^1.6.1",
"karma": "^0.13.9",
"karma-cli": "^0.1.0",
"karma-mocha": "^0.2.0",
"karma-mocha-reporter": "^1.0.2",
"karma-phantomjs-launcher": "^0.2.0",
"karma-webpack": "^1.5.0",
"karma-mocha-reporter": "^1.1.1",
"karma-phantomjs-launcher": "^0.2.1",
"karma-sinon-chai": "^1.1.0",
"karma-sourcemap-loader": "^0.3.5",
"karma-webpack": "^1.7.0",
"less": "^2.5.1",
"less-loader": "^2.2.0",
"lodash": "^3.10.0",
"mocha": "^2.1.0",
"mt-changelog": "^0.6.1",
"mocha": "^2.3.2",
"mt-changelog": "^0.6.2",
"node-libs-browser": "^0.5.2",
"phantomjs": "^1.9.13",
"react": ">0.10.0",
"react-bootstrap": ">=0.22.4",
"react-router": ">=0.13.1",
"release-script": "^0.2.1",
"shelljs": "^0.5.1",
"phantomjs": "^1.9.18",
"react": "^0.14.0-rc1",
"react-bootstrap": "^0.25.100-react-pre.1",
"react-dom": "^0.14.0-rc1",
"react-router": "^1.0.0-rc1",
"release-script": "^0.2.7",
"style-loader": "^0.12.3",
"url-loader": "^0.5.6",
"webpack": "^1.4.15",
"webpack-dev-server": "^1.7.0",
"yargs": "^3.15.0"
"webpack": "^1.12.1",
"webpack-dev-server": "^1.10.1",
"yargs": "^3.25.0"
},
"files": [
"README",
"CHANGELOG.md",
"lib"
],
"release-script": {
70 changes: 0 additions & 70 deletions scripts/bower-prepare.js

This file was deleted.

20 changes: 0 additions & 20 deletions src/ButtonLink.js

This file was deleted.

11 changes: 11 additions & 0 deletions src/IndexLinkContainer.js
Original file line number Diff line number Diff line change
@@ -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 changes: 53 additions & 0 deletions src/LinkContainer.js
Original file line number Diff line number Diff line change
@@ -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 changes: 0 additions & 83 deletions src/LinkMixin.js

This file was deleted.

20 changes: 0 additions & 20 deletions src/ListGroupItemLink.js

This file was deleted.

23 changes: 0 additions & 23 deletions src/MenuItemLink.js

This file was deleted.

20 changes: 0 additions & 20 deletions src/NavItemLink.js

This file was deleted.

20 changes: 0 additions & 20 deletions src/PageItemLink.js

This file was deleted.

7 changes: 0 additions & 7 deletions src/RouterOverlayTrigger.js

This file was deleted.

20 changes: 0 additions & 20 deletions src/ThumbnailLink.js

This file was deleted.

9 changes: 2 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 8 deletions tests/.eslintrc
Original file line number Diff line number Diff line change
@@ -11,13 +11,7 @@
"mocha"
],
"rules": {
"func-names": 0,
"no-alert": 0,
"no-script-url": 0,
"no-unused-expressions": 0,
"react/no-multi-comp": 0,
"react/prop-types": 0,
"react/sort-comp": 0,
"mocha/no-exclusive-tests": 2
"mocha/no-exclusive-tests": 2,
"react/no-multi-comp": 0
}
}
166 changes: 0 additions & 166 deletions tests/ButtonLink.spec.js

This file was deleted.

56 changes: 56 additions & 0 deletions tests/IndexLinkContainer.spec.js
Original file line number Diff line number Diff line change
@@ -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 changes: 223 additions & 0 deletions tests/LinkContainer.spec.js
Original file line number Diff line number Diff line change
@@ -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 changes: 0 additions & 164 deletions tests/ListGroupItemLink.spec.js

This file was deleted.

168 changes: 0 additions & 168 deletions tests/MenuItemLink.spec.js

This file was deleted.

190 changes: 0 additions & 190 deletions tests/NavItemLink.spec.js

This file was deleted.

103 changes: 0 additions & 103 deletions tests/PageItemLink.spec.js

This file was deleted.

13 changes: 0 additions & 13 deletions tests/RouterOverlayTrigger.spec.js

This file was deleted.

31 changes: 0 additions & 31 deletions tests/TestHandlers.js

This file was deleted.

103 changes: 0 additions & 103 deletions tests/ThumbnailLink.spec.js

This file was deleted.

21 changes: 0 additions & 21 deletions tests/bower-imports-module.spec.js

This file was deleted.

21 changes: 3 additions & 18 deletions tests/index.js
Original file line number Diff line number Diff line change
@@ -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 changes: 0 additions & 31 deletions tests/phantom-shims.js

This file was deleted.

2 changes: 0 additions & 2 deletions tests/visual.js

This file was deleted.

71 changes: 40 additions & 31 deletions tests/visual/ButtonVisual.js
Original file line number Diff line number Diff line change
@@ -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'>&lt;-- 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 changes: 72 additions & 36 deletions tests/visual/ListGroupItemVisual.js
Original file line number Diff line number Diff line change
@@ -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'>&lt;-- 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 changes: 0 additions & 42 deletions tests/visual/MenuItemVisual.js

This file was deleted.

56 changes: 28 additions & 28 deletions tests/visual/NavItemVisual.js
Original file line number Diff line number Diff line change
@@ -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'>&lt;-- 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 changes: 0 additions & 28 deletions tests/visual/PageItemVisual.js

This file was deleted.

21 changes: 0 additions & 21 deletions tests/visual/ThumbnailVisual.js

This file was deleted.

29 changes: 0 additions & 29 deletions tests/visual/app.js

This file was deleted.

29 changes: 10 additions & 19 deletions tests/visual/home.js
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions tests/visual/index.js
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 39 deletions webpack.config.babel.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,24 @@
import path from 'path';
import webpack from 'webpack';
import yargs from 'yargs';

const plugins = [];

if (process.env.COMPRESS) {
plugins.push(
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
);
}
const {optimizeMinimize} = yargs.alias('p', 'optimize-minimize').argv;
const nodeEnv = optimizeMinimize ? 'production' : 'development';

export default {
entry: {
'ReactRouterBootstrap': './src/index.js'
},

output: {
path: './lib',
filename: process.env.COMPRESS ? '[name].min.js' : '[name].js',
filename: optimizeMinimize ? '[name].min.js' : '[name].js',
library: 'ReactRouterBootstrap',
libraryTarget: 'umd'
},

module: {
loaders: [
{
test: /\.js/,
loaders: [
'babel',
path.join(__dirname, 'webpack/bower-imports-loader.js')
],
exclude: /node_modules/ }
{test: /\.js$/, loader: 'babel', exclude: /node_modules/}
]
},

devtool: process.env.COMPRESS && 'source-map',

externals: [
{
'react': {
@@ -55,20 +35,12 @@ export default {
commonjs: 'react-router',
amd: 'react-router'
}
},
{
'react-bootstrap': {
root: 'ReactBootstrap',
commonjs2: 'react-bootstrap',
commonjs: 'react-bootstrap',
amd: 'react-bootstrap'
}
}
],

node: {
buffer: false
},

plugins
plugins: [
new webpack.DefinePlugin({
'process.env': {'NODE_ENV': JSON.stringify(nodeEnv)}
})
],
devtool: optimizeMinimize ? 'source-map' : null
};
23 changes: 5 additions & 18 deletions webpack.test.config.babel.js
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions webpack.visual.config.babel.js
Original file line number Diff line number Diff line change
@@ -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 changes: 0 additions & 7 deletions webpack/bower-imports-loader.js

This file was deleted.

0 comments on commit ac500c8

Please sign in to comment.