ERP-node/popdocs/archive/V4_UNIFIED_DESIGN_SPEC.md

13 KiB

POP v4 통합 설계 모드 스펙

작성일: 2026-02-04 최종 업데이트: 2026-02-04 상태: Phase 3 완료 (visibility + 줄바꿈 컴포넌트)


개요

v3/v4 탭을 제거하고, v4 자동 모드를 기본으로 하되 모드별 오버라이드 기능을 지원하는 통합 설계 방식.


핵심 개념

기존 방식 (v3)

4개 모드 각각 설계 필요
태블릿 가로: 버튼 → col 1, row 1
태블릿 세로: 버튼 → col 1, row 5  (따로 설정)
모바일 가로: 버튼 → col 1, row 1  (따로 설정)
모바일 세로: 버튼 → col 1, row 10 (따로 설정)

새로운 방식 (v4 통합)

기본: 태블릿 가로에서 규칙 설정
      버튼 → width: fill, height: 48px

결과: 모든 모드에 자동 적용
      태블릿 가로: 버튼 너비 1024px, 높이 48px
      태블릿 세로: 버튼 너비 768px, 높이 48px
      모바일 가로: 버튼 너비 667px, 높이 48px
      모바일 세로: 버튼 너비 375px, 높이 48px

예외: 특정 모드에서 편집하면 오버라이드
      모바일 세로: 버튼 높이 36px (수동 설정)

현재 UI (Phase 1.5 완료)

┌─────────────────────────────────────────────────────────────────┐
│ ← 목록  화면명  *변경됨  [↶][↷]   자동 레이아웃 (v4)     [저장] │
├─────────────────────────────────────────────────────────────────┤
│ 편집 중: v4 (자동 반응형)                                       │
│ 규칙 기반 레이아웃                                              │
├────────────┬────────────────────────────────────┬───────────────┤
│ 컴포넌트    │  미리보기: [모바일↕][모바일↔]      │    속성       │
│            │           [태블릿↕][태블릿↔(기본)]  │               │
│ 필드       │  너비: [====●====] 1024 x 768      │               │
│ 버튼       │                                    │               │
│ 리스트     │  ┌──────────────────────────────┐  │ 탭: 크기      │
│ 인디케이터  │  │ [필드1] [필드2] [필드3]      │  │     설정      │
│ 스캐너     │  │ [필드4] [Spacer] [버튼]      │  │     표시 ⬅ 🆕│
│ 숫자패드   │  │                              │  │     데이터    │
│ 스페이서   │  │   (가로 배치 + 자동 줄바꿈)   │  │               │
│ 줄바꿈 🆕  │  │   (스크롤 가능)              │  │               │
│            │  └──────────────────────────────┘  │               │
│            │        태블릿 가로 (1024x768)      │               │
└────────────┴────────────────────────────────────┴───────────────┘

레이아웃 방식 (업계 표준)

서비스 방식
Figma Auto Layout (Flexbox)
Webflow Flexbox + CSS Grid
FlutterFlow Row/Column/Stack
Adalo 2.0 Flexbox + Constraints
POP v4 Flexbox (horizontal + wrap)

특수 컴포넌트 사용법

Spacer (빈 공간)

[버튼A] [Spacer(fill)] [버튼B]     → 버튼B가 오른쪽 끝으로
[Spacer] [컴포넌트] [Spacer]       → 컴포넌트가 가운데로
[Spacer(fill)] [컴포넌트]          → 컴포넌트가 오른쪽으로

줄바꿈 (Break) 🆕 Phase 3

[필드A] [필드B] [줄바꿈] [필드C]   → 필드C가 새 줄로 이동

태블릿: [필드A] [필드B] [필드C]    ← 줄바꿈 숨김 (한 줄)
모바일: [필드A] [필드B]            ← 줄바꿈 표시 (두 줄)
        [필드C]

프리셋 버튼 (4개 모드)

버튼 해상도 설명
모바일↕ 375 x 667 모바일 세로
모바일↔ 667 x 375 모바일 가로
태블릿↕ 768 x 1024 태블릿 세로
태블릿↔* 1024 x 768 태블릿 가로 (기본)

레이아웃 판별 로직

// 새 화면 또는 빈 레이아웃 → v4로 시작
const hasValidLayout = loadedLayout && loadedLayout.version;
const hasComponents = loadedLayout?.components && 
                      Object.keys(loadedLayout.components).length > 0;

