Merge pull request '초기화' (#558) from dev into dev-deploy
Reviewed-on: #558
This commit is contained in:
commit
e5dd5f0ab0
@ -23,8 +23,23 @@ export const CalculatorInput = forwardRef(
|
|||||||
}, [ref])
|
}, [ref])
|
||||||
|
|
||||||
// Sync displayValue with value prop
|
// Sync displayValue with value prop
|
||||||
|
// useEffect(() => {
|
||||||
|
// setDisplayValue(value || '0')
|
||||||
|
// }, [value])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDisplayValue(value || '0')
|
const newValue = value || '0'
|
||||||
|
setDisplayValue(newValue)
|
||||||
|
|
||||||
|
// 외부에서 value가 변경될 때 계산기 내부 상태도 동기화
|
||||||
|
const calculator = calculatorRef.current
|
||||||
|
if (calculator) {
|
||||||
|
// 연산 중이 아닐 때 외부에서 값이 들어오면 현재 피연산자로 설정
|
||||||
|
calculator.currentOperand = newValue.toString()
|
||||||
|
calculator.previousOperand = ''
|
||||||
|
calculator.operation = undefined
|
||||||
|
setHasOperation(false)
|
||||||
|
}
|
||||||
}, [value])
|
}, [value])
|
||||||
|
|
||||||
// 클릭 외부 감지
|
// 클릭 외부 감지
|
||||||
|
|||||||
@ -8,104 +8,6 @@ export default function Angle({ props }) {
|
|||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { angle1, setAngle1, angle1Ref, length1, setLength1, length1Ref } = props
|
const { angle1, setAngle1, angle1Ref, length1, setLength1, length1Ref } = props
|
||||||
|
|
||||||
const resetCalculatorValue = () => {
|
|
||||||
// 1. 즉시 상태를 0으로 변경
|
|
||||||
setLength1(0);
|
|
||||||
|
|
||||||
if (length1Ref.current) {
|
|
||||||
// 2. input에 포커스를 주어 계산기 UI가 떠있는 상태를 유지하게 함
|
|
||||||
length1Ref.current.focus();
|
|
||||||
length1Ref.current.value = '';
|
|
||||||
|
|
||||||
// 3. 약간의 시간차를 두어 계산기 UI 내부의 버튼을 찾음
|
|
||||||
setTimeout(() => {
|
|
||||||
const acButton = document.querySelector('.keypad-btn.ac, .btn-ac') ||
|
|
||||||
Array.from(document.querySelectorAll('button')).find(el => el.textContent === 'AC');
|
|
||||||
|
|
||||||
if (acButton) {
|
|
||||||
acButton.click();
|
|
||||||
} else {
|
|
||||||
// 버튼을 못 찾으면 강제로 input 이벤트와 Enter/Escape 등을 시뮬레이션
|
|
||||||
length1Ref.current.dispatchEvent(new Event('input', { bubbles: true }));
|
|
||||||
}
|
|
||||||
// 다시 포커스를 주어 키패드가 유지되도록 함 (필요시)
|
|
||||||
length1Ref.current.focus();
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetCalculatorValue2 = () => {
|
|
||||||
// 1. 즉시 상태를 0으로 변경
|
|
||||||
setAngle1(0);
|
|
||||||
|
|
||||||
if (angle1Ref.current) {
|
|
||||||
// 2. input에 포커스를 주어 계산기 UI가 떠있는 상태를 유지하게 함
|
|
||||||
angle1Ref.current.focus();
|
|
||||||
angle1Ref.current.value = '';
|
|
||||||
|
|
||||||
// 3. 약간의 시간차를 두어 계산기 UI 내부의 버튼을 찾음
|
|
||||||
setTimeout(() => {
|
|
||||||
const acButton = document.querySelector('.keypad-btn.ac, .btn-ac') ||
|
|
||||||
Array.from(document.querySelectorAll('button')).find(el => el.textContent === 'AC');
|
|
||||||
|
|
||||||
if (acButton) {
|
|
||||||
acButton.click();
|
|
||||||
} else {
|
|
||||||
// 버튼을 못 찾으면 강제로 input 이벤트와 Enter/Escape 등을 시뮬레이션
|
|
||||||
angle1Ref.current.dispatchEvent(new Event('input', { bubbles: true }));
|
|
||||||
}
|
|
||||||
// 다시 포커스를 주어 키패드가 유지되도록 함 (필요시)
|
|
||||||
angle1Ref.current.focus();
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 키보드 입력 처리
|
|
||||||
useEffect(() => {
|
|
||||||
const handleKeyDown = (e) => {
|
|
||||||
|
|
||||||
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
|
||||||
// 계산기 값이 확정된 후 초기화하기 위해 약간의 지연을 줌
|
|
||||||
setTimeout(() => {
|
|
||||||
resetCalculatorValue();
|
|
||||||
}, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 계산기 키패드가 보이는지 확인
|
|
||||||
const keypadVisible = document.querySelector('.keypad-container')
|
|
||||||
|
|
||||||
// 계산기 키패드가 보이면 계산기가 처리하도록 함
|
|
||||||
if (keypadVisible) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 이미 계산기 input에 포커스가 있으면 계산기가 처리하도록 함
|
|
||||||
if (document.activeElement && document.activeElement.classList.contains('calculator-input')) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 엔터키는 계산기가 숨겨진 상태에서만 페이지가 처리
|
|
||||||
if (e.key === 'Enter') {
|
|
||||||
// 엔터키를 페이지 레벨로 전달 (useOuterLineWall.js에서 처리)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 숫자 키가 입력되면 계산기 input에 포커스만 주기
|
|
||||||
if (/^[0-9+\-*\/=.]$/.test(e.key) || e.key === 'Backspace' || e.key === 'Delete') {
|
|
||||||
const calcInput = document.querySelector('.calculator-input')
|
|
||||||
if (calcInput) {
|
|
||||||
// 포커스만 주고 이벤트는 preventDefault 하지 않음
|
|
||||||
calcInput.focus()
|
|
||||||
calcInput.click()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// capture: true로 설정하여 다른 핸들러보다 먼저 실행
|
|
||||||
document.addEventListener('keydown', handleKeyDown, { capture: true })
|
|
||||||
return () => document.removeEventListener('keydown', handleKeyDown, { capture: true })
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="outline-wrap">
|
<div className="outline-wrap">
|
||||||
@ -130,33 +32,29 @@ export default function Angle({ props }) {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={angle1}
|
value={angle1}
|
||||||
ref={angle1Ref}
|
ref={angle1Ref}
|
||||||
onChange={(value) => {setAngle1(value)
|
onChange={(value) => {
|
||||||
|
// Calculate the final value first
|
||||||
// Convert to number and ensure it's within -180 to 180 range
|
let finalValue = value;
|
||||||
const numValue = parseInt(value, 10);
|
const numValue = parseInt(value, 10);
|
||||||
if (!isNaN(numValue)) {
|
if (!isNaN(numValue)) {
|
||||||
const clampedValue = Math.min(180, Math.max(-180, numValue));
|
const clampedValue = Math.min(180, Math.max(-180, numValue));
|
||||||
setAngle1(String(clampedValue));
|
finalValue = String(clampedValue);
|
||||||
} else {
|
|
||||||
setAngle1(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Set state once with the final value
|
||||||
|
setAngle1(finalValue);
|
||||||
|
}}
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
onFocus={() => (angle1Ref.current.value = '')}
|
onFocus={() => (angle1Ref.current.value = '')}
|
||||||
options={{
|
options={{
|
||||||
allowNegative: true,
|
allowNegative: true,
|
||||||
allowDecimal: false
|
allowDecimal: true
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="reset-btn"
|
className="reset-btn"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
setAngle1(0)
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
resetCalculatorValue2()
|
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
@ -190,11 +88,8 @@ export default function Angle({ props }) {
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="reset-btn"
|
className="reset-btn"
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
e.preventDefault();
|
setLength1(0)
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
resetCalculatorValue()
|
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,44 +11,9 @@ export default function OuterLineWall({ props }) {
|
|||||||
|
|
||||||
const { length1, setLength1, length1Ref, arrow1, setArrow1 } = props
|
const { length1, setLength1, length1Ref, arrow1, setArrow1 } = props
|
||||||
|
|
||||||
const resetCalculatorValue = () => {
|
|
||||||
// 1. 즉시 상태를 0으로 변경
|
|
||||||
setLength1(0);
|
|
||||||
|
|
||||||
if (length1Ref.current) {
|
|
||||||
// 2. input에 포커스를 주어 계산기 UI가 떠있는 상태를 유지하게 함
|
|
||||||
length1Ref.current.focus();
|
|
||||||
length1Ref.current.value = '';
|
|
||||||
|
|
||||||
// 3. 약간의 시간차를 두어 계산기 UI 내부의 버튼을 찾음
|
|
||||||
setTimeout(() => {
|
|
||||||
const acButton = document.querySelector('.keypad-btn.ac, .btn-ac') ||
|
|
||||||
Array.from(document.querySelectorAll('button')).find(el => el.textContent === 'AC');
|
|
||||||
|
|
||||||
if (acButton) {
|
|
||||||
acButton.click();
|
|
||||||
} else {
|
|
||||||
// 버튼을 못 찾으면 강제로 input 이벤트와 Enter/Escape 등을 시뮬레이션
|
|
||||||
length1Ref.current.dispatchEvent(new Event('input', { bubbles: true }));
|
|
||||||
}
|
|
||||||
// 다시 포커스를 주어 키패드가 유지되도록 함 (필요시)
|
|
||||||
length1Ref.current.focus();
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 키보드 입력 처리
|
// 키보드 입력 처리
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleKeyDown = (e) => {
|
const handleKeyDown = (e) => {
|
||||||
|
|
||||||
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
|
||||||
// 계산기 값이 확정된 후 초기화하기 위해 약간의 지연을 줌
|
|
||||||
setTimeout(() => {
|
|
||||||
resetCalculatorValue();
|
|
||||||
}, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 계산기 키패드가 보이는지 확인
|
// 계산기 키패드가 보이는지 확인
|
||||||
const keypadVisible = document.querySelector('.keypad-container')
|
const keypadVisible = document.querySelector('.keypad-container')
|
||||||
|
|
||||||
@ -123,58 +88,37 @@ export default function OuterLineWall({ props }) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button className="reset-btn" onClick={() => setLength1(0)}></button>
|
||||||
className="reset-btn"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
resetCalculatorValue()
|
|
||||||
}}
|
|
||||||
></button>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
||||||
<div className="grid-direction">
|
<div className="grid-direction">
|
||||||
<button
|
<button
|
||||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
|
|
||||||
setArrow1('↑')
|
setArrow1('↑')
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
resetCalculatorValue()
|
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<button
|
<button
|
||||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
setArrow1('↓')
|
setArrow1('↓')
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
resetCalculatorValue()
|
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<button
|
<button
|
||||||
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
setArrow1('←')
|
setArrow1('←')
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
resetCalculatorValue()
|
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<button
|
<button
|
||||||
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
setArrow1('→')
|
setArrow1('→')
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
resetCalculatorValue()
|
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user