Skip to content

Commit

Permalink
Merge pull request react-bootstrap#536 from tacomanator/master
Browse files Browse the repository at this point in the history
[added] convenience factories for non-JSX users in lib/factories
  • Loading branch information
dozoisch committed May 2, 2015
2 parents 5986534 + 8da11b4 commit 694113f
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 4 deletions.
10 changes: 10 additions & 0 deletions docs/src/GettingStartedPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ const Page = React.createClass({
</script>
`}</code></pre>
</div>

<h3>Without JSX</h3>
<p>If you do not use JSX and just call components as functions, you must explicitly <a href="https://facebook.github.io/react/blog/2014/10/14/introducing-react-elements.html#deprecated-auto-generated-factories">create a factory before calling it</a>. React-bootstrap provides factories for you in <code>lib/factories</code>:</p>
<div className="highlight">
<pre><code className="js">{`
var Alert = require('react-bootstrap/lib/factories').Alert;
// or
var Alert = require('react-bootstrap/lib/factories/Alert');
`}</code></pre>
</div>
</div>
<div className="bs-docs-section">
<h2 id="browser-support" className="page-header">Browser support</h2>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"scripts": {
"build": "node run-babel tools/build.js",
"test-watch": "karma start",
"test": "karma start --single-run && npm run lint && npm run build",
"test": "npm run lint && npm run build && karma start --single-run",
"lint": "eslint src test docs ie8 tools webpack karma.conf.js webpack.config.js webpack.docs.js",
"docs-build": "node run-babel tools/build.js --docs-only",
"docs": "node run-babel docs/server.js",
Expand Down
9 changes: 9 additions & 0 deletions src/templates/factory.index.js.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<% _.forEach(components, function (component) { %>
import <%= component %> from './<%= component %>';
<% }); %>

export default {
<% _.forEach(components, function (component) { %>
<%= component %>,
<% }); %>
}
4 changes: 4 additions & 0 deletions src/templates/factory.js.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import React from 'react';
import <%= name %> from '../<%= name %>';

export default React.createFactory(<%= name %>);
20 changes: 20 additions & 0 deletions test/FactoriesSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import components from '../tools/public-components';

let props = {
Glyphicon: {glyph: 'star'},
Modal: {onRequestHide: function() {}},
ModalTrigger: {modal: React.DOM.div(null)},
OverlayTrigger: {overlay: React.DOM.div(null)}
};

function createTest(component) {
let factory = require(`../lib/factories/${component}`);
describe('factories', function () {
it(`Should have a ${component} factory`, function () {
assert.ok(React.isValidElement(factory(props[component])));
});
});
}

components.map(component => createTest(component));
10 changes: 8 additions & 2 deletions tools/amd/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path';
import fsp from 'fs-promise';
import { copy } from '../fs-utils';
import { exec } from '../exec';
import generateFactories from '../generateFactories';
import { repoRoot, srcRoot, bowerRoot } from '../constants';

const packagePath = path.join(repoRoot, 'package.json');
Expand All @@ -12,6 +13,10 @@ const bowerJson = path.join(bowerRoot, 'bower.json');
const readme = path.join(__dirname, 'README.md');
const license = path.join(repoRoot, 'LICENSE');

const babelOptions = '--modules amd --optional es7.objectRestSpread';

const factoriesDestination = path.join(bowerRoot, 'factories');

function bowerConfig() {
return Promise.all([
fsp.readFile(packagePath)
Expand All @@ -27,10 +32,11 @@ export default function BuildBower() {
console.log('Building: '.cyan + 'bower module'.green);

return exec(`rimraf ${bowerRoot}`)
.then(() => fsp.mkdir(bowerRoot))
.then(() => fsp.mkdirs(factoriesDestination))
.then(() => Promise.all([
bowerConfig(),
exec(`babel --modules amd --optional es7.objectRestSpread ${srcRoot} --out-dir ${path.join(bowerRoot, 'lib')}`),
generateFactories(babelOptions, factoriesDestination),
exec(`babel ${babelOptions} ${srcRoot} --out-dir ${bowerRoot}`),
copy(readme, bowerRoot),
copy(license, bowerRoot)
]))
Expand Down
31 changes: 31 additions & 0 deletions tools/generateFactories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import _ from 'lodash';
import path from 'path';
import fsp from 'fs-promise';
import { exec } from './exec';
import { srcRoot } from './constants';
import components from './public-components';

const templatePath = path.join(srcRoot, 'templates');
const factoryTemplatePath = path.join(templatePath, 'factory.js.template');
const indexTemplatePath = path.join(templatePath, 'factory.index.js.template');

export default function generateFactories(babelOptions, destination) {

let generateCompiledFile = function (file, content) {
let outpath = path.join(destination, `${file}.js`);
return exec(`babel ${babelOptions} --out-file ${outpath} <<EOF\n ${content}`);
};

return Promise.all([
fsp.readFile(factoryTemplatePath)
.then(template => {
Promise.all(components.map(name => {
generateCompiledFile(name, _.template(template)({name: name}));
}));
}),
fsp.readFile(indexTemplatePath)
.then(template => _.template(template)({components: components}))
.then(content => generateCompiledFile('index', content))
]);

}
12 changes: 11 additions & 1 deletion tools/lib/build.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import 'colors';
import { exec } from '../exec';
import path from 'path';
import fsp from 'fs-promise';
import { srcRoot, libRoot } from '../constants';
import generateFactories from '../generateFactories';

const factoryDestination = path.join(libRoot, 'factories');
const babelOptions = '--optional es7.objectRestSpread';

export default function BuildCommonJs() {
console.log('Building: '.cyan + 'npm module'.green);

return exec(`rimraf ${libRoot}`)
.then(() => exec(`babel --optional es7.objectRestSpread ${srcRoot} --out-dir ${libRoot}`))
.then(() => fsp.mkdirs(factoryDestination))
.then(() => Promise.all([
generateFactories(babelOptions, factoryDestination),
exec(`babel ${babelOptions} ${srcRoot} --out-dir ${libRoot}`)
]))
.then(() => console.log('Built: '.cyan + 'npm module'.green));
}
11 changes: 11 additions & 0 deletions tools/public-components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import index from '../src/index';

let components = [];
Object.keys(index).forEach(function (item) {
if (index[item] instanceof React.Component.constructor) {
components.push(item);
}
});

export default components;

0 comments on commit 694113f

Please sign in to comment.