if (hasValidLayout && hasComponents) {
  // v4면 v4, 그 외 v3로 변환
} else {
  // v4로 새로 시작
}

오버라이드 동작 (Phase 2 예정)

자동 감지 방식

  1. 사용자가 **태블릿 가로(기본)**에서 편집 → 기본 규칙 저장
  2. 사용자가 다른 모드에서 편집 → 해당 모드 오버라이드 자동 저장
  3. 편집 안 한 모드 → 기본 규칙에서 자동 계산

편집 상태 표시

상태 버튼 색상 설명
기본 (태블릿 가로) 강조 + "(기본)" 항상 표시
자동 기본 색상 편집 안 함
편집됨 강조 색상 오버라이드 있음

되돌리기

  • 편집된 모드에만 "자동으로 되돌리기" 버튼 활성화
  • 클릭 시 오버라이드 삭제 → 기본 규칙 복원

데이터 구조

PopLayoutDataV4 (Phase 2에서 수정 예정)

interface PopLayoutDataV4 {
  version: "pop-4.0";
  root: PopContainerV4;
  components: Record<string, PopComponentDefinitionV4>;
  dataFlow: PopDataFlow;
  settings: PopGlobalSettingsV4;
  
  // 모드별 오버라이드 (Phase 2에서 추가)
  overrides?: {
    mobile_portrait?: ModeOverride;
    mobile_landscape?: ModeOverride;
    tablet_portrait?: ModeOverride;
    // tablet_landscape는 기본이므로 오버라이드 없음
  };
}

interface ModeOverride {
  components?: Record<string, Partial<PopComponentDefinitionV4>>;
  containers?: Record<string, Partial<PopContainerV4>>; 
}

PopComponentDefinitionV4 (Phase 3에서 수정 예정)

interface PopComponentDefinitionV4 {
  type: PopComponentType;
  label?: string;
  size: PopSizeConstraintV4;
  alignSelf?: "start" | "center" | "end" | "stretch";
  
  // 모드별 표시 설정 (Phase 3에서 추가)
  visibility?: {
    mobile_portrait?: boolean;   // 기본 true
    mobile_landscape?: boolean;  // 기본 true
    tablet_portrait?: boolean;   // 기본 true
    tablet_landscape?: boolean;  // 기본 true
  };
}

컴포넌트 표시/숨김 (Phase 3 예정)

업계 표준 (Webflow, Figma)

  • 삭제가 아닌 숨김 처리
  • 특정 모드에서만 display: none
  • 언제든 다시 표시 가능

UI (속성 패널)

┌─────────────────────────┐
│ 버튼                    │
├─────────────────────────┤
│ 표시 설정               │
│ [x] 모바일 세로          │
│ [x] 모바일 가로          │
│ [x] 태블릿 세로          │
│ [x] 태블릿 가로          │
│                         │
│ (체크 해제 = 숨김)       │
└─────────────────────────┘

구현 상태

Phase 1: 기본 구조 (완료)

  • v3/v4 탭 제거 (자동 판별)
  • 새 화면 → v4로 시작
  • 기존 v3 화면 → v3로 로드 (하위 호환)
  • 4개 프리셋 버튼 (모바일↕, 모바일↔, 태블릿↕, 태블릿↔)
  • 기본 프리셋 표시 (태블릿 가로 + "(기본)")
  • 슬라이더 유지 (320~1200px, 비율 유지)
  • ComponentPaletteV4 생성

Phase 1.5: Flexbox 가로 배치 (완료)

  • Undo/Redo (Ctrl+Z / Ctrl+Shift+Z, 데스크탑 모드와 동일 방식)
  • 드래그 리사이즈 핸들
  • Flexbox 가로 배치 (direction: horizontal, wrap: true)
  • 컴포넌트 타입별 기본 크기 설정
  • Spacer 컴포넌트 (pop-spacer)
  • 컴포넌트 순서 변경 (드래그 앤 드롭)
  • 디바이스 스크린 무한 스크롤

Phase 1.6: 비율 스케일링 시스템 (완료)

  • 기준 너비 1024px (10인치 태블릿 가로)
  • 최대 너비 1366px (12인치 태블릿)
  • 뷰포트 감지 및 resize 이벤트 리스너
  • 컴포넌트 크기 스케일 적용 (fixedWidth/Height)
  • 컨테이너 스케일 적용 (gap, padding)
  • 디자인 모드 분리 (scale=1)
  • DndProvider 에러 수정

