371 lines
11 KiB
TypeScript
371 lines
11 KiB
TypeScript
/**
|
|
* 컴포넌트 시스템 타입 정의
|
|
* 레이아웃 시스템과 동일한 패턴으로 설계된 새로운 컴포넌트 관리 시스템
|
|
*/
|
|
|
|
import React from "react";
|
|
import type { WebType } from "./screen";
|
|
|
|
/**
|
|
* 컴포넌트 카테고리 열거형
|
|
* 기존의 하드코딩된 카테고리를 타입 안전한 enum으로 대체
|
|
*/
|
|
export enum ComponentCategory {
|
|
UI = "ui", // 기본 UI 컴포넌트 (버튼, 입력 등)
|
|
INPUT = "input", // 입력 컴포넌트 (텍스트, 셀렉트, 체크박스 등)
|
|
DISPLAY = "display", // 표시 컴포넌트 (라벨, 이미지, 아이콘 등)
|
|
ACTION = "action", // 액션 컴포넌트 (버튼, 링크 등)
|
|
LAYOUT = "layout", // 레이아웃 컴포넌트 (컨테이너, 그룹 등)
|
|
CHART = "chart", // 차트 컴포넌트 (그래프, 차트 등)
|
|
FORM = "form", // 폼 컴포넌트 (폼 그룹, 필드셋 등)
|
|
MEDIA = "media", // 미디어 컴포넌트 (이미지, 비디오 등)
|
|
NAVIGATION = "navigation", // 네비게이션 컴포넌트 (메뉴, 탭 등)
|
|
FEEDBACK = "feedback", // 피드백 컴포넌트 (알림, 토스트 등)
|
|
UTILITY = "utility", // 유틸리티 컴포넌트 (로딩, 스피너 등)
|
|
CONTAINER = "container", // 컨테이너 컴포넌트 (패널, 카드 등)
|
|
SYSTEM = "system", // 시스템 컴포넌트 (에러 바운더리 등)
|
|
ADMIN = "admin", // 관리자 전용 컴포넌트
|
|
CUSTOM = "custom", // 커스텀 컴포넌트
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 설정 인터페이스
|
|
* 각 컴포넌트의 고유한 설정값들을 타입 안전하게 관리
|
|
*/
|
|
export interface ComponentConfig {
|
|
[key: string]: any;
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 크기 정의
|
|
*/
|
|
export interface ComponentSize {
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
// screen.ts에서 자동생성 관련 타입들을 import
|
|
export type { AutoGenerationType, AutoGenerationConfig } from "./screen";
|
|
|
|
/**
|
|
* 컴포넌트 렌더러 Props
|
|
* 모든 컴포넌트 렌더러가 받는 공통 Props
|
|
*/
|
|
export interface ComponentRendererProps {
|
|
component: any; // ComponentData from screen.ts
|
|
isDesignMode?: boolean;
|
|
isSelected?: boolean;
|
|
isInteractive?: boolean;
|
|
onClick?: () => void;
|
|
onDragStart?: (e: React.DragEvent) => void;
|
|
onDragEnd?: (e: React.DragEvent) => void;
|
|
onUpdate?: (updates: Partial<any>) => void;
|
|
className?: string;
|
|
style?: React.CSSProperties;
|
|
formData?: Record<string, any>;
|
|
onFormDataChange?: (fieldName: string, value: any) => void;
|
|
|
|
// 새로운 기능들
|
|
autoGeneration?: AutoGenerationConfig; // 자동생성 설정
|
|
hidden?: boolean; // 숨김 기능 (편집기에서는 연하게, 실제 화면에서는 숨김)
|
|
|
|
// 설정 변경 핸들러
|
|
onConfigChange?: (config: any) => void;
|
|
|
|
[key: string]: any;
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 렌더러 클래스 인터페이스
|
|
*/
|
|
export interface ComponentRendererClass {
|
|
new (props: ComponentRendererProps): {
|
|
render(): React.ReactElement;
|
|
};
|
|
componentDefinition: ComponentDefinition;
|
|
registerSelf(): void;
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 정의 인터페이스
|
|
* 각 컴포넌트의 메타데이터와 설정을 담는 핵심 인터페이스
|
|
*/
|
|
export interface ComponentDefinition {
|
|
// 기본 정보
|
|
id: string; // 고유 ID (kebab-case)
|
|
name: string; // 한글 표시명
|
|
nameEng?: string; // 영문명
|
|
description: string; // 설명
|
|
|
|
// 분류 및 타입
|
|
category: ComponentCategory; // 카테고리 (enum)
|
|
webType: WebType; // 웹 타입 (기존 WebType 재사용)
|
|
|
|
// React 컴포넌트
|
|
component: React.ComponentType<any>; // 실제 React 컴포넌트
|
|
renderer?: ComponentRendererClass; // 렌더러 클래스 (선택사항)
|
|
|
|
// 설정
|
|
defaultConfig: ComponentConfig; // 기본 설정값
|
|
defaultSize: ComponentSize; // 기본 크기
|
|
configPanel?: React.ComponentType<any>; // 설정 패널 컴포넌트
|
|
|
|
// UI 요소
|
|
icon?: React.ComponentType | string; // 아이콘 (컴포넌트 또는 문자열)
|
|
previewImage?: string; // 미리보기 이미지 URL
|
|
|
|
// 메타데이터
|
|
tags?: string[]; // 검색용 태그
|
|
version?: string; // 버전
|
|
author?: string; // 작성자
|
|
documentation?: string; // 문서 URL
|
|
|
|
// 검증 및 제약
|
|
validation?: ComponentValidation; // 유효성 검사 규칙
|
|
dependencies?: string[]; // 의존성 컴포넌트 ID
|
|
|
|
// 생성 정보
|
|
createdAt?: Date; // 생성일
|
|
updatedAt?: Date; // 수정일
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 유효성 검사 규칙
|
|
*/
|
|
export interface ComponentValidation {
|
|
required?: string[]; // 필수 속성들
|
|
minSize?: ComponentSize; // 최소 크기
|
|
maxSize?: ComponentSize; // 최대 크기
|
|
allowedParents?: string[]; // 허용되는 부모 컴포넌트 타입
|
|
allowedChildren?: string[]; // 허용되는 자식 컴포넌트 타입
|
|
maxLength?: { [field: string]: number }; // 필드별 최대 길이
|
|
pattern?: { [field: string]: RegExp }; // 필드별 정규식 패턴
|
|
custom?: (component: any) => string | null; // 커스텀 검증 함수
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 레지스트리 이벤트
|
|
*/
|
|
export interface ComponentRegistryEvent {
|
|
type: "component_registered" | "component_unregistered" | "component_updated";
|
|
data: ComponentDefinition;
|
|
timestamp: Date;
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 검색 옵션
|
|
*/
|
|
export interface ComponentSearchOptions {
|
|
query?: string; // 검색어
|
|
category?: ComponentCategory; // 카테고리 필터
|
|
webType?: WebType; // 웹타입 필터
|
|
tags?: string[]; // 태그 필터
|
|
author?: string; // 작성자 필터
|
|
limit?: number; // 결과 제한
|
|
offset?: number; // 시작 위치
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 통계 정보
|
|
*/
|
|
export interface ComponentStats {
|
|
total: number; // 전체 컴포넌트 수
|
|
byCategory: Array<{
|
|
// 카테고리별 통계
|
|
category: ComponentCategory;
|
|
count: number;
|
|
}>;
|
|
byWebType: Array<{
|
|
// 웹타입별 통계
|
|
webType: WebType;
|
|
count: number;
|
|
}>;
|
|
byAuthor: Array<{
|
|
// 작성자별 통계
|
|
author: string;
|
|
count: number;
|
|
}>;
|
|
recentlyAdded: ComponentDefinition[]; // 최근 추가된 컴포넌트
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 자동 발견 옵션
|
|
*/
|
|
export interface ComponentAutoDiscoveryOptions {
|
|
pattern?: string; // 파일 패턴
|
|
baseDir?: string; // 기본 디렉토리
|
|
verbose?: boolean; // 상세 로그
|
|
continueOnError?: boolean; // 오류 시 계속 진행
|
|
timeout?: number; // 타임아웃 (ms)
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 자동 발견 결과
|
|
*/
|
|
export interface ComponentDiscoveryResult {
|
|
success: boolean; // 성공 여부
|
|
componentsFound: number; // 발견된 컴포넌트 수
|
|
componentsLoaded: number; // 로드된 컴포넌트 수
|
|
errors: Error[]; // 발생한 오류들
|
|
duration: number; // 소요 시간 (ms)
|
|
details: ComponentModuleInfo[]; // 상세 정보
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 모듈 정보
|
|
*/
|
|
export interface ComponentModuleInfo {
|
|
path: string; // 파일 경로
|
|
id: string; // 컴포넌트 ID
|
|
name: string; // 컴포넌트 이름
|
|
loaded: boolean; // 로드 여부
|
|
error?: Error; // 오류 (있는 경우)
|
|
timestamp: number; // 타임스탬프
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 생성 옵션 (CLI용)
|
|
*/
|
|
export interface CreateComponentOptions {
|
|
id: string; // 컴포넌트 ID
|
|
name: string; // 컴포넌트 이름
|
|
nameEng?: string; // 영문명
|
|
description: string; // 설명
|
|
category: ComponentCategory; // 카테고리
|
|
webType: WebType; // 웹타입
|
|
defaultSize: ComponentSize; // 기본 크기
|
|
author?: string; // 작성자
|
|
tags?: string[]; // 태그
|
|
icon?: string; // 아이콘
|
|
template?: string; // 템플릿 이름
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 마이그레이션 옵션
|
|
*/
|
|
export interface ComponentMigrationOptions {
|
|
componentCode: string; // 기존 컴포넌트 코드
|
|
newId: string; // 새 컴포넌트 ID
|
|
preserveConfig?: boolean; // 설정 보존 여부
|
|
updateReferences?: boolean; // 참조 업데이트 여부
|
|
dryRun?: boolean; // 테스트 실행 여부
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 정의 생성 헬퍼 함수의 옵션
|
|
*/
|
|
export interface CreateComponentDefinitionOptions {
|
|
id: string;
|
|
name: string;
|
|
nameEng?: string;
|
|
description: string;
|
|
category: ComponentCategory;
|
|
webType: WebType;
|
|
component: React.ComponentType<any>;
|
|
renderer?: ComponentRendererClass;
|
|
defaultConfig?: ComponentConfig;
|
|
defaultSize: ComponentSize;
|
|
configPanel?: React.ComponentType<any>;
|
|
icon?: React.ComponentType | string;
|
|
previewImage?: string;
|
|
tags?: string[];
|
|
version?: string;
|
|
author?: string;
|
|
documentation?: string;
|
|
validation?: ComponentValidation;
|
|
dependencies?: string[];
|
|
}
|
|
|
|
/**
|
|
* 유틸리티 타입들
|
|
*/
|
|
export type ComponentId = string;
|
|
export type ComponentName = string;
|
|
export type ComponentCategoryKey = keyof typeof ComponentCategory;
|
|
|
|
/**
|
|
* 기본 상수들
|
|
*/
|
|
export const DEFAULT_COMPONENT_SIZE: ComponentSize = {
|
|
width: 200,
|
|
height: 36,
|
|
};
|
|
|
|
export const COMPONENT_CATEGORIES_INFO = {
|
|
[ComponentCategory.UI]: {
|
|
name: "UI",
|
|
description: "기본 UI 컴포넌트",
|
|
color: "#3b82f6",
|
|
},
|
|
[ComponentCategory.INPUT]: {
|
|
name: "입력",
|
|
description: "사용자 입력을 받는 컴포넌트",
|
|
color: "#10b981",
|
|
},
|
|
[ComponentCategory.DISPLAY]: {
|
|
name: "표시",
|
|
description: "정보를 표시하는 컴포넌트",
|
|
color: "#f59e0b",
|
|
},
|
|
[ComponentCategory.ACTION]: {
|
|
name: "액션",
|
|
description: "사용자 동작을 처리하는 컴포넌트",
|
|
color: "#ef4444",
|
|
},
|
|
[ComponentCategory.LAYOUT]: {
|
|
name: "레이아웃",
|
|
description: "화면 구조를 제공하는 컴포넌트",
|
|
color: "#8b5cf6",
|
|
},
|
|
[ComponentCategory.CHART]: {
|
|
name: "차트",
|
|
description: "데이터 시각화 컴포넌트",
|
|
color: "#3b83f6",
|
|
},
|
|
[ComponentCategory.FORM]: {
|
|
name: "폼",
|
|
description: "폼 관련 컴포넌트",
|
|
color: "#84cc16",
|
|
},
|
|
[ComponentCategory.MEDIA]: {
|
|
name: "미디어",
|
|
description: "이미지, 비디오 등 미디어 컴포넌트",
|
|
color: "#f97316",
|
|
},
|
|
[ComponentCategory.NAVIGATION]: {
|
|
name: "네비게이션",
|
|
description: "화면 이동을 도와주는 컴포넌트",
|
|
color: "#6366f1",
|
|
},
|
|
[ComponentCategory.FEEDBACK]: {
|
|
name: "피드백",
|
|
description: "사용자 피드백을 제공하는 컴포넌트",
|
|
color: "#ec4899",
|
|
},
|
|
[ComponentCategory.UTILITY]: {
|
|
name: "유틸리티",
|
|
description: "보조 기능 컴포넌트",
|
|
color: "#6b7280",
|
|
},
|
|
[ComponentCategory.CONTAINER]: {
|
|
name: "컨테이너",
|
|
description: "다른 컴포넌트를 담는 컨테이너",
|
|
color: "#3b83f6",
|
|
},
|
|
[ComponentCategory.SYSTEM]: {
|
|
name: "시스템",
|
|
description: "시스템 관련 컴포넌트",
|
|
color: "#1f2937",
|
|
},
|
|
[ComponentCategory.ADMIN]: {
|
|
name: "관리",
|
|
description: "관리자 전용 컴포넌트",
|
|
color: "#7c2d12",
|
|
},
|
|
[ComponentCategory.CUSTOM]: {
|
|
name: "커스텀",
|
|
description: "사용자 정의 컴포넌트",
|
|
color: "#059669",
|
|
},
|
|
} as const;
|