7.6 KiB
7.6 KiB
2026-02-06 작업 기록
요약
v5.1 자동 줄바꿈 + 검토 필요 시스템 완성, 브레이크포인트 재설계, 세로 자동 확장 구현
완료
브레이크포인트 재설계
- GRID_BREAKPOINTS 값 수정 (기기 기반)
- detectGridMode() 조건 수정
- useDeviceOrientation.ts TABLET_MIN 768로 변경
- 뷰어에서 detectGridMode() 사용하여 일관성 확보
세로 자동 확장
- VIEWPORT_PRESETS에서 height 속성 제거
- dynamicCanvasHeight useMemo 추가
- MIN_CANVAS_HEIGHT, CANVAS_EXTRA_ROWS 상수 추가
- gridLabels 동적 계산 (행 수 자동 조정)
- gridCells 동적 계산 (PopRenderer)
- 뷰어 프리뷰 모드 스크롤 지원
자동 줄바꿈 시스템 (v5.1)
- convertAndResolvePositions() 자동 줄바꿈 로직
- 원본 col 보존 로직
- 초과 컴포넌트 맨 아래 배치
- colSpan 자동 축소
검토 필요 시스템
- needsReview() 함수 추가
- OutOfBoundsPanel → ReviewPanel 변경
- 파란색 테마 (안내 느낌)
- 클릭 시 컴포넌트 선택
버그 수정
- hiddenComponentIds 중복 정의 에러 수정
- useDrop 의존성 배열 수정
- 검토 필요 패널 모드별 표시 불일치 수정
그리드 셀 크기 강제 고정 (v5.2.1)
- gridAutoRows → gridTemplateRows 변경 (행 높이 강제 고정)
- dynamicRowCount를 gridStyle과 gridCells에서 공유
- 컴포넌트 overflow: visible → overflow: hidden 변경
- PopRenderer dynamicRowCount에서 숨김 컴포넌트 제외
- PopCanvas와 PopRenderer의 여유행 기준 통일 (+3)
- 디버깅용 console.log 2개 삭제
- 뷰어 page.tsx viewportWidth 선언 순서 수정
브레이크포인트 변경 상세
변경 전 → 변경 후
| 모드 | 변경 전 | 변경 후 | 근거 |
|---|---|---|---|
| mobile_portrait | ~599px | ~479px | 스마트폰 세로 최대 440px |
| mobile_landscape | 600~839px | 480~767px | 767px까지 스마트폰 |
| tablet_portrait | 840~1023px | 768~1023px | iPad Mini 768px 포함 |
| tablet_landscape | 1024px+ | 동일 | 변경 없음 |
연구 결과 (기기별 CSS 뷰포트)
| 기기 | CSS 뷰포트 너비 |
|---|---|
| iPhone SE | 375px |
| iPhone 16 Pro | 402px |
| Galaxy S25 Ultra | 440px |
| iPad Mini 7 | 768px |
| iPad Pro 11 | 834px (세로), 1194px (가로) |
| iPad Pro 13 | 1024px (세로), 1366px (가로) |
세로 자동 확장 상세
핵심 상수
const MIN_CANVAS_HEIGHT = 600; // 최소 캔버스 높이 (px)
const CANVAS_EXTRA_ROWS = 3; // 항상 유지되는 여유 행 수
동적 높이 계산 로직
const dynamicCanvasHeight = useMemo(() => {
const visibleComps = Object.values(layout.components)
.filter(comp => !hiddenComponentIds.includes(comp.id));
if (visibleComps.length === 0) return MIN_CANVAS_HEIGHT;
const maxRowEnd = visibleComps.reduce((max, comp) => {
const pos = getEffectivePosition(comp);
return Math.max(max, pos.row + pos.rowSpan);
}, 1);
const totalRows = maxRowEnd + CANVAS_EXTRA_ROWS;
const height = totalRows * (rowHeight + gap) + padding * 2;
return Math.max(MIN_CANVAS_HEIGHT, height);
}, [dependencies]);
영향받는 영역
| 영역 | 변경 |
|---|---|
| 캔버스 컨테이너 | minHeight: dynamicCanvasHeight |
| 디바이스 스크린 | minHeight: dynamicCanvasHeight |
| 행 라벨 | 동적 행 수 계산 |
| 격자 셀 | 동적 행 수 계산 |
자동 줄바꿈 로직 상세
처리 단계
1. 비율 변환 + 원본 col 보존
converted = map(comp => ({
position: convertPositionToMode(comp.position),
originalCol: comp.position.col, // 원본 보존
}))
2. 정상 vs 초과 분리
normalComponents = filter(originalCol <= targetColumns)
overflowComponents = filter(originalCol > targetColumns)
3. 초과 컴포넌트 맨 아래 배치
maxRow = normalComponents의 최대 (row + rowSpan - 1)
overflowComponents → col=1, row=maxRow+1
4. colSpan 자동 축소
if (colSpan > targetColumns) colSpan = targetColumns
5. 겹침 해결
resolveOverlaps([...normalComponents, ...wrappedComponents])
대화 핵심
반응형 불일치 문제
사용자 리포트:
"아이폰 SE, iPad Pro 프리셋은 잘 되는데, 브라우저 수동 리사이즈 시 6칸 모드가 적용 안 되는 것 같아"
원인 분석:
- useResponsiveMode: width/height 비율로 landscape/portrait 판정
- GRID_BREAKPOINTS: 순수 너비 기반
- 768~839px 구간에서 불일치 발생
해결:
- 뷰어에서 detectGridMode(viewportWidth) 사용
- 프리뷰 모드만 useResponsiveModeWithOverride 유지
세로 무한 스크롤 결정
사용자 질문:
"우리 화면 모드는 너비만 신경쓰면 되잖아? 세로는 무한 스크롤이 가능해야 하겠네?"
확인 사항:
- 너비만 신경쓰면 됨 ✅
- 캔버스 세로 무한 스크롤 필요 ✅
- 뷰어에서 터치 스크롤 지원 ✅
구현 방식 선택:
- 수동 행 추가 방식 vs 자동 확장 방식 (채택)
- 이유: 여유 공간 3행 자동 유지, 사용자 부담 최소화
빌드 결과
exit_code: 0
주요 변경 파일: 6개
관련 링크
- ADR: decisions/005-breakpoint-redesign.md
- ADR: decisions/006-auto-wrap-review-system.md
- 이전 세션: sessions/2026-02-05.md
이번 작업에서 배운 것
새로 알게 된 기술 개념
- gridAutoRows vs gridTemplateRows:
gridAutoRows는 행의 최소 높이만 보장하고 콘텐츠에 따라 늘어날 수 있음.gridTemplateRows는 행 높이를 강제 고정함. 가이드 셀과 컴포넌트가 같은 Grid 컨테이너에 있을 때, 컴포넌트 콘텐츠가 행 높이를 밀어내면 인접한 빈 가이드 셀 크기도 함께 변해 시각적 불일치가 발생함.
발생했던 에러와 원인 패턴
| 에러 | 원인 패턴 |
|---|---|
| 그리드 셀 크기 불균일 | 같은 CSS Grid에서 gridAutoRows(최소값)를 사용하면 콘텐츠가 행 높이를 변형시킴 |
| Canvas vs Renderer 행 수 불일치 | 같은 데이터(행 수)를 두 곳에서 계산하면서 필터 조건(숨김 제외)이 달랐음 |
| 디버깅 console.log 잔존 | 기능 완료 후 정리 단계를 생략함 |
| viewportWidth 참조 순서 | 변수 사용 코드가 선언 코드보다 위에 위치 (JS 호이스팅으로 동작은 하지만 가독성 저하) |
다음에 비슷한 작업할 때 주의할 점
- CSS Grid에서 "고정 크기" 셀이 필요하면
gridTemplateRows를 사용하고,gridAutoRows는 동적 추가행 대비용으로만 유지 - 같은 데이터를 여러 곳에서 계산할 때, 필터 조건이 동일한지 반드시 비교 (숨김 제외 등)
- 기능 완료 후
console.log를 Grep으로 검색하여 디버깅 로그 정리 - 변수 선언 순서는 의존 관계 순서와 일치시켜야 가독성과 유지보수성 확보
중단점
다음 작업: Phase 4 실제 컴포넌트 구현
- pop-label, pop-button 등 실제 렌더링 구현
- 데이터 바인딩 연결
- STATUS.md의 "다음 작업" 섹션 참조
다음 작업자 참고
-
테스트 필요
- 아이폰 SE 실기기 테스트
- iPad Mini 세로 모드 확인
- 브라우저 리사이즈로 모드 전환 확인
-
향후 작업
- Phase 4: 실제 컴포넌트 구현 (pop-label, pop-button 등)
- 데이터 바인딩 연결
- 워크플로우 연동