Phase 2: 오버라이드 기능 (다음)

  • ModeOverride 데이터 구조 추가
  • 편집 감지 → 자동 오버라이드 저장
  • 편집 상태 표시 (버튼 색상)
  • "자동으로 되돌리기" 버튼

Phase 3: 컴포넌트 표시/숨김

  • visibility 속성 추가
  • 속성 패널 체크박스 UI
  • 렌더러에서 visibility 처리

Phase 4: 순서 오버라이드

  • 모드별 children 순서 오버라이드
  • 드래그로 순서 변경 UI

관련 파일

파일 역할 상태
PopDesigner.tsx v3/v4 통합 디자이너 완료
PopCanvasV4.tsx v4 캔버스 (4개 프리셋 + 슬라이더) 완료
PopFlexRenderer.tsx v4 Flexbox 렌더러 + 비율 스케일링 완료
ComponentPaletteV4.tsx v4 컴포넌트 팔레트 완료
ComponentEditorPanelV4.tsx v4 속성 편집 패널 완료
pop-layout.ts v3/v4 타입 정의 완료, Phase 2-3에서 수정 예정
page.tsx (뷰어) v4 뷰어 + viewportWidth 감지 완료

비율 스케일링 시스템

업계 표준

Rockwell Automation HMI의 "Scale with Fixed Aspect Ratio" 방식 적용

원리

10인치(1024px) 기준으로 디자인 → 8~12인치에서 배치 유지, 크기만 비례 조정

계산

scale = viewportWidth / 1024
scaledWidth = originalWidth * scale
scaledHeight = originalHeight * scale
scaledGap = originalGap * scale
scaledPadding = originalPadding * scale

화면별 결과

화면 scale 200px 컴포넌트 8px gap
8인치 (800px) 0.78 156px 6px
10인치 (1024px) 1.00 200px 8px
12인치 (1366px) 1.33 266px 11px
14인치+ 1.33 (max) 266px + 여백 11px

적용 위치

파일 함수/변수 역할
PopFlexRenderer.tsx BASE_VIEWPORT_WIDTH 기준 너비 상수 (1024)
PopFlexRenderer.tsx calculateSizeStyle(size, settings, scale) 크기 스케일 적용
PopFlexRenderer.tsx ContainerRenderer.containerStyle gap, padding 스케일 적용
page.tsx viewportWidth state 뷰포트 너비 감지
page.tsx Math.min(window.innerWidth, 1366) 최대 너비 제한

Phase 3: Visibility + 줄바꿈 컴포넌트 (완료)

개요

모드별 컴포넌트 표시/숨김 제어 및 강제 줄바꿈 기능 추가.

추가 타입

visibility 속성

interface PopComponentDefinitionV4 {
  // 기존 속성...
  
  // 🆕 모드별 표시/숨김
  visibility?: {
    tablet_landscape?: boolean;
    tablet_portrait?: boolean;
    mobile_landscape?: boolean;
    mobile_portrait?: boolean;
  };
}

pop-break 컴포넌트

type PopComponentType =
  | "pop-field"
  | "pop-button"
  | "pop-list"
  | "pop-indicator"
  | "pop-scanner"
  | "pop-numpad"
  | "pop-spacer"
  | "pop-break";  // 🆕 줄바꿈

사용 예시

모바일 전용 버튼

{
  id: "call-button",
  type: "pop-button",
  label: "전화 걸기",
  visibility: {
    tablet_landscape: false,  // 태블릿: 숨김
    mobile_portrait: true,    // 모바일: 표시
  },
}

모드별 줄바꿈

레이아웃: [A] [B] [줄바꿈] [C] [D]

줄바꿈 visibility: { tablet_landscape: false, mobile_portrait: true }

결과:
태블릿: [A] [B] [C] [D]  (한 줄)
모바일: [A] [B]          (두 줄)
        [C] [D]

속성 패널 "표시" 탭

┌─────────────────────┐
│ 탭: 크기 설정 표시 📍│
├─────────────────────┤
│ 모드별 표시 설정     │
│ ☑ 태블릿 가로       │
│ ☑ 태블릿 세로       │
│ ☐ 모바일 가로 (숨김)│
│ ☑ 모바일 세로       │
└─────────────────────┘

참고 문서


이 문서는 v4 통합 설계 모드의 스펙을 정의합니다. 최종 업데이트: 2026-02-04 (Phase 3 완료)