React.js Feature Grid
HTML
<script src="//unpkg.com/[email protected]/dist/react-with-addons.js"></script>
<script src="//unpkg.com/[email protected]/dist/JSXTransformer.js"></script>
<script src="//fb.me/react-js-fiddle-integration.js"></script>
CSS
@import url("//fonts.googleapis.com/css?family=Noto+Sans:400,700,400italic,700italic");
/*********** DEFAULT BODY STYLING **********/
body {
font-family:"Noto Sans";
font-size: 12px;
line-height: 1.0;
border-spacing: 0px;
}
table.feature-tbl {
width:100%;
}
a.feature-link {
color: #337EC6;
/* $blue_link */
text-decoration: none;
}
/********** DEFAULT TABLE STYLING **********/
table.feature-tbl {
font-size: 12px;
line-height: 1.4;
border-spacing: 0px;
}
table.feature-tbl tr {
height: 32px;
}
table.feature-tbl td {
padding: 4px;
vertical-align: top;
border-bottom: 1px solid #D6D6D6;
/* $grey3 */
}
table.feature-tbl th {
font-weight: normal;
color: #000;
/* black */
border-bottom: 2px solid #D6D6D6;
/* $grey3 */
vertical-align: bottom;
text-align: left;
padding: 4px;
}
/***** COMMENT (Do NOT use this code as reference to production *****/
.pbar.container {
width: 100px;
float: left;
height: 20px;
}
.pbar.container .bar {
font-size: 12px;
line-height: 1.0;
width: 100px;
background: #E6E6E6;
/* $grey2 */
position: absolute;
float: left;
height: 20px;
border-radius: 2px;
}
.pbar.container .bar:hover {
cursor: pointer;
}
.pbar.container .meter {
float: left;
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
text-decoration: none;
position: absolute;
height: 20px;
}
.pbar.container .percent {
text-transform: uppercase;
font-family:"ProximaNovaSemiBold", sans-serif;
color: #444;
/* $grey8 */
font-size: .8em;
/* 13px */
text-align: center;
float: left;
position: absolute;
width: 100px;
padding: 5px 0px;
}
.meter.notStarted {
background: #E6E6E6;
/* $grey2 */
}
.meter.onTrack {
background: #8DC63F;
/* $lime */
}
.meter.risk {
background: #FAD200;
/*...
JavaScript 1.7
/** @jsx React.DOM */
var ProgressBar = React.createClass({
propTypes: {
percentComplete: React.PropTypes.number.isRequired,
label: React.PropTypes.string,
disposition: React.PropTypes.oneOf(['notStarted', 'onTrack','risk', 'late', 'complete'])
},
render: function() {
var text = this.props.percentComplete + "%"
if (this.props.label) {
text += " / " + this.props.label;
}
var barStyle = {width:this.props.percentComplete+"%"};
var meterClass = "meter " + (this.props.disposition || "")
return <div className="pbar container">
<div className="bar">
<div style={barStyle} className={meterClass}></div>
<div className="percent">{text}</div>
</div>
</div>;
}
});
var FeatureRow = React.createClass({
propTypes: {
feature: React.PropTypes.object.isRequired
},
render: function() {
var feature = this.props.feature;
return <tr>
<td className="drag"></td>
<td>
<a href="#" className="feature-link">{feature.formattedId}</a>
</td>
<td>{feature.name}</td>
<td>
<ProgressBar percentComplete={feature.percentComplete} disposition={feature.dispo} label="On Track" />
</td>
<td>On Track</td>
</tr>;
}
});
var FeatureTable = React.createClass({
propTypes: {
features: React.PropTypes.array.isRequired
},
render: function() {
var rows = [];
features.forEach(function(feature){
rows.push(<FeatureRow feature={feature} />);
});
return <table className="feature-tbl">
<tr>
<th></th>
<th>ID</th>
<th>Name</th>
<th>% Complete</th>
<th>Status</th>
</tr>
{rows}
</table>;
}
});
var...