/** * 컴포넌트 시스템 타입 정의 * 레이아웃 시스템과 동일한 패턴으로 설계된 새로운 컴포넌트 관리 시스템 */ 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) => void; className?: string; style?: React.CSSProperties; formData?: Record; 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; // 실제 React 컴포넌트 renderer?: ComponentRendererClass; // 렌더러 클래스 (선택사항) // 설정 defaultConfig: ComponentConfig; // 기본 설정값 defaultSize: ComponentSize; // 기본 크기 configPanel?: React.ComponentType; // 설정 패널 컴포넌트 // 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; renderer?: ComponentRendererClass; defaultConfig?: ComponentConfig; defaultSize: ComponentSize; configPanel?: React.ComponentType; 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: "#212121", }, [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: "#212121", }, [ComponentCategory.SYSTEM]: { name: "시스템", description: "시스템 관련 컴포넌트", color: "#1f2937", }, [ComponentCategory.ADMIN]: { name: "관리", description: "관리자 전용 컴포넌트", color: "#7c2d12", }, [ComponentCategory.CUSTOM]: { name: "커스텀", description: "사용자 정의 컴포넌트", color: "#059669", }, } as const;