React/ReactJS: Dynamic Progress Bar

In this tutorial, you will be learning how to create/build your own simple progress bar in React/ReactJS and develop it as a component which looks like below.

We will build a simple horizontal progress bar which look as follows.

reactjs progress bar

Planning the Template

Our progress bar component consists of the wrapper <div className="progress-bar"> containing four child div elements, forming rows, as follows —

					
				       <div className="progress-bar">
				          <div className="value">		
				          </div>
				          <div className="scale">
				          </div>
				          <div className="bar">
				          </div>
				          <div className="legend">
				          </div>
				        </div>
					
				

The value in percent will be displayed inside the top row <div className="value">; the vertical graduation inside the second row <div className="scale">; the coloured bar inside the third row <div className="bar"> and the legend inside the bottom row <div className="legend">.

The component will be passed the following data (props) as an object argument, based on which we will develop our component.

					
						this.reading = {
							name: 'Apples',
							value: 27,
							color: '#b53471'
						};
					
				

The Component

The component receives props (this.props) which is assigned to the const called parent inside the render() method, and is structured as follows —

					
						class ProgressBar extends Component {
						  constructor(props) {
						    super(props);
						  }

						  render() {
						    const parent = this.props;
						    return (
						        <div className="progress-bar">
						          <div className="value">
						            <div style={{'color': parent.reading.color, 'width': parent.reading.value + '%'}}>
						              <span>{parent.reading.value}%</span>
						            </div>
						          </div>
						          <div className="scale">
						            <div className="graduation" style={{'color': parent.reading.color, 'width': parent.reading.value + '%'}}>
						              <span>|</span>
						            </div>
						          </div>
						          <div className="bar">
						            <div style={{'backgroundColor': parent.reading.color, 'width': parent.reading.value + '%'}}>
						            </div>
						            <div style={{'backgroundColor': '#d3d3d3', 'width': (100-parent.reading.value) + '%'}}>
						            </div>
						          </div>
						          <div className="legend">
						            <div>
						              <span className="dot" style={{'color': parent.reading.color}}>●</span>
						              <span className="label">{parent.reading.name}</span>
						            </div>
						          </div>
						        </div>
						    );
						  }
						}

						export default ProgressBar;
					
				

The Style

The corresponding CSS for the component is as below:

					
						.progress-bar {
						    margin: 20px 20%;
						}

						.progress-bar .value > div {
						    text-align: center;
						}

						.progress-bar .scale .graduation {
						    text-align: center;
						}

						.progress-bar .bar > div {
						    display: inline-block;
						    height: 10px;
						}

						.progress-bar .bar > div:first-of-type {
						    border-top-left-radius: 5px;
						    border-bottom-left-radius: 5px;
						}

						.progress-bar .bar > div:last-of-type {
						    border-top-right-radius: 5px;
						    border-bottom-right-radius: 5px;
						}

						.progress-bar .legend {
						    text-align: center;
						}

						.progress-bar .legend > div {
						    display: inline-block;
						    margin: 0 5px;
						    text-align: center;
						}

						.progress-bar .legend > div .dot {
						    font-size: 25px;
						    vertical-align: middle;
						}

						.progress-bar .legend > div .label {
						    margin-left: 2px;
						    vertical-align: middle;
						}
					
				

Upon rendering the component, we get our progress bar for the set of values passed as the object this.reading to it.

				
					this.reading = {
						name: 'Apples',
						value: 27,
						color: '#b53471'
					};

					ReactDOM.render(<ProgressBar reading={this.reading}/>, 
						document.getElementById('root'));
				
			

You can also avail the full code on CodePen.

See the Pen ReactJS Progress Bar by Dennis Gabil (@dennisgabil) on CodePen.

We will be building a multi-colour progress bar in our next tutorial.