Bootstrap ships classes for cross-cutting concerns, e.g. size (lg, md, sm) and style (default, primary, success, etc).
One soluton for a React.js component library is to make components for all combinations. Here’s a suggestion for composing the classes via mixins.
The main idea is to have a set of properties, e.g. bsSize, bsStyle, and construct the className string from them:
var ClassNameHelper = { extendClassName: function() { var bsClass = this.props.bsClass; var bsStyle = this.props.bsStyle; var bsSize = this.props.bsSize; var prefix = this.props.bsClass + '-'; var classes = {} // TODO: Check there are no conflicting values in this.props.className if(this.props.bsClass) classes[this.props.bsClass] = true; if(this.props.bsSize) classes[prefix + this.props.bsSize] = true; if(this.props.bsStyle) classes[prefix + this.props.bsStyle] = true; // Merge with previous classes if(this.props.className) this.props.className.split(' ').map( function(klass){ classes[klass] = true; } ); // This produces a ' ' delineated string // from all members of classes that evaluate as truthy return React.addons.classSet(classes); }, };
The mixin would be used in the component library like this:
var Button = React.createClass({ mixins = [ClassNameHelper], getDefaultProps: function() {return {bsClass: 'btn'};}, render: function() { return this.transferPropsTo( <button className={this.extendClassName()}> {this.props.children} </button> ); } });
Users could pass in the arguments as props:
<Button bsSize="sm" bsStyle="default">Sign Up!</Button>
I prefer creating ad hoc asset components though, so I think there should also be a set of mixins:
var Large = {getDefaultProps: function() { return {bsSize: 'lg'};}}; var Medium = {getDefaultProps: function() { return {bsSize: 'md'};}}; var Small = {getDefaultProps: function() { return {bsSize: 'sm'};}}; var Default = {getDefaultProps: function() { return {bsStyle: 'default'};}}; var Primary = {getDefaultProps: function() { return {bsStyle: 'primary'};}}; var Success = {getDefaultProps: function() { return {bsStyle: 'success'};}}; var Info = {getDefaultProps: function() { return {bsStyle: 'info'};}}; var Warning = {getDefaultProps: function() { return {bsStyle: 'warning'};}}; var Danger = {getDefaultProps: function() { return {bsStyle: 'danger'};}}; var Link = {getDefaultProps: function() { return {bsStyle: 'link'};}}; var SignupButton = React.createClass({ mixins = [Large, Success, Button], render: function() {return <Button>Sign Up Now!</Button>;} });
If we can get the design right, I think that a good Bootstrap component library could be a very popular resource.