POP v4 제약조건 기반 레이아웃 타입 정의 및 문서 구조 재정리

- v4 타입 추가: PopLayoutDataV4, PopContainerV4, PopSizeConstraintV4
- 핵심 변경: 4모드 위치 지정 → 단일 소스 규칙 기반 (fill/fixed/hug)
- 생성 함수: createEmptyPopLayoutV4(), isV4Layout() 타입 가드
- 문서 정리: popdocs/ 폴더로 통합, 기존 문서 archive/로 이동
This commit is contained in:
SeongHyun Kim
2026-02-04 10:14:05 +09:00
parent de2163bcef
commit 223f5c0251
16 changed files with 2448 additions and 4 deletions

View File

@@ -1,9 +1,173 @@
// POP 디자이너 레이아웃 타입 정의
// v3.0: 섹션 제거, 컴포넌트 직접 배치
// 그리드 기반 반응형 레이아웃 (픽셀 좌표 없음, 그리드 셀 기반)
// v4.0: 제약조건 기반, 단일 소스 → 자동 적응 (Flexbox)
// v3.0: 4모드 그리드 기반 (CSS Grid)
// ========================================
// 레이아웃 모드 키 (4가지)
// v4.0 제약조건 기반 레이아웃
// ========================================
// 핵심: 1번 설계 → 모든 화면 자동 적응
// - 위치(col/row) 대신 규칙(fill/fixed/hug) 설정
// - Flexbox로 렌더링, 자동 줄바꿈
/**
* v4 레이아웃 (반응형)
* - 단일 소스: 4모드 따로 설계 X
* - 규칙 기반: 컴포넌트가 어떻게 반응할지 정의
*/
export interface PopLayoutDataV4 {
version: "pop-4.0";
// 루트 컨테이너 (스택)
root: PopContainerV4;
// 컴포넌트 정의 (ID → 정의)
components: Record<string, PopComponentDefinitionV4>;
// 데이터 흐름 (기존과 동일)
dataFlow: PopDataFlow;
// 전역 설정
settings: PopGlobalSettingsV4;
// 메타데이터
metadata?: PopLayoutMetadata;
}
/**
* v4 컨테이너 (스택)
* - Flexbox 기반
* - 자식: 컴포넌트 ID 또는 중첩 컨테이너
*/
export interface PopContainerV4 {
id: string;
type: "stack";
// 방향: 가로 또는 세로
direction: "horizontal" | "vertical";
// 줄바꿈 허용
wrap: boolean;
// 간격 (px)
gap: number;
// 정렬
alignItems: "start" | "center" | "end" | "stretch";
justifyContent: "start" | "center" | "end" | "space-between";
// 패딩 (px)
padding?: number;
// 반응형 규칙 (선택)
responsive?: PopResponsiveRuleV4[];
// 자식 요소
children: (string | PopContainerV4)[];
}
/**
* 반응형 규칙
* - 특정 너비 이하에서 속성 변경
*/
export interface PopResponsiveRuleV4 {
// 이 너비 이하에서 적용 (px)
breakpoint: number;
// 변경할 속성들
direction?: "horizontal" | "vertical";
gap?: number;
hidden?: boolean; // 컨테이너 숨김
}
/**
* v4 컴포넌트 정의
* - 크기 제약 기반
*/
export interface PopComponentDefinitionV4 {
id: string;
type: PopComponentType;
label?: string;
// 크기 제약 (핵심)
size: PopSizeConstraintV4;
// 개별 정렬 (컨테이너 설정 덮어쓰기)
alignSelf?: "start" | "center" | "end" | "stretch";
// 반응형 숨김
hideBelow?: number; // 이 너비 이하에서 숨김
// 기존 속성
dataBinding?: PopDataBinding;
style?: PopStylePreset;
config?: PopComponentConfig;
}
/**
* 크기 제약
* - fixed: 고정 px
* - fill: 남은 공간 채움
* - hug: 내용에 맞춤
*/
export interface PopSizeConstraintV4 {
width: "fixed" | "fill" | "hug";
height: "fixed" | "fill" | "hug";
// fixed일 때 값
fixedWidth?: number;
fixedHeight?: number;
// 최소/최대
minWidth?: number;
maxWidth?: number;
minHeight?: number;
}
/**
* v4 전역 설정
*/
export interface PopGlobalSettingsV4 {
// 터치 최소 크기 (px)
touchTargetMin: number; // 기본 48
// 모드
mode: "normal" | "industrial"; // industrial: 터치 60px
// 기본 간격
defaultGap: number; // 기본 8
// 기본 패딩
defaultPadding: number; // 기본 16
}
// ========================================
// v4 생성 함수
// ========================================
export const createEmptyPopLayoutV4 = (): PopLayoutDataV4 => ({
version: "pop-4.0",
root: {
id: "root",
type: "stack",
direction: "vertical",
wrap: false,
gap: 8,
alignItems: "stretch",
justifyContent: "start",
padding: 16,
children: [],
},
components: {},
dataFlow: { connections: [] },
settings: {
touchTargetMin: 48,
mode: "normal",
defaultGap: 8,
defaultPadding: 16,
},
});
// ========================================
// 레이아웃 모드 키 (v3용)
// ========================================
export type PopLayoutModeKey =
| "tablet_landscape" // 태블릿 가로 (1024x768)
@@ -127,7 +291,11 @@ export interface PopLayoutDataV1 {
// 통합 타입
// ========================================
export type PopLayoutData = PopLayoutDataV1 | PopLayoutDataV2 | PopLayoutDataV3;
export type PopLayoutData = PopLayoutDataV1 | PopLayoutDataV2 | PopLayoutDataV3 | PopLayoutDataV4;
export function isV4Layout(data: PopLayoutData): data is PopLayoutDataV4 {
return data.version === "pop-4.0";
}
export function isV3Layout(data: PopLayoutData): data is PopLayoutDataV3 {
return data.version === "pop-3.0";