app completed
This commit is contained in:
parent
674bedb6a3
commit
bb9326edf9
46
package-lock.json
generated
46
package-lock.json
generated
@ -3768,6 +3768,11 @@
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs="
|
||||
},
|
||||
"complex.js": {
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.15.tgz",
|
||||
"integrity": "sha512-gDBvQU8IG139ZBQTSo2qvDFP+lANMGluM779csXOr6ny1NUtA3wkUnCFjlDNH/moAVfXtvClYt6G0zarFbtz5w=="
|
||||
},
|
||||
"compressible": {
|
||||
"version": "2.0.18",
|
||||
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
|
||||
@ -4627,6 +4632,11 @@
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"escape-latex": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
|
||||
"integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw=="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
@ -6337,6 +6347,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript-natural-sort": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
|
||||
"integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k="
|
||||
},
|
||||
"jest": {
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
|
||||
@ -7834,6 +7849,22 @@
|
||||
"tmpl": "1.0.5"
|
||||
}
|
||||
},
|
||||
"mathjs": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/mathjs/-/mathjs-10.4.0.tgz",
|
||||
"integrity": "sha512-2zVrKvORwxeWbewweD5NDxkTgAMvqkwmMljHUPhDPJtX4sGJEL6ugFXQN597rhH9RGtnMxNzz/+hPGIr9UEWrg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.17.2",
|
||||
"complex.js": "^2.0.15",
|
||||
"decimal.js": "^10.3.1",
|
||||
"escape-latex": "^1.2.0",
|
||||
"fraction.js": "^4.2.0",
|
||||
"javascript-natural-sort": "^0.7.1",
|
||||
"seedrandom": "^3.0.5",
|
||||
"tiny-emitter": "^2.1.0",
|
||||
"typed-function": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"mdn-data": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
|
||||
@ -9897,6 +9928,11 @@
|
||||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"seedrandom": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
||||
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
@ -10593,6 +10629,11 @@
|
||||
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
|
||||
},
|
||||
"tmpl": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
||||
@ -10707,6 +10748,11 @@
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"typed-function": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.1.0.tgz",
|
||||
"integrity": "sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ=="
|
||||
},
|
||||
"typedarray-to-buffer": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.4",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"mathjs": "^10.4.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "5.0.0",
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
import "./App.css";
|
||||
|
||||
import Calculator from "./components/Calculator";
|
||||
function App() {
|
||||
return <></>;
|
||||
return (
|
||||
<>
|
||||
<Calculator />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
90
src/components/Buttons.js
Normal file
90
src/components/Buttons.js
Normal file
@ -0,0 +1,90 @@
|
||||
import React from "react";
|
||||
import "./styles/Buttons.css";
|
||||
// import CALCULATOR_BUTTONS from "./CalculatorButtons";
|
||||
|
||||
const Buttons = ({
|
||||
inputHandler,
|
||||
clearInput,
|
||||
backspace,
|
||||
changePlusMinus,
|
||||
calculateAns,
|
||||
}) => {
|
||||
return (
|
||||
<div className="show-btn">
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
^
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
(
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
)
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
√
|
||||
</button>
|
||||
<button className="btn clr" onClick={clearInput}>
|
||||
AC
|
||||
</button>
|
||||
<button className="btn clr" onClick={backspace}>
|
||||
⌫
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
%
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
÷
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
7
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
8
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
9
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
x
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
4
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
5
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
6
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
-
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
1
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
2
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
3
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
+
|
||||
</button>
|
||||
<button className="btn exp" onClick={changePlusMinus}>
|
||||
±
|
||||
</button>
|
||||
<button className="btn" onClick={inputHandler}>
|
||||
0
|
||||
</button>
|
||||
<button className="btn exp" onClick={inputHandler}>
|
||||
.
|
||||
</button>
|
||||
<button className="btn exp" onClick={calculateAns}>
|
||||
=
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Buttons;
|
||||
144
src/components/Calculator.js
Normal file
144
src/components/Calculator.js
Normal file
@ -0,0 +1,144 @@
|
||||
import React, { useState } from "react";
|
||||
import Display from "./Display";
|
||||
import Buttons from "./Buttons";
|
||||
import "./styles/Calculator.css";
|
||||
import { evaluate, round } from "mathjs";
|
||||
|
||||
function Calculator() {
|
||||
const [input, setInput] = useState("");
|
||||
const [answer, setAnswer] = useState("");
|
||||
|
||||
//input
|
||||
const inputHandler = (event) => {
|
||||
if (answer === "Invalid Input!!") return;
|
||||
let val = event.target.innerText;
|
||||
let str = input + val;
|
||||
if (str.length > 14) return;
|
||||
|
||||
if (answer !== "") {
|
||||
setInput(answer + val);
|
||||
setAnswer("");
|
||||
} else setInput(str);
|
||||
// setInput(str);
|
||||
};
|
||||
|
||||
//Clear screen
|
||||
const clearInput = () => {
|
||||
setInput("");
|
||||
setAnswer("");
|
||||
};
|
||||
|
||||
// check brackets are balanced or not
|
||||
const checkBracketBalanced = (expr) => {
|
||||
let stack = [];
|
||||
for (let i = 0; i < expr.length; i++) {
|
||||
let x = expr[i];
|
||||
if (x === "(") {
|
||||
stack.push(x);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (x === ")") {
|
||||
if (stack.length === 0) return false;
|
||||
else stack.pop();
|
||||
}
|
||||
}
|
||||
return stack.length === 0;
|
||||
};
|
||||
|
||||
// calculate final answer
|
||||
const calculateAns = () => {
|
||||
if (input === "") return;
|
||||
let result = 0;
|
||||
let finalexpression = input;
|
||||
// finalexpression = input.replaceAll("^", "**"); //for eval()
|
||||
finalexpression = finalexpression.replaceAll("x", "*");
|
||||
finalexpression = finalexpression.replaceAll("÷", "/");
|
||||
|
||||
// evaluate square root
|
||||
let noSqrt = input.match(/√[0-9]+/gi);
|
||||
|
||||
if (noSqrt !== null) {
|
||||
let evalSqrt = input;
|
||||
for (let i = 0; i < noSqrt.length; i++) {
|
||||
evalSqrt = evalSqrt.replace(
|
||||
noSqrt[i],
|
||||
`sqrt(${noSqrt[i].substring(1)})`
|
||||
);
|
||||
}
|
||||
finalexpression = evalSqrt;
|
||||
}
|
||||
|
||||
try {
|
||||
// check brackets are balanced or not
|
||||
if (!checkBracketBalanced(finalexpression)) {
|
||||
const errorMessage = { message: "Brackets are not balanced!" };
|
||||
throw errorMessage;
|
||||
}
|
||||
result = evaluate(finalexpression); //mathjs
|
||||
} catch (error) {
|
||||
result =
|
||||
error.message === "Brackets are not balanced!"
|
||||
? "Brackets are not balanced!"
|
||||
: "Invalid Input!!"; //error.message;
|
||||
}
|
||||
isNaN(result) ? setAnswer(result) : setAnswer(round(result, 3));
|
||||
};
|
||||
|
||||
// remove last character
|
||||
const backspace = () => {
|
||||
if (answer !== "") {
|
||||
setInput(answer.toString().slice(0, -1));
|
||||
setAnswer("");
|
||||
} else setInput((prev) => prev.slice(0, -1));
|
||||
};
|
||||
|
||||
// change prefix of expression
|
||||
const changePlusMinus = () => {
|
||||
//need to change for answer
|
||||
if (answer === "Invalid Input!!") return;
|
||||
else if (answer !== "") {
|
||||
if (input.charAt(0) === "-") {
|
||||
let plus = "+";
|
||||
setInput(plus.concat(answer.slice(1, answer.length)));
|
||||
} else if (input.charAt(0) === "+") {
|
||||
let minus = "-";
|
||||
setInput(minus.concat(answer.slice(1, answer.length)));
|
||||
} else {
|
||||
let minus = "-";
|
||||
setInput(minus.concat(answer));
|
||||
}
|
||||
setAnswer("");
|
||||
} else {
|
||||
if (input.charAt(0) === "-") {
|
||||
let plus = "+";
|
||||
setInput((prev) => plus.concat(prev.slice(1, prev.length)));
|
||||
} else if (input.charAt(0) === "+") {
|
||||
let minus = "-";
|
||||
setInput((prev) => minus.concat(prev.slice(1, prev.length)));
|
||||
} else {
|
||||
let minus = "-";
|
||||
setInput((prev) => minus.concat(prev));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="container">
|
||||
<div className="main">
|
||||
<Display input={input} setInput={setInput} answer={answer} />
|
||||
<Buttons
|
||||
inputHandler={inputHandler}
|
||||
clearInput={clearInput}
|
||||
backspace={backspace}
|
||||
changePlusMinus={changePlusMinus}
|
||||
calculateAns={calculateAns}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Calculator;
|
||||
56
src/components/Display.js
Normal file
56
src/components/Display.js
Normal file
@ -0,0 +1,56 @@
|
||||
import React from "react";
|
||||
import "./styles/Display.css";
|
||||
|
||||
const Display = ({ input, setInput, answer }) => {
|
||||
// const onChangeTagInput = (e) => {
|
||||
// // setInputVal(e.target.value.replace(/^[0-9 ()+-]+$/, "a"));
|
||||
// // if(e.target.value === "1")
|
||||
// setInput(e.target.value);
|
||||
// // console.log(e.target.value.test(/^[0-9 ()+-]+$/));
|
||||
// // console.log(e.target.value);
|
||||
// };
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="display">
|
||||
{answer === "" ? (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
name="input"
|
||||
className="input"
|
||||
style={{ padding: "29px" }}
|
||||
value={input}
|
||||
placeholder="0"
|
||||
// onChange={onChangeTagInput}
|
||||
maxLength={12}
|
||||
disabled
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
name="input"
|
||||
className="value"
|
||||
value={input}
|
||||
placeholder="0"
|
||||
// onChange={onChangeTagInput}
|
||||
maxLength={12}
|
||||
disabled
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
name="value"
|
||||
className="input"
|
||||
value={answer}
|
||||
disabled
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Display;
|
||||
39
src/components/styles/Buttons.css
Normal file
39
src/components/styles/Buttons.css
Normal file
@ -0,0 +1,39 @@
|
||||
.show-btn {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto;
|
||||
background-color: white;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 6px auto;
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
background: none;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #6dd5ed;
|
||||
color: white;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
background-color: #48b1bf;
|
||||
color: white;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.clr {
|
||||
color: #d66d75;
|
||||
}
|
||||
|
||||
.exp {
|
||||
color: #06beb6;
|
||||
}
|
||||
22
src/components/styles/Calculator.css
Normal file
22
src/components/styles/Calculator.css
Normal file
@ -0,0 +1,22 @@
|
||||
.container {
|
||||
background-color: gainsboro;
|
||||
min-height: 100vh;
|
||||
min-width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.main {
|
||||
border: 0px;
|
||||
box-shadow: 0px 0px 3px 0.5px #c4e0e5;
|
||||
border-radius: 10px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
44
src/components/styles/Display.css
Normal file
44
src/components/styles/Display.css
Normal file
@ -0,0 +1,44 @@
|
||||
.display {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
padding-bottom: 20px;
|
||||
background: linear-gradient(90deg, #06beb6, #48b1bf 100%);
|
||||
}
|
||||
|
||||
.expression {
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.input,
|
||||
.value {
|
||||
padding: 10px;
|
||||
text-align: right;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border: 0px;
|
||||
letter-spacing: 1.5px;
|
||||
}
|
||||
|
||||
.input {
|
||||
font-size: 35px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.input::placeholder,
|
||||
.value::placeholder {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.input:focus-visible,
|
||||
.value:focus-visible {
|
||||
outline-style: none;
|
||||
outline-width: 0px;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user