input 계산기 수정
This commit is contained in:
parent
38a1907842
commit
f15ff10bf6
@ -4,34 +4,37 @@ 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) // input 요소에 대한 ref 추가
|
const inputRef = useRef(null)
|
||||||
|
|
||||||
|
// 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 (/[+\-×÷]/.test(value)) {
|
if (hasOperation) {
|
||||||
const newValue = calculatorRef.current.clear()
|
// If there's an operation in progress, compute the result when losing focus
|
||||||
onChange(newValue)
|
handleCompute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('mousedown', handleClickOutside)
|
document.addEventListener('mousedown', handleClickOutside)
|
||||||
return () => document.removeEventListener('mousedown', handleClickOutside)
|
return () => document.removeEventListener('mousedown', handleClickOutside)
|
||||||
}, [value, onChange])
|
}, [value, onChange, hasOperation])
|
||||||
|
|
||||||
// 계산기 상태 관리를 위한 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 newValue = ''
|
let newDisplayValue = ''
|
||||||
|
|
||||||
if (hasOperation) {
|
if (hasOperation) {
|
||||||
// 연산자 이후 숫자 입력 시
|
// 연산자 이후 숫자 입력 시
|
||||||
@ -41,30 +44,34 @@ export const CalculatorInput = ({ value, onChange, label, options = {}, id, clas
|
|||||||
} else {
|
} else {
|
||||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||||
}
|
}
|
||||||
newValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
||||||
setDisplayValue(newValue)
|
setDisplayValue(newDisplayValue)
|
||||||
onChange(calculator.currentOperand)
|
|
||||||
} else {
|
} else {
|
||||||
// 첫 번째 숫자 입력 시
|
// 첫 번째 숫자 입력 시
|
||||||
if (value === '0' || calculator.shouldResetDisplay) {
|
if (displayValue === '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 = newValue.length
|
const len = newDisplayValue.length
|
||||||
inputRef.current.setSelectionRange(len, len)
|
inputRef.current.setSelectionRange(len, len)
|
||||||
// Ensure focus is maintained
|
|
||||||
inputRef.current.focus()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -72,67 +79,42 @@ 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
|
||||||
const newValue = calculator.previousOperand + operation
|
newDisplayValue = calculator.previousOperand + operation
|
||||||
setDisplayValue(newValue)
|
setDisplayValue(newDisplayValue)
|
||||||
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 = ''
|
||||||
const newValue = result.toString() + operation
|
newDisplayValue = calculator.previousOperand + operation
|
||||||
setDisplayValue(newValue)
|
setDisplayValue(newDisplayValue)
|
||||||
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 = displayValue
|
calculator.previousOperand = calculator.currentOperand || '0'
|
||||||
calculator.operation = operation
|
calculator.operation = operation
|
||||||
calculator.currentOperand = ''
|
calculator.currentOperand = ''
|
||||||
const newValue = displayValue + operation
|
|
||||||
setDisplayValue(newValue)
|
|
||||||
setHasOperation(true)
|
setHasOperation(true)
|
||||||
onChange(displayValue)
|
newDisplayValue = calculator.previousOperand + operation
|
||||||
|
setDisplayValue(newDisplayValue)
|
||||||
// 포커스와 커서 위치 설정
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
if (inputRef.current) {
|
|
||||||
inputRef.current.focus()
|
|
||||||
const len = newValue.length
|
|
||||||
inputRef.current.setSelectionRange(len, len)
|
|
||||||
inputRef.current.focus()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 포커스와 커서 위치 설정 (새로운 값의 길이로 설정)
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.focus()
|
||||||
|
const len = newDisplayValue.length
|
||||||
|
inputRef.current.setSelectionRange(len, len)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// AC 버튼 클릭 핸들러
|
// AC 버튼 클릭 핸들러
|
||||||
@ -157,44 +139,26 @@ 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
|
||||||
|
|
||||||
// 현재 입력된 값이 없으면 0으로 설정
|
|
||||||
if (!calculator.currentOperand) {
|
|
||||||
calculator.currentOperand = '0'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 계산 실행
|
|
||||||
const result = calculator.compute()
|
const result = calculator.compute()
|
||||||
|
if (result !== undefined) {
|
||||||
// 계산 결과가 유효한지 확인
|
const resultStr = result.toString()
|
||||||
if (result === undefined || result === null) {
|
setDisplayValue(resultStr)
|
||||||
console.error('계산 결과가 유효하지 않습니다.')
|
setHasOperation(false)
|
||||||
return
|
// 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 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 버튼 클릭 핸들러
|
||||||
|
|||||||
@ -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({
|
setCurrentRoof(prev => ({
|
||||||
...currentRoof,
|
...prev,
|
||||||
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({
|
setCurrentRoof( prev => ({
|
||||||
...currentRoof,
|
...prev,
|
||||||
pitch: num === '' ? '' : getChonByDegree(num),
|
pitch: num === '' ? '' : getChonByDegree(num),
|
||||||
angle: num === '' ? '' : num,
|
angle: num === '' ? '' : num,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
options={{
|
options={{
|
||||||
allowNegative: false,
|
allowNegative: false,
|
||||||
allowDecimal: (index !== 0),
|
allowDecimal: false //(index !== 0),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user