<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.1/math.min.js" crossorigin="anonymous"></script>
<div id ="root"</div>
#root {
	height: 100vh;
	width : 100%;
	vertical-align: center;
	z-index: 100;
	background-color: #7cb342;
}

.calculator {
	
}


.screenRow {
	min-height: 30px;
	background-color: #4b830d;
	color: white;
	font-weight: bold;
	font-size: 1.2rem;
	padding: 5px;
}

.mainScreen {
	
}

.secondaryScreen {
	
}

.btnContainer {
	display:flex;
	flex: auto;
	 border:0px solid transparent;
}

.btn {
	border-raiuds : 0 rem !important;
	color: grey;
	font-weight: bold;
	font-size: 1.4rem;
}

.btnContainerFill {
	display:flex;
	flex-direction: row;
  align-items: stretch;
	flex-grow: 3;
}

.btnNormal {
	background-color: #aee571;
	flex: 1 0 auto;
	width: 50px;
	margin: 0;
	 border:0px solid transparent;
}

.btnFill {
	flex: 1 0 auto;
	width: 50px;
}

.btnLarge {
	background-color: #aee571;
	flex: 1 0 auto;
	width: 100px;
}

.flexcontainer {
   display: -webkit-flex;
   display: flex;
   -webkit-flex-direction: row;
   flex-direction: row;
   -webkit-align-items: center;
   align-items: center;
   -webkit-justify-content: center;
   justify-content: center;
	height: 100vh;
}
function Screen(props) {
	return (<div className="screen">
		<div className="screenRow text-right">{props.operation} {!props.result ? "" : props.result}
					</div>
					<div className="screenRow text-right">{props.function}{!props.result ? "" : "=" + props.result}
					</div>
					</div>
				 );
}

class CalcButton extends React.Component {
	render() {
		return(
			<button type="button" onClick={this.props.operation} className="btn btn-secondary btnNormal">{this.props.operatorImg}</button>
		)
	};			
}

class Calculator extends React.Component {
	constructor(props){
		super(props);
		
		this.state= {
			operation: "0",
			function: "",
			result: "",
			digitsLimit: 20
		};
		
		
	}
	
	lastCharacterIsNumber(func) {
		if(!Number(func.toString().substr(func.length - 1)))
			{
				return true;
			} 
		return false;
	}
	
	validateOperationNumber(operation:string, element: string) {
		if(operation.length >= this.state.digitsLimit)
			{
				return "0";
			}
		if(Number(operation) === 0)
			{
				return element;
			}
		/*if(!Number(operation + element))
			{
				return "";
			}*/
		return operation.toString() + element.toString();
	}
	
	validateFunctionNumber(func:string, result: string, element: string) {
		if(result )
			{
				return element;
			}
		if(func.length >= this.state.digitsLimit)
			{
				return "";
			}
		if(Number(func) === 0)
			{
				return element;
			}
		return func.toString() + element.toString();
	}
	
		validateOperationOperator(operation:string, element: string) {
		if(operation.length === 0)
			{
				return "";
			}
			if(this.lastCharacterIsNumber(operation))
			{
				return operation;
			}
		return operation.toString() + element.toString();
	}
	
	validateFunctionOperator(func:string, result: string, element: string) {
		
		if(func.length === 0)
			{
				return "";
			}
		
		if(this.lastCharacterIsNumber(func))
			{
				return func;
			}
		
		if(result)
			{
				return result.toString() + element;
			}
		return func.toString() + element.toString();
	}
	
	addNumber(element){
		this.setState((prevState, props) => {
			let operation = this.validateOperationNumber(prevState.operation, element);
			let func = this.validateFunctionNumber(prevState.function, prevState.result, element);
		return {
			operation: operation,
			function: func,
			result: !prevState.result ? prevState.result : ""
					 };
	});
		}
	
	addOperator(element){
		this.setState((prevState, props) => {
			let operation = this.validateOperationOperator(prevState.operation, element);
			let func = this.validateFunctionOperator(prevState.function, prevState.result, element);
		return {
			operation: operation,
			function: func,
			result: !prevState.result ? prevState.result : ""
					 };
	});
		}
	
	getResult(){
			let result = math.eval(this.state.function);
	
			this.setState({result: result, operation: ""});
		}
	
	delete(){
			this.setState({operation: "0",
										result: this.state.result && "",
										 function: this.state.result && ""});
		}
	
	deleteAll(){
			this.setState({operation:"0", function: "", result: ""});
		}
	
	render() {
		return (<div className="calculator">
						<div className="">
						<Screen operation = {this.state.operation} function= {this.state.function} result ={this.state.result}> </Screen>
						</div>
						<div className="btnContainer btn-group">
						<CalcButton operation={() => this.deleteAll()} operatorImg="AC"></CalcButton>
						<CalcButton operation={() => this.delete()} operatorImg="CE"></CalcButton>
						<CalcButton operation={() => this.addOperator("/")} operatorImg="/"></CalcButton>
						<CalcButton operation={() => this.addOperator("*")} operatorImg="*"></CalcButton>
						</div>
						<div className="btnContainer btn-group">
						<CalcButton operation={() => this.addNumber(7)} operatorImg="7"></CalcButton>
						<CalcButton operation={() => this.addNumber(8)} operatorImg="8"></CalcButton>
						<CalcButton operation={() => this.addNumber(9)} operatorImg="9"></CalcButton>
						<CalcButton operation={() => this.addOperator("-")} operatorImg="-"></CalcButton>
						</div>
						<div className="btnContainer btn-group">
							<CalcButton operation={() => this.addNumber(4)} operatorImg="4"></CalcButton>
							<CalcButton operation={() => this.addNumber(5)} operatorImg="5"></CalcButton>
							<CalcButton operation={() => this.addNumber(6)} operatorImg="6"></CalcButton>
							<CalcButton operation={() => this.addOperator("+")} operatorImg="+"></CalcButton>
						</div>
						<div className="btnContainer btn-group">
							<CalcButton operation={() => this.addNumber(1)} operatorImg="1"></CalcButton>
							<CalcButton operation={() => this.addNumber(2)} operatorImg="2"></CalcButton>
							<CalcButton operation={() => this.addNumber(3)} operatorImg="3"></CalcButton>
						<CalcButton operation={() => this.getResult()} operatorImg="="></CalcButton>							
						</div>
						<div className="btnContainerFill btn-group">
							<CalcButton operation={() => this.addNumber(0)} operatorImg="0"></CalcButton>
							<CalcButton operation={() => this.addNumber(".")} operatorImg="."></CalcButton>
						
						<button className="btn btnLarge " disabled></button>
						</div>
						</div>
					 );
	}
}

ReactDOM.render(<div className="flexcontainer text-center"><Calculator></Calculator></div>,
							 document.getElementById("root"));
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js