From 2148e8e019ca6b71b4b1d35a8fdcf8723962e8df Mon Sep 17 00:00:00 2001 From: kjs Date: Mon, 10 Nov 2025 15:54:07 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=84=88=EB=B9=84=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=20=EC=8B=9C=20=EC=99=84=EC=A0=84=20=EC=9E=90=EC=9C=A0=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=ED=97=88=EC=9A=A9=20(=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=20=EC=82=AC=EC=9A=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 문제: 너비 입력 시 onChange에서 즉시 업데이트되어 30에서 3을 지우기 어려움 - 해결: 1. localWidth 상태 추가 2. onChange: 로컬 상태만 업데이트 (완전 자유 입력) 3. onBlur/Enter: 실제 업데이트 + 10px 단위 스냅 4. useEffect로 컴포넌트 변경 시 localWidth 동기화 - 영향: - 30 입력 시 3, 0 모두 자유롭게 지우고 입력 가능 - 포커스 아웃 시에만 10px 단위로 정렬 --- .../screen/panels/UnifiedPropertiesPanel.tsx | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/frontend/components/screen/panels/UnifiedPropertiesPanel.tsx b/frontend/components/screen/panels/UnifiedPropertiesPanel.tsx index 838842f8..84297aa7 100644 --- a/frontend/components/screen/panels/UnifiedPropertiesPanel.tsx +++ b/frontend/components/screen/panels/UnifiedPropertiesPanel.tsx @@ -105,8 +105,9 @@ export const UnifiedPropertiesPanel: React.FC = ({ const { webTypes } = useWebTypes({ active: "Y" }); const [localComponentDetailType, setLocalComponentDetailType] = useState(""); - // 높이 입력 로컬 상태 (격자 스냅 방지) + // 높이/너비 입력 로컬 상태 (자유 입력 허용) const [localHeight, setLocalHeight] = useState(""); + const [localWidth, setLocalWidth] = useState(""); // 새로운 컴포넌트 시스템의 webType 동기화 useEffect(() => { @@ -125,6 +126,13 @@ export const UnifiedPropertiesPanel: React.FC = ({ } }, [selectedComponent?.size?.height, selectedComponent?.id]); + // 너비 값 동기화 + useEffect(() => { + if (selectedComponent?.size?.width !== undefined) { + setLocalWidth(String(selectedComponent.size.width)); + } + }, [selectedComponent?.size?.width, selectedComponent?.id]); + // 격자 설정 업데이트 함수 (early return 이전에 정의) const updateGridSetting = (key: string, value: any) => { if (onGridSettingsChange && gridSettings) { @@ -415,19 +423,30 @@ export const UnifiedPropertiesPanel: React.FC = ({ min={10} max={3840} step="1" - value={selectedComponent.size?.width || 100} + value={localWidth} onChange={(e) => { - const value = parseInt(e.target.value, 10); - if (!isNaN(value) && value >= 10) { - handleUpdate("size.width", value); - } + // 입력 중에는 로컬 상태만 업데이트 (자유 입력) + setLocalWidth(e.target.value); }} onBlur={(e) => { + // 포커스를 잃을 때 10px 단위로 스냅 const value = parseInt(e.target.value, 10); if (!isNaN(value) && value >= 10) { - // 포커스 아웃 시 10px 단위로 스냅 const snappedValue = Math.round(value / 10) * 10; handleUpdate("size.width", snappedValue); + setLocalWidth(String(snappedValue)); + } + }} + onKeyDown={(e) => { + // Enter 키를 누르면 즉시 적용 (10px 단위로 스냅) + if (e.key === "Enter") { + const value = parseInt(e.currentTarget.value, 10); + if (!isNaN(value) && value >= 10) { + const snappedValue = Math.round(value / 10) * 10; + handleUpdate("size.width", snappedValue); + setLocalWidth(String(snappedValue)); + } + e.currentTarget.blur(); // 포커스 제거 } }} className="h-6 w-full px-2 py-0 text-xs"