From f15ff10bf6d995ecfe99ec99a4cc116ec6883e01 Mon Sep 17 00:00:00 2001 From: ysCha Date: Fri, 29 Aug 2025 17:10:05 +0900 Subject: [PATCH] =?UTF-8?q?input=20=EA=B3=84=EC=82=B0=EA=B8=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/input/CalcInput.jsx | 162 +++++++----------- .../placementShape/PlacementShapeSetting.jsx | 14 +- 2 files changed, 70 insertions(+), 106 deletions(-) diff --git a/src/components/common/input/CalcInput.jsx b/src/components/common/input/CalcInput.jsx index b85a9393..8e60506b 100644 --- a/src/components/common/input/CalcInput.jsx +++ b/src/components/common/input/CalcInput.jsx @@ -4,34 +4,37 @@ import '@/styles/calc.scss' export const CalculatorInput = ({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false }) => { const [showKeypad, setShowKeypad] = useState(false) + const [displayValue, setDisplayValue] = useState(value || '0') + const [hasOperation, setHasOperation] = useState(false) const calculatorRef = useRef(createCalculator(options)) 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(() => { const handleClickOutside = (event) => { if (containerRef.current && !containerRef.current.contains(event.target)) { setShowKeypad(false) - if (/[+\-×÷]/.test(value)) { - const newValue = calculatorRef.current.clear() - onChange(newValue) + if (hasOperation) { + // If there's an operation in progress, compute the result when losing focus + handleCompute() } } } document.addEventListener('mousedown', handleClickOutside) return () => document.removeEventListener('mousedown', handleClickOutside) - }, [value, onChange]) - - // 계산기 상태 관리를 위한 state 추가 - const [displayValue, setDisplayValue] = useState(value || '0') - const [hasOperation, setHasOperation] = useState(false) + }, [value, onChange, hasOperation]) // 숫자 입력 처리 함수 수정 const handleNumber = (num) => { const calculator = calculatorRef.current - let newValue = '' + let newDisplayValue = '' if (hasOperation) { // 연산자 이후 숫자 입력 시 @@ -41,30 +44,34 @@ export const CalculatorInput = ({ value, onChange, label, options = {}, id, clas } else { calculator.currentOperand = (calculator.currentOperand || '') + num } - newValue = calculator.previousOperand + calculator.operation + calculator.currentOperand - setDisplayValue(newValue) - onChange(calculator.currentOperand) + newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand + setDisplayValue(newDisplayValue) } else { // 첫 번째 숫자 입력 시 - if (value === '0' || calculator.shouldResetDisplay) { + if (displayValue === '0' || calculator.shouldResetDisplay) { calculator.currentOperand = num.toString() calculator.shouldResetDisplay = false + newDisplayValue = calculator.currentOperand + setDisplayValue(newDisplayValue) + if (!hasOperation) { + onChange(calculator.currentOperand) + } } else { calculator.currentOperand = (calculator.currentOperand || '') + num + newDisplayValue = calculator.currentOperand + setDisplayValue(newDisplayValue) + if (!hasOperation) { + onChange(newDisplayValue) + } } - newValue = calculator.currentOperand - setDisplayValue(newValue) - onChange(newValue) } - // 포커스와 커서 위치 설정 + // 포커스와 커서 위치 설정 (새로운 값의 길이로 설정) requestAnimationFrame(() => { if (inputRef.current) { inputRef.current.focus() - const len = newValue.length + const len = newDisplayValue.length 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 calculator = calculatorRef.current + let newDisplayValue = '' // 현재 입력된 값이 없으면 이전 값 사용 (연속 연산 시) if (!calculator.currentOperand && calculator.previousOperand) { calculator.operation = operation - const newValue = calculator.previousOperand + operation - setDisplayValue(newValue) + newDisplayValue = calculator.previousOperand + operation + setDisplayValue(newDisplayValue) setHasOperation(true) - // 포커스와 커서 위치 설정 - requestAnimationFrame(() => { - if (inputRef.current) { - inputRef.current.focus() - const len = newValue.length - inputRef.current.setSelectionRange(len, len) - inputRef.current.focus() - } - }) - return - } - - if (hasOperation) { + } else if (hasOperation) { // 이미 연산자가 있는 경우, 계산 실행 const result = calculator.compute() if (result !== undefined) { calculator.previousOperand = result.toString() calculator.operation = operation calculator.currentOperand = '' - const newValue = result.toString() + operation - 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() - } - }) + newDisplayValue = calculator.previousOperand + operation + setDisplayValue(newDisplayValue) } } else { - // 새로운 연산자 추가 - calculator.previousOperand = displayValue + // 첫 번째 연산자 입력 시 + calculator.previousOperand = calculator.currentOperand || '0' calculator.operation = operation calculator.currentOperand = '' - const newValue = displayValue + operation - setDisplayValue(newValue) setHasOperation(true) - onChange(displayValue) - - // 포커스와 커서 위치 설정 - requestAnimationFrame(() => { - if (inputRef.current) { - inputRef.current.focus() - const len = newValue.length - inputRef.current.setSelectionRange(len, len) - inputRef.current.focus() - } - }) + newDisplayValue = calculator.previousOperand + operation + setDisplayValue(newDisplayValue) } + + // 포커스와 커서 위치 설정 (새로운 값의 길이로 설정) + requestAnimationFrame(() => { + if (inputRef.current) { + inputRef.current.focus() + const len = newDisplayValue.length + inputRef.current.setSelectionRange(len, len) + } + }) } // AC 버튼 클릭 핸들러 @@ -157,44 +139,26 @@ export const CalculatorInput = ({ value, onChange, label, options = {}, id, clas // 계산 실행 함수 수정 const handleCompute = () => { - if (!hasOperation) return - const calculator = calculatorRef.current + if (!hasOperation || !calculator.currentOperand) return - // 현재 입력된 값이 없으면 0으로 설정 - if (!calculator.currentOperand) { - calculator.currentOperand = '0' - } - - // 계산 실행 const result = calculator.compute() - - // 계산 결과가 유효한지 확인 - if (result === undefined || result === null) { - console.error('계산 결과가 유효하지 않습니다.') - return + if (result !== undefined) { + const resultStr = result.toString() + 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 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 버튼 클릭 핸들러 diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 2d5d9c41..a8ee7102 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -353,23 +353,23 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla onChange={(value) => { if (index === 0) { const num = value === '' ? '' : Number(value) - setCurrentRoof({ - ...currentRoof, + setCurrentRoof(prev => ({ + ...prev, pitch: num === '' ? '' : num, angle: num === '' ? '' : getDegreeByChon(num), - }) + })) } else { const num = value === '' ? '' : Number(value) - setCurrentRoof({ - ...currentRoof, + setCurrentRoof( prev => ({ + ...prev, pitch: num === '' ? '' : getChonByDegree(num), angle: num === '' ? '' : num, - }) + })) } }} options={{ allowNegative: false, - allowDecimal: (index !== 0), + allowDecimal: false //(index !== 0), }} />