JSFiddle - React, Tailwind, and code Playground
by Arnold Daniels
HTML
<div class="calculator">
<div class="screen">
<div class="formula"></div>
<div class="result"></div>
</div>
<div class="buttons">
<button class="fn" fn="clear_all">CE</button>
<button class="fn" fn="clear">C</button>
<button class="fn" fn="del">⌫</button>
<button class="fn op">÷</button>
<button class="num">7</button>
<button class="num">8</button>
<button class="num">9</button>
<button class="fn op">×</button>
<button class="num">4</button>
<button class="num">5</button>
<button class="num">6</button>
<button class="fn op">–</button>
<button class="num">1</button>
<button class="num">2</button>
<button class="num">3</button>
<button class="fn op">+</button>
<button class="num op" fn="inv">±</button>
<button class="num">0</button>
<button class="num">.</button>
<button class="res" fn="result">=</button>
</div>
</div>
SCSS
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;600&display=swap');
.calculator {
width: 240px;
box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.25);
margin: 20px auto;
font-family: "Roboto", Serif;
.screen {
height: 90px;
padding: 20px;
background-color: #78909C;
color: #FFFFFF;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 5px;
.formula {
text-align: right;
font-size: 14px;
}
.result {
text-align: right;
font-weight: 600;
font-size: 26px;
height: 26px;
overflow: hidden;
}
}
.buttons {
display: flex;
flex-flow: row wrap;
}
button {
border: none;
width: 60px;
height: 60px;
font-size: 16px;
color: #5A747F;
cursor: pointer;
border-left: 1px solid #FFFFFF;
border-bottom: 1px solid #FFFFFF;
&.fn {
background-color: #E4E9EC;
}
&.num {
background-color: #FFFFFF;
border-color: #E4E9EC;
}
&.op {
font-size: 20px;
}
&.res {
background-color: #FF6567;
color: #FFFFFF;
font-size: 24px;
border: none;
transform: scale(1.1);
}
&:nth-child(4n+1) {
border-left: none;
}
}
}
JavaScript
for (const calculator of document.getElementsByClassName('calculator')) {
initCalculator(calculator);
}
function initCalculator(calculator) {
const formulaScreen = calculator.querySelector('.formula');
const resultScreen = calculator.querySelector('.result');
let inResultState = false;
const operators = new Map([
['+', '+'],
['-', '-'],
['\u2013', '-'],
['\u00d7', '*'],
['\u00f7', '/'],
]);
const functions = {
clear_all: () => {
formulaScreen.innerText = "";
resultScreen.innerText = "";
},
clear: () => {
if (inResultState) functions.clear_all();
resultScreen.innerText = "";
},
del: () => {
if (inResultState) functions.clear_all();
resultScreen.innerText = resultScreen.innerText.slice(0, -1);
},
inv: () => {
if (inResultState) formulaScreen.innerText = "";
resultScreen.innerText = resultScreen.innerText.startsWith('-')
? resultScreen.innerText.slice(1)
: '-' + resultScreen.innerText;
},
result: () => {
if (inResultState) formulaScreen.innerText = "";
formulaScreen.innerText = resultScreen.innerText !== ""
? formulaScreen.innerText + ' ' + resultScreen.innerText
: formulaScreen.innerText.replace(/\D$/u, '');
const code = formulaScreen.innerText
.replace(/[^\d\s\.]/g, char => operators.get(char))
.replace(/(^|\s)\./g, " 0.");
resultScreen.innerText = Function(`return (${code}) || ''`)();
}
}
const appendOperator = operator => {
if (formulaScreen.innerText === "" && resultScreen.innerText === "") return;
const formula = resultScreen.innerText === "" ? formulaScreen.innerText.replace(/\D$/u, '') : formulaScreen.innerText;
formulaScreen.innerText = (inResultState ? '' : formula + ' ') + resultScreen.innerText.replace(/\.$/, '') + ' ' + operator;
resultScreen.innerText = "";
}
calculator.addEventListener("click", event => {
const fn =...