JSFiddle - React, Tailwind, and code Playground
HTML
<div class="calc">
<div id="sum">A + B = </div>
<input type="number" placeholder="A" id="a"/>
<input type="number" placeholder="B" id="b"/>
<ul id="history" class="history">
</ul>
</div>
CSS
.calc {
display: flex;
flex-direction: column;
height: 4rem;
width: 20rem;
}
.history {
display: flex;
flex-direction: column;
list-style-type: none;
padding: 0;
margin: 0;
}
.history li {
background-color: blueviolet;
color: white;
cursor: pointer;
}
#sum {
flex: 1 0;
background-color: yellow;
}
JavaScript
let state = {
a: 0,
b: 0
}
let stateHistory = []
document.addEventListener("DOMContentLoaded", () => {
const aEl = document.getElementById('a')
const bEl = document.getElementById('b')
const historyEl = document.getElementById('history')
if (!aEl || !bEl || !historyEl) {
return;
}
aEl.addEventListener('input', (ev) => {
changestate({ type: 'add_a', value: Number(ev.target.value) })
updateUI()
})
bEl.addEventListener('input', (ev) => {
changestate({ type: 'add_b', value: Number(ev.target.value) })
updateUI()
})
historyEl.addEventListener('click', (ev) => {
if (ev.target && ev.target.nodeName === "LI") {
selectHistory(stateHistory[ev.target.dataset.index])
udateBindings()
updateUI()
}
})
updateUI()
})
function changestate(action) {
state = {...state}
switch(action.type) {
case 'add_a':
state.a = action.value
break
case 'add_b':
state.b = action.value
break
default:
}
addHistory()
}
function updateUI() {
const sumEl = document.getElementById('sum')
const historyEl = document.getElementById('history')
if (!sumEl || !historyEl) {
return
}
sumEl.innerHTML = `A + B = ${state.a + state.b}`
historyEl.innerHTML = stateHistory
.map((s, i) => `<li data-index="${i}"" >a: ${s.a}, b: ${s.b}</li>`)
.join("")
}
function addHistory() {
stateHistory.push(state)
}
function selectHistory(s) {
state = {...s}
}
function udateBindings() {
const aEl = document.getElementById('a')
const bEl = document.getElementById('b')
if (!aEl || !bEl) {
return;
}
aEl.value = state.a
bEl.value = state.b
}