fix: 너비 입력 시 완전 자유 입력 허용 (로컬 상태 사용)

- 문제: 너비 입력 시 onChange에서 즉시 업데이트되어 30에서 3을 지우기 어려움
- 해결:
  1. localWidth 상태 추가
  2. onChange: 로컬 상태만 업데이트 (완전 자유 입력)
  3. onBlur/Enter: 실제 업데이트 + 10px 단위 스냅
  4. useEffect로 컴포넌트 변경 시 localWidth 동기화
- 영향:
  - 30 입력 시 3, 0 모두 자유롭게 지우고 입력 가능
  - 포커스 아웃 시에만 10px 단위로 정렬
This commit is contained in:
kjs 2025-11-10 15:54:07 +09:00
parent 5d374f902a
commit 2148e8e019
1 changed files with 26 additions and 7 deletions

View File

@ -105,8 +105,9 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
const { webTypes } = useWebTypes({ active: "Y" });
const [localComponentDetailType, setLocalComponentDetailType] = useState<string>("");
// 높이 입력 로컬 상태 (격자 스냅 방지)
// 높이/너비 입력 로컬 상태 (자유 입력 허용)
const [localHeight, setLocalHeight] = useState<string>("");
const [localWidth, setLocalWidth] = useState<string>("");
// 새로운 컴포넌트 시스템의 webType 동기화
useEffect(() => {
@ -125,6 +126,13 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
}
}, [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<UnifiedPropertiesPanelProps> = ({
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"