Compare commits

..

No commits in common. "044de983beb9adc31adbfa408c1fe66d54c80028" and "2d72402ca57cc6e59407a51c18b586ab31b8276d" have entirely different histories.

2 changed files with 107 additions and 71 deletions

View File

@ -4,37 +4,34 @@ import '@/styles/calc.scss'
export const CalculatorInput = ({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false }) => { export const CalculatorInput = ({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false }) => {
const [showKeypad, setShowKeypad] = useState(false) const [showKeypad, setShowKeypad] = useState(false)
const [displayValue, setDisplayValue] = useState(value || '0')
const [hasOperation, setHasOperation] = useState(false)
const calculatorRef = useRef(createCalculator(options)) const calculatorRef = useRef(createCalculator(options))
const containerRef = useRef(null) const containerRef = useRef(null)
const inputRef = useRef(null) const inputRef = useRef(null) // input ref
// Sync displayValue with value prop
useEffect(() => {
setDisplayValue(value || '0')
}, [value])
// //
useEffect(() => { useEffect(() => {
const handleClickOutside = (event) => { const handleClickOutside = (event) => {
if (containerRef.current && !containerRef.current.contains(event.target)) { if (containerRef.current && !containerRef.current.contains(event.target)) {
setShowKeypad(false) setShowKeypad(false)
if (hasOperation) { if (/[+\-×÷]/.test(value)) {
// If there's an operation in progress, compute the result when losing focus const newValue = calculatorRef.current.clear()
handleCompute() onChange(newValue)
} }
} }
} }
document.addEventListener('mousedown', handleClickOutside) document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside) return () => document.removeEventListener('mousedown', handleClickOutside)
}, [value, onChange, hasOperation]) }, [value, onChange])
// state
const [displayValue, setDisplayValue] = useState(value || '0')
const [hasOperation, setHasOperation] = useState(false)
// //
const handleNumber = (num) => { const handleNumber = (num) => {
const calculator = calculatorRef.current const calculator = calculatorRef.current
let newDisplayValue = '' let newValue = ''
if (hasOperation) { if (hasOperation) {
// //
@ -44,34 +41,30 @@ export const CalculatorInput = ({ value, onChange, label, options = {}, id, clas
} else { } else {
calculator.currentOperand = (calculator.currentOperand || '') + num calculator.currentOperand = (calculator.currentOperand || '') + num
} }
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand newValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
setDisplayValue(newDisplayValue) setDisplayValue(newValue)
onChange(calculator.currentOperand)
} else { } else {
// //
if (displayValue === '0' || calculator.shouldResetDisplay) { if (value === '0' || calculator.shouldResetDisplay) {
calculator.currentOperand = num.toString() calculator.currentOperand = num.toString()
calculator.shouldResetDisplay = false calculator.shouldResetDisplay = false
newDisplayValue = calculator.currentOperand
setDisplayValue(newDisplayValue)
if (!hasOperation) {
onChange(calculator.currentOperand)
}
} else { } else {
calculator.currentOperand = (calculator.currentOperand || '') + num calculator.currentOperand = (calculator.currentOperand || '') + num
newDisplayValue = calculator.currentOperand
setDisplayValue(newDisplayValue)
if (!hasOperation) {
onChange(newDisplayValue)
}
} }
newValue = calculator.currentOperand
setDisplayValue(newValue)
onChange(newValue)
} }
// ( ) //
requestAnimationFrame(() => { requestAnimationFrame(() => {
if (inputRef.current) { if (inputRef.current) {
inputRef.current.focus() inputRef.current.focus()
const len = newDisplayValue.length const len = newValue.length
inputRef.current.setSelectionRange(len, len) inputRef.current.setSelectionRange(len, len)
// Ensure focus is maintained
inputRef.current.focus()
} }
}) })
} }
@ -79,42 +72,67 @@ export const CalculatorInput = ({ value, onChange, label, options = {}, id, clas
// //
const handleOperation = (operation) => { const handleOperation = (operation) => {
const calculator = calculatorRef.current const calculator = calculatorRef.current
let newDisplayValue = ''
// ( ) // ( )
if (!calculator.currentOperand && calculator.previousOperand) { if (!calculator.currentOperand && calculator.previousOperand) {
calculator.operation = operation calculator.operation = operation
newDisplayValue = calculator.previousOperand + operation const newValue = calculator.previousOperand + operation
setDisplayValue(newDisplayValue) setDisplayValue(newValue)
setHasOperation(true) setHasOperation(true)
} else if (hasOperation) { //
requestAnimationFrame(() => {
if (inputRef.current) {
inputRef.current.focus()
const len = newValue.length
inputRef.current.setSelectionRange(len, len)
inputRef.current.focus()
}
})
return
}
if (hasOperation) {
// , // ,
const result = calculator.compute() const result = calculator.compute()
if (result !== undefined) { if (result !== undefined) {
calculator.previousOperand = result.toString() calculator.previousOperand = result.toString()
calculator.operation = operation calculator.operation = operation
calculator.currentOperand = '' calculator.currentOperand = ''
newDisplayValue = calculator.previousOperand + operation const newValue = result.toString() + operation
setDisplayValue(newDisplayValue) setDisplayValue(newValue)
setHasOperation(true)
onChange(result.toString())
//
requestAnimationFrame(() => {
if (inputRef.current) {
inputRef.current.focus()
const len = newValue.length
inputRef.current.setSelectionRange(len, len)
inputRef.current.focus()
}
})
} }
} else { } else {
// //
calculator.previousOperand = calculator.currentOperand || '0' calculator.previousOperand = displayValue
calculator.operation = operation calculator.operation = operation
calculator.currentOperand = '' calculator.currentOperand = ''
const newValue = displayValue + operation
setDisplayValue(newValue)
setHasOperation(true) setHasOperation(true)
newDisplayValue = calculator.previousOperand + operation onChange(displayValue)
setDisplayValue(newDisplayValue)
}
// ( ) //
requestAnimationFrame(() => { requestAnimationFrame(() => {
if (inputRef.current) { if (inputRef.current) {
inputRef.current.focus() inputRef.current.focus()
const len = newDisplayValue.length const len = newValue.length
inputRef.current.setSelectionRange(len, len) inputRef.current.setSelectionRange(len, len)
} inputRef.current.focus()
}) }
})
}
} }
// AC // AC
@ -139,26 +157,44 @@ export const CalculatorInput = ({ value, onChange, label, options = {}, id, clas
// //
const handleCompute = () => { const handleCompute = () => {
if (!hasOperation) return
const calculator = calculatorRef.current const calculator = calculatorRef.current
if (!hasOperation || !calculator.currentOperand) return
const result = calculator.compute() // 0
if (result !== undefined) { if (!calculator.currentOperand) {
const resultStr = result.toString() calculator.currentOperand = '0'
setDisplayValue(resultStr)
setHasOperation(false)
// Only call onChange with the final result
onChange(resultStr)
// ( )
requestAnimationFrame(() => {
if (inputRef.current) {
inputRef.current.focus()
const len = resultStr.length
inputRef.current.setSelectionRange(len, len)
}
})
} }
//
const result = calculator.compute()
//
if (result === undefined || result === null) {
console.error('계산 결과가 유효하지 않습니다.')
return
}
//
const resultStr = result.toString()
setDisplayValue(resultStr)
setHasOperation(false)
onChange(resultStr)
// ( )
calculator.clear()
calculator.previousOperand = resultStr
//
requestAnimationFrame(() => {
if (inputRef.current) {
inputRef.current.focus()
const len = resultStr.length
inputRef.current.setSelectionRange(len, len)
// Ensure focus is maintained
inputRef.current.focus()
}
})
} }
// DEL // DEL

View File

@ -353,23 +353,23 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
onChange={(value) => { onChange={(value) => {
if (index === 0) { if (index === 0) {
const num = value === '' ? '' : Number(value) const num = value === '' ? '' : Number(value)
setCurrentRoof(prev => ({ setCurrentRoof({
...prev, ...currentRoof,
pitch: num === '' ? '' : num, pitch: num === '' ? '' : num,
angle: num === '' ? '' : getDegreeByChon(num), angle: num === '' ? '' : getDegreeByChon(num),
})) })
} else { } else {
const num = value === '' ? '' : Number(value) const num = value === '' ? '' : Number(value)
setCurrentRoof( prev => ({ setCurrentRoof({
...prev, ...currentRoof,
pitch: num === '' ? '' : getChonByDegree(num), pitch: num === '' ? '' : getChonByDegree(num),
angle: num === '' ? '' : num, angle: num === '' ? '' : num,
})) })
} }
}} }}
options={{ options={{
allowNegative: false, allowNegative: false,
allowDecimal: false //(index !== 0), allowDecimal: (index !== 0),
}} }}
/> />
</div> </div>