ERP-node/popdocs/decisions/005-breakpoint-redesign.md

5.2 KiB

ADR 005: 브레이크포인트 재설계 (기기 기반)

날짜: 2026-02-06
상태: 채택
의사결정자: 시스템 아키텍트


상황 (Context)

문제 1: 뷰어에서 모드 전환 불일치

브라우저 수동 리사이즈 시:
- useResponsiveMode 훅: 768px 이상 → "tablet" 판정
- GRID_BREAKPOINTS: 768~839px → "mobile_landscape" (6칸)

결과: 768~839px 구간에서 모드 불일치 발생

문제 2: 기존 브레이크포인트 근거 부족

기존 설정:
- mobile_portrait: ~599px
- mobile_landscape: 600~839px  
- tablet_portrait: 840~1023px

문제: 실제 기기 뷰포트와 맞지 않음
- iPad Mini 세로: 768px (mobile_landscape로 분류됨)

사용자 요구사항

"현장 모바일 기기가 최소 8인치 ~ 최대 14인치, 핸드폰은 아이폰 미니 ~ 갤럭시 울트라 사이즈"


연구 (Research)

실제 기기 CSS 뷰포트 조사 (2026년 기준)

기기 화면 크기 CSS 뷰포트 너비
iPhone SE 4.7" 375px
iPhone 16 Pro 6.3" 402px
Galaxy S25 Ultra 6.9" 440px
iPad Mini 7 8.3" 768px
iPad Pro 11 11" 834px (세로), 1194px (가로)
iPad Pro 13 13" 1024px (세로), 1366px (가로)

업계 표준 브레이크포인트

프레임워크 모바일/태블릿 경계 태블릿/데스크톱 경계
Tailwind CSS 768px 1024px
Bootstrap 5 768px 992px
Material Design 3 600px 840px

공통점: 768px, 1024px가 거의 표준


결정 (Decision)

채택: 기기 기반 브레이크포인트

모드 너비 범위 변경 전 근거
mobile_portrait 0~479px 0~599px 스마트폰 세로 최대 440px
mobile_landscape 480~767px 600~839px 스마트폰 가로, 767px까지
tablet_portrait 768~1023px 840~1023px iPad Mini 768px 포함
tablet_landscape 1024px+ 동일 대형 태블릿 가로

핵심 변경

// pop-layout.ts - GRID_BREAKPOINTS
mobile_portrait:  { maxWidth: 479 }   // was 599
mobile_landscape: { minWidth: 480, maxWidth: 767 }  // was 600, 839
tablet_portrait:  { minWidth: 768, maxWidth: 1023 } // was 840, 1023
tablet_landscape: { minWidth: 1024 }  // 동일

// pop-layout.ts - detectGridMode()
if (viewportWidth < 480) return "mobile_portrait";   // was 600
if (viewportWidth < 768) return "mobile_landscape";  // was 840
if (viewportWidth < 1024) return "tablet_portrait";

// useDeviceOrientation.ts - BREAKPOINTS
TABLET_MIN: 768  // was 840

구현 (Implementation)

수정 파일

파일 변경 내용
pop-layout.ts GRID_BREAKPOINTS 값 수정, detectGridMode() 조건 수정
useDeviceOrientation.ts BREAKPOINTS.TABLET_MIN = 768
PopCanvas.tsx VIEWPORT_PRESETS width 값 조정
page.tsx (뷰어) detectGridMode() 사용으로 일관성 확보

뷰어 모드 감지 방식 변경

// 변경 전: useResponsiveModeWithOverride만 사용
const currentModeKey = getModeKey(deviceType, isLandscape);

// 변경 후: 프리뷰 모드와 일반 모드 분리
const currentModeKey = isPreviewMode
  ? getModeKey(deviceType, isLandscape)  // 프리뷰: 수동 선택
  : detectGridMode(viewportWidth);        // 일반: 너비 기반

결과 (Consequences)

긍정적 효과

효과 설명
기기 커버리지 아이폰 SE ~ 갤럭시 울트라, 8~14인치 태블릿 모두 포함
업계 표준 호환 768px, 1024px는 거의 모든 프레임워크 기준점
일관성 확보 GRID_BREAKPOINTS와 detectGridMode() 완전 일치
직관적 매핑 스마트폰 세로/가로, 태블릿 세로/가로 자연스럽게 분류

트레이드오프

항목 설명
기존 데이터 영향 600~767px 구간이 6칸→6칸 (영향 없음)
768~839px 변경 기존 6칸→8칸 (태블릿으로 재분류)

세로 자동 확장 (추가 결정)

배경

"세로는 신경쓸 필요가 없는 것 맞지? 그렇다면 캔버스도 세로 무한 스크롤이 가능해야겠네?"

결정

  1. 뷰포트 프리셋에서 height 제거 (width만 유지)
  2. 캔버스 높이 동적 계산 (컴포넌트 배치 기준)
  3. 항상 여유 행 3개 유지 (추가 배치 공간)
  4. 뷰어에서 터치 스크롤 지원

구현

// PopCanvas.tsx
const MIN_CANVAS_HEIGHT = 600;
const CANVAS_EXTRA_ROWS = 3;

const dynamicCanvasHeight = useMemo(() => {
  const maxRowEnd = visibleComps.reduce((max, comp) => {
    return Math.max(max, comp.row + comp.rowSpan);
  }, 1);
  
  const totalRows = maxRowEnd + CANVAS_EXTRA_ROWS;
  return Math.max(MIN_CANVAS_HEIGHT, totalRows * rowHeight);
}, [layout.components, ...]);

관련 문서


결론: 실제 기기 뷰포트 기반 브레이크포인트로 일관성 확보 + 세로 무한 스크롤로 UX 개선