"use client"; import React, { useEffect, useRef } from "react"; import { AutoRegisteringComponentRenderer } from "../../AutoRegisteringComponentRenderer"; import { V2InputDefinition } from "./index"; import { V2Input } from "@/components/v2/V2Input"; import { isColumnRequiredByMeta } from "../../DynamicComponentRenderer"; /** * dataBinding이 설정된 v2-input을 위한 wrapper * v2-table-list의 선택 이벤트를 window CustomEvent로 수신하여 * 선택된 행의 특정 컬럼 값을 자동으로 formData에 반영 */ function DataBindingWrapper({ dataBinding, columnName, onFormDataChange, children, }: { dataBinding: { sourceComponentId: string; sourceColumn: string }; columnName: string; onFormDataChange?: (field: string, value: any) => void; children: React.ReactNode; }) { const lastBoundValueRef = useRef(null); const onFormDataChangeRef = useRef(onFormDataChange); onFormDataChangeRef.current = onFormDataChange; useEffect(() => { if (!dataBinding?.sourceComponentId || !dataBinding?.sourceColumn) return; const handler = (e: Event) => { const detail = (e as CustomEvent).detail; if (!detail || detail.source !== dataBinding.sourceComponentId) return; const selectedRow = detail.data?.[0]; const value = selectedRow?.[dataBinding.sourceColumn] ?? ""; if (value !== lastBoundValueRef.current) { lastBoundValueRef.current = value; onFormDataChangeRef.current?.(columnName, value); } }; window.addEventListener("v2-table-selection", handler); return () => window.removeEventListener("v2-table-selection", handler); }, [dataBinding?.sourceComponentId, dataBinding?.sourceColumn, columnName]); return <>{children}; } /** * V2Input 렌더러 * 자동 등록 시스템을 사용하여 컴포넌트를 레지스트리에 등록 */ export class V2InputRenderer extends AutoRegisteringComponentRenderer { static componentDefinition = V2InputDefinition; render(): React.ReactElement { const { component, formData, onFormDataChange, isDesignMode, isSelected, isInteractive, ...restProps } = this.props; const config = component.componentConfig || component.config || {}; const columnName = component.columnName; const tableName = component.tableName || this.props.tableName; const currentValue = formData?.[columnName] ?? component.value ?? ""; const handleChange = (value: any) => { if (isInteractive && onFormDataChange && columnName) { onFormDataChange(columnName, value); } }; const style = component.style || {}; const labelDisplay = style.labelDisplay ?? (component as any).labelDisplay; const effectiveLabel = labelDisplay === true ? style.labelText || component.label : undefined; const dataBinding = config.dataBinding || (component as any).dataBinding || config.componentConfig?.dataBinding; const inputElement = ( ); // dataBinding이 있으면 wrapper로 감싸서 이벤트 구독 if (dataBinding?.sourceComponentId && dataBinding?.sourceColumn) { return ( {inputElement} ); } return inputElement; } } // 자동 등록 실행 V2InputRenderer.registerSelf(); // Hot Reload 지원 (개발 모드) if (process.env.NODE_ENV === "development") { V2InputRenderer.enableHotReload(); }