Skip to content

Commit

Permalink
Merge pull request react-bootstrap#1465 from react-bootstrap/bootstra…
Browse files Browse the repository at this point in the history
…p-mixin

remove bootstrap mixin
  • Loading branch information
jquense committed Nov 6, 2015
2 parents 3bb42f2 + 0f3ee3e commit fac0095
Show file tree
Hide file tree
Showing 53 changed files with 955 additions and 695 deletions.
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"stage": 1,
"optional": ["runtime"],
"loose": ["all"]
"loose": ["all"],
"plugins": ["object-assign"]
}
13 changes: 11 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,23 @@
"comma-dangle": 0,
"eqeqeq": [2, "allow-null"],
"id-length": 0,
"no-eq-null": 0,
"one-var": [2, { "initialized": "never" }],
"prefer-const": 0,
"no-param-reassign": 0,
"no-this-before-super": 2,
"babel/object-shorthand": 2,
"react/jsx-boolean-value": 2,
"react/jsx-no-duplicate-props": 2,
"react/prop-types": [2, { "ignore": [ "children", "className", "style" ] }],
"react/sort-comp": 0
"react/sort-comp": 0,
"react/prop-types": [2, { "ignore": [
"children",
"className",
"style",
"bsStyle",
"bsClass",
"bsSize"
]
}],
}
}
61 changes: 54 additions & 7 deletions docs/generate-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import glob from 'glob';
import fsp from 'fs-promise';
import promisify from '../tools/promisify';
import marked from 'marked';
import defaultDescriptions from './src/defaultPropDescriptions';

