Skip to content

Commit 0441851

Browse files
committed
desktop changes
1 parent 8c10b48 commit 0441851

File tree

8 files changed

+1459
-237
lines changed

8 files changed

+1459
-237
lines changed

component/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
"@babel/preset-react": "^7.0.0",
1818
"rollup": "^1.21.2",
1919
"rollup-plugin-babel": "^4.3.3",
20+
"rollup-plugin-postcss": "^2.0.3",
2021
"rollup-plugin-uglify": "^6.0.3"
2122
},
22-
"dependencies": {
23-
"react-resize-detector": "^4.2.1"
24-
}
23+
"dependencies": {}
2524
}

component/rollup.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import babel from 'rollup-plugin-babel'
22
import { uglify } from 'rollup-plugin-uglify'
3+
import postcss from 'rollup-plugin-postcss'
34

45
const config = {
56
input: 'src/Calculator.js',
67
external: ['react'],
78
plugins: [
9+
postcss({
10+
extensions: [ '.css' ]
11+
}),
812
babel({
913
exclude: "node_modules/**"
1014
}),

component/src/Calculator.js

Lines changed: 148 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,141 @@
1-
import React, { Fragment, useState } from 'react'
2-
import ReactResizeDetector from 'react-resize-detector'
3-
4-
// operators
5-
const ADDITION = '+'
6-
const SUBTRACTION = '-'
7-
const MULTIPLICATION = 'x'
8-
const DIVISION = '/'
9-
const MODULUS = '%'
1+
import React, { useState, useEffect } from 'react'
2+
import './index.css'
3+
import { isArray } from 'util'
104

115
const Calculator = () => {
12-
// the initial values object
13-
const initialCalculation = {
14-
left: '0',
15-
operator: null,
16-
right: null
17-
}
18-
19-
// TODO after the equals button is pressed, new number presses should clear the answer
6+
// operator constants
7+
const ADDITION = '+'
8+
const SUBTRACTION = '-'
9+
const MULTIPLICATION = '*'
10+
const DIVISION = '/'
11+
const MODULUS = '%'
12+
13+
// listens for the keydown event for the given key and calls the callback function
14+
const onKeyDown = (key, callback) => {
15+
const onDown = (e) => {
16+
const eventKeyLower = e.key.toLowerCase()
17+
if (isArray(key)) {
18+
if(key.find((elem) => elem.toLowerCase() == eventKeyLower)) {
19+
callback()
20+
}
21+
} else if (key.toLowerCase() == eventKeyLower) {
22+
callback()
23+
}
24+
}
2025

21-
// TODO add keyboard input functionality
26+
useEffect(() => {
27+
window.addEventListener("keydown", onDown)
28+
return () => {
29+
window.removeEventListener("keydown", onDown)
30+
}
31+
}, [key])
32+
}
2233

23-
// TODO css height match width - use padding-top and 0 height
34+
// Number Button (0-9)
35+
const NumberKey = ({children:key}) => {
36+
onKeyDown(key, () => onNumClick(key))
37+
return (
38+
<td className="button button--number" onClick={() => {onNumClick(key)}}><div>{key}</div></td>
39+
)
40+
}
2441

25-
// TODO responsive font sizing - CSS @media only works based on viewport size, not container size
26-
// - will need to use JS to watch the container width
42+
// Operator Button (plus, minus, divide, multiply, modulus)
43+
const OperatorKey = ({children:key}) => {
44+
onKeyDown(key, () => onOperatorClick(key))
45+
return (
46+
<td className="button button--operator" onClick={() => onOperatorClick(key)}><div>{key}</div></td>
47+
)
48+
}
2749

28-
// TODO export CSS with component
50+
// Control Button (clear, delete, equals, decimal)
51+
const ControlKey = ({children:value, onClick, listenKey, classModify, ...rest}) => {
52+
onKeyDown(listenKey || value, onClick)
53+
return (
54+
<td className={"button button--control " + classModify} onClick={onClick} {...rest}><div>{value}</div></td>
55+
)
56+
}
2957

30-
// create the calculation state
58+
// setup the state
59+
const initialCalculation = {
60+
left: null,
61+
operator: null,
62+
right: null,
63+
answer: null
64+
}
3165
const [calculation, setCalculation] = useState(initialCalculation)
3266

33-
// destructure the state object into variables
34-
const { left, operator, right } = calculation
35-
67+
// gets the left or right value based on if operator is set
3668
const getCurrentValue = () => {
37-
return operator ? right || '' : left
69+
return calculation.operator ? calculation.right : calculation.left
3870
}
3971

72+
// sets the left or right value based on if operator is set
4073
const setCurrentValue = (value) => {
4174
setCalculation({
4275
...calculation,
43-
left: operator ? calculation.left : value,
44-
right: operator ? value : calculation.right
76+
answer: initialCalculation.answer,
77+
left: calculation.operator ? calculation.left : value,
78+
right: calculation.operator ? value : calculation.right
4579
})
4680
}
4781

48-
// handle a number being clicked
49-
const onNumClick = e => {
50-
// get the button value clicked
51-
const buttonText = e.target.textContent
52-
53-
// get the value to append
82+
// appends the number onto the current value
83+
const onNumClick = (number) => {
5484
let value = getCurrentValue()
55-
56-
if (value === '0' || isNaN(value) || !isFinite(value)) {
57-
value = buttonText
58-
} else {
59-
value = value + buttonText
60-
}
61-
62-
setCurrentValue(value)
85+
setCurrentValue((value === null || value === '0' || isNaN(value) || !isFinite(value)) ? number : value + number)
6386
}
6487

65-
const onDecimalClick = e => {
66-
let value = getCurrentValue()
67-
if (value.match(/\./)) {
68-
return
69-
} else if (isNaN(value) || !isFinite(value)) {
70-
value = '0.'
71-
} else {
72-
value = value + '.'
73-
}
88+
// handle an operator being clicked
89+
const onOperatorClick = (operator) => {
90+
setCalculation({
91+
...calculation,
92+
answer: initialCalculation.answer,
93+
left: calculation.left || calculation.answer,
94+
operator
95+
})
96+
}
7497

75-
setCurrentValue(value)
98+
// clears the entire calculation
99+
const onClearClick = () => {
100+
setCalculation({
101+
...initialCalculation
102+
})
76103
}
77104

78-
const onOperatorClick = e => {
105+
// clears the current entry of the calculation
106+
const onClearEntryClick = () => {
79107
setCalculation({
80108
...calculation,
81-
operator: e.target.textContent
109+
answer: initialCalculation.answer,
110+
left: calculation.operator ? calculation.left : initialCalculation.left,
111+
right: initialCalculation.right
82112
})
83113
}
84114

85-
const onDeleteClick = e => {
115+
// backspace on the current entry of the calculation
116+
const onDeleteClick = () => {
86117
let value = getCurrentValue()
118+
setCurrentValue(value === null || value.length === 1 ? null : value.substring(0, value.length - 1))
119+
}
87120

88-
if (value.length === 1) {
89-
value = '0'
90-
} else {
91-
value = value.substring(0, value.length - 1);
92-
}
93-
94-
setCurrentValue(value)
121+
// adds a decimal to the current entry of the calculation
122+
const onDecimalClick = () => {
123+
let value = getCurrentValue()
124+
if (value !== null && value.match(/\./)) return
125+
setCurrentValue((value === null || value === '0' || isNaN(value) || !isFinite(value)) ? '0.' : value + '.')
95126
}
96127

97-
const onEqualsClick = e => {
98-
if (right === null) {
128+
// sets the answer to the calculation as the new left entry value
129+
const onEqualsClick = () => {
130+
// if no right value, dont calculate
131+
if (calculation.right === null) {
99132
return
100133
}
101134

102135
let value;
103-
const leftNumber = Number(left)
104-
const rightNumber = Number(right)
105-
switch (operator) {
136+
const leftNumber = Number(calculation.left)
137+
const rightNumber = Number(calculation.right)
138+
switch (calculation.operator) {
106139
case ADDITION:
107140
value = leftNumber + rightNumber
108141
break
@@ -124,46 +157,64 @@ const Calculator = () => {
124157

125158
setCalculation({
126159
...calculation,
127-
left: value.toString(),
160+
left: null,
128161
operator: null,
129-
right: null
130-
})
131-
}
132-
133-
const onClearEntryClick = e => {
134-
setCalculation({
135-
...calculation,
136-
left: operator ? calculation.left : '0',
137-
right: operator ? '0' : null
162+
right: null,
163+
answer: value.toString()
138164
})
139165
}
140166

141-
const onClearClick = e => {
142-
setCalculation({
143-
...initialCalculation
144-
})
145-
}
146-
147-
const getDisplayValue = () => {
148-
let text = right || left
149-
return text.length > 16 ? Number(text).toExponential().toString() : text
150-
}
167+
const getDisplayText = () => {
168+
if (calculation.answer) {
169+
return calculation.answer
170+
}
151171

152-
const onResize = (width, height) => {
153-
console.log(`width: ${width}`)
154-
console.log(`height: ${height}`)
155-
console.log('------------------')
172+
return `${calculation.left || '0'} ${calculation.operator || ''} ${calculation.right || ''}`
156173
}
157174

158175
return (
159176
<div className="calculator">
160-
<ReactResizeDetector handleWidth handleHeight onResize={this.onResize} />
161177
<div className="display">
162-
<p className="display--calculation">test
163-
{operator && <span>{left.length > 16 ? Number(left).toExponential() : left} {operator}</span>}
164-
</p>
165-
<h4 className="display--value">{getDisplayValue()}</h4>
178+
<div className="display--inner">
179+
<h4 className="display--value">{getDisplayText()}</h4>
180+
</div>
166181
</div>
182+
<table className="keypad">
183+
<tbody>
184+
<tr>
185+
<ControlKey onClick={onClearClick} listenKey="escape" width="25%">C</ControlKey>
186+
<ControlKey onClick={onClearEntryClick} listenKey="delete" width="50%" colSpan={2}>CE</ControlKey>
187+
<OperatorKey width="25%">{MODULUS}</OperatorKey>
188+
</tr>
189+
<tr>
190+
<NumberKey>1</NumberKey>
191+
<NumberKey>2</NumberKey>
192+
<NumberKey>3</NumberKey>
193+
<OperatorKey>{DIVISION}</OperatorKey>
194+
</tr>
195+
<tr>
196+
<NumberKey>4</NumberKey>
197+
<NumberKey>5</NumberKey>
198+
<NumberKey>6</NumberKey>
199+
<OperatorKey>{MULTIPLICATION}</OperatorKey>
200+
</tr>
201+
<tr>
202+
<NumberKey>7</NumberKey>
203+
<NumberKey>8</NumberKey>
204+
<NumberKey>9</NumberKey>
205+
<OperatorKey>{SUBTRACTION}</OperatorKey>
206+
</tr>
207+
<tr>
208+
<ControlKey onClick={onDeleteClick} listenKey="backspace">del</ControlKey>
209+
<NumberKey>0</NumberKey>
210+
<ControlKey onClick={onDecimalClick}>.</ControlKey>
211+
<OperatorKey>{ADDITION}</OperatorKey>
212+
</tr>
213+
<tr>
214+
<ControlKey onClick={onEqualsClick} listenKey={['=', 'Enter']} classModify="button--control-equals" colSpan={4}>=</ControlKey>
215+
</tr>
216+
</tbody>
217+
</table>
167218
</div>
168219
)
169220
}

0 commit comments

Comments
 (0)