marked.setOptions({
xhtml: true
Expand All @@ -18,6 +19,7 @@ let cleanDoclets = desc => {

let cleanDocletValue = str => str.trim().replace(/^\{/, '').replace(/\}$/, '');

let quote = str => str && `'${str}'`;

let isLiteral = str => (/^('|")/).test(str.trim());

Expand All @@ -26,10 +28,11 @@ let isLiteral = str => (/^('|")/).test(str.trim());
*
* @param {ComponentMetadata|PropMetadata} obj
*/
function parseDoclets(obj) {
obj.doclets = metadata.parseDoclets(obj.desc || '') || {};
obj.desc = cleanDoclets(obj.desc || '');
obj.descHtml = marked(obj.desc || '');
function parseDoclets(obj, propName) {
let desc = obj.desc || defaultDescriptions[propName] || '';
obj.doclets = metadata.parseDoclets(desc) || {};
obj.desc = cleanDoclets(desc);
obj.descHtml = marked(desc);
}

/**
Expand Down Expand Up @@ -61,7 +64,7 @@ function applyPropDoclets(props, propName) {

// Use @required to mark a prop as required
// useful for custom propTypes where there isn't a `.isRequired` addon
if ( doclets.required) {
if (doclets.required) {
prop.required = true;
}

Expand All @@ -71,27 +74,71 @@ function applyPropDoclets(props, propName) {
}
}

function addBootstrapPropTypes(Component, componentData) {
let propTypes = Component.propTypes || {};
let defaultProps = Component.defaultProps || {};

function bsPropInfo(propName) {
let props = componentData.props;
let prop = propTypes[propName];

if (prop && !props[propName]) {
let values = prop._values || [];

props[propName] = {
desc: '',
defaultValue: quote(defaultProps[propName]),
type: {
name: 'enum',
value: values.map( v => `"${v}"`),
}
};
}
}

bsPropInfo('bsStyle');
bsPropInfo('bsSize');

if (propTypes.bsClass) {
componentData.props.bsClass = {
desc: '',
defaultValue: quote(defaultProps.bsClass),
type: { name: 'string' }
};
}
}

export default function generate(destination, options = { mixins: true, inferComponent: true }) {
return globp(__dirname + '/../src/**/*.js') // eslint-disable-line no-path-concat
.then( files => {
let results = files.map(
filename => fsp.readFile(filename).then(content => metadata(content, options)) );
filename => fsp.readFile(filename).then(content => metadata(content, options)));

return Promise.all(results)
.then( data => {
let result = {};

data.forEach(components => {
Object.keys(components).forEach(key => {
let Component;

try {
// require the actual component to inspect props we can only get a runtime
Component = require('../src/' + key);
} catch (e) {} //eslint-disable-line

const component = components[key];

if (Component) {
addBootstrapPropTypes(Component, component);
}

parseDoclets(component);

Object.keys(component.props).forEach( propName => {
const prop = component.props[propName];

parseDoclets(prop);
parseDoclets(prop, propName);
applyPropDoclets(component.props, propName);
});
});
Expand Down
19 changes: 10 additions & 9 deletions docs/src/ComponentsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,16 +225,17 @@ const ComponentsPage = React.createClass({
<h1 className="page-header"><Anchor id="menu-item">Menu Item</Anchor> <small> MenuItem</small></h1>
<p>This is a component used in other components (see <a href="buttons">Buttons</a>, <a href="#navbars">Navbars</a>).</p>
<p>It supports the basic anchor properties <code>href</code>, <code>target</code>, <code>title</code>.</p>
<p>It also supports different properties of the normal Bootstrap MenuItem.
<ul>
<li><code>header</code>: To add a header label to sections</li>
<li><code>divider</code>: Adds an horizontal divider between sections</li>
<li><code>disabled</code>: shows the item as disabled, and prevents the onclick</li>
<li><code>eventKey</code>: passed to the callback</li>
<li><code>onSelect</code>: a callback that is called when the user clicks the item.</li>
</ul>
<p>The callback is called with the following arguments: <code>eventKey</code>, <code>href</code> and <code>target</code></p>
<p>
It also supports different properties of the normal Bootstrap MenuItem.
</p>
<ul>
<li><code>header</code>: To add a header label to sections</li>
<li><code>divider</code>: Adds an horizontal divider between sections</li>
<li><code>disabled</code>: shows the item as disabled, and prevents the onclick</li>
<li><code>eventKey</code>: passed to the callback</li>
<li><code>onSelect</code>: a callback that is called when the user clicks the item.</li>
</ul>
<p>The callback is called with the following arguments: <code>eventKey</code>, <code>href</code> and <code>target</code></p>
<ReactPlayground codeText={Samples.MenuItem} />

<h3><Anchor id="menu-item-props">Props</Anchor></h3>
Expand Down
2 changes: 1 addition & 1 deletion docs/src/PropTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const PropTable = React.createClass({
render() {
let propsData = this.propsData;

if ( !Object.keys(propsData).length) {
if (!Object.keys(propsData).length) {
return <span/>;
}

Expand Down
7 changes: 7 additions & 0 deletions docs/src/defaultPropDescriptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

export default {
bsClass: 'Base css class name and prefix for the Component. Generally one should only change `bsClass` ' +
'if they are providing new, non bootstrap, css styles for a component.',
bsStyle: 'Component visual or contextual style variants.',
bsSize: 'Component size variations.'
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"babel-core": "^5.8.25",
"babel-eslint": "^4.1.3",
"babel-loader": "^5.3.2",
"babel-plugin-object-assign": "^1.2.1",
"bootstrap": "^3.3.5",
"brfs": "^1.4.1",
"chai": "^3.3.0",
Expand Down Expand Up @@ -116,11 +117,12 @@
"babel-runtime": "^5.8.25",
"classnames": "^2.1.5",
"dom-helpers": "^2.4.0",
"invariant": "^2.1.2",
"keycode": "^2.1.0",
"lodash-compat": "^3.10.1",
"react-overlays": "^0.5.0",
"uncontrollable": "^3.1.3",
"react-prop-types": "^0.3.0",
"uncontrollable": "^3.1.3",
"warning": "^2.1.0"
},
"release-script": {
Expand Down
17 changes: 9 additions & 8 deletions src/Alert.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import classNames from 'classnames';
import BootstrapMixin from './BootstrapMixin';
import bootstrapUtils, { bsStyles, bsClass } from './utils/bootstrapUtils';
import { State } from './styleMaps';

const Alert = React.createClass({
mixins: [BootstrapMixin],
let Alert = React.createClass({

propTypes: {
onDismiss: React.PropTypes.func,
Expand All @@ -13,8 +13,6 @@ const Alert = React.createClass({

getDefaultProps() {
return {
bsClass: 'alert',
bsStyle: 'info',
closeLabel: 'Close Alert'
};
},
Expand Down Expand Up @@ -43,10 +41,10 @@ const Alert = React.createClass({
},

render() {
let classes = this.getBsClassSet();
let classes = bootstrapUtils.getClassSet(this.props);
let isDismissable = !!this.props.onDismiss;

classes['alert-dismissable'] = isDismissable;
classes[bootstrapUtils.prefix(this.props, 'dismissable')] = isDismissable;

return (
<div {...this.props} role="alert" className={classNames(this.props.className, classes)}>
Expand All @@ -68,4 +66,7 @@ const Alert = React.createClass({
}
});

export default Alert;

export default bsStyles(State.values(), State.INFO,
bsClass('alert', Alert)
);
7 changes: 4 additions & 3 deletions src/Badge.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ValidComponentChildren from './utils/ValidComponentChildren';
import classNames from 'classnames';

import tbsUtils from './utils/bootstrapUtils';

const Badge = React.createClass({
propTypes: {
Expand All @@ -10,7 +10,8 @@ const Badge = React.createClass({

getDefaultProps() {
return {
pullRight: false
pullRight: false,
bsClass: 'badge'
};
},

Expand All @@ -24,7 +25,7 @@ const Badge = React.createClass({
render() {
let classes = {
'pull-right': this.props.pullRight,
'badge': this.hasContent()
[tbsUtils.prefix(this.props)]: this.hasContent()
};
return (
<span
Expand Down
55 changes: 0 additions & 55 deletions src/BootstrapMixin.js

This file was deleted.

23 changes: 15 additions & 8 deletions src/Button.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react';
import classNames from 'classnames';
import BootstrapMixin from './BootstrapMixin';
import elementType from 'react-prop-types/lib/elementType';

const types = ['button', 'reset', 'submit'];

const Button = React.createClass({
mixins: [BootstrapMixin],
import bootstrapUtils, { bsStyles, bsSizes, bsClass } from './utils/bootstrapUtils';
import { Sizes, State, DEFAULT, PRIMARY, LINK } from './styleMaps';

const ButtonStyles = State.values().concat(DEFAULT, PRIMARY, LINK);

let Button = React.createClass({

propTypes: {
active: React.PropTypes.bool,
Expand All @@ -32,21 +35,21 @@ const Button = React.createClass({
return {
active: false,
block: false,
bsClass: 'button',
bsStyle: 'default',
disabled: false,
navItem: false,
navDropdown: false
};
},

render() {
let classes = this.props.navDropdown ? {} : this.getBsClassSet();
let classes = this.props.navDropdown ? {} : bootstrapUtils.getClassSet(this.props);
let renderFuncName;

let blockClass = bootstrapUtils.prefix(this.props, 'block');

classes = {
active: this.props.active,
'btn-block': this.props.block,
[blockClass]: this.props.block,
...classes
};

Expand Down Expand Up @@ -104,4 +107,8 @@ const Button = React.createClass({

Button.types = types;

export default Button;
export default bsStyles(ButtonStyles, DEFAULT,
bsSizes([Sizes.LARGE, Sizes.SMALL, Sizes.XSMALL],
bsClass('btn', Button)
)
);
Loading

0 comments on commit fac0095

Please sign in to comment.