ERP-node/frontend/lib/registry/components/text-display/TextDisplayComponent.tsx

128 lines
3.8 KiB
TypeScript

"use client";
import React from "react";
import { ComponentRendererProps } from "../../types";
import { TextDisplayConfig } from "./types";
export interface TextDisplayComponentProps extends ComponentRendererProps {
// 추가 props가 필요한 경우 여기에 정의
}
/**
* TextDisplay 컴포넌트
* text-display 컴포넌트입니다
*/
export const TextDisplayComponent: React.FC<TextDisplayComponentProps> = ({
component,
isDesignMode = false,
isSelected = false,
onClick,
onDragStart,
onDragEnd,
...props
}) => {
const componentConfig = (component.componentConfig || {}) as TextDisplayConfig;
// 컴포넌트 스타일 계산
const componentStyle: React.CSSProperties = {
position: "absolute",
left: `${component.style?.positionX || 0}px`,
top: `${component.style?.positionY || 0}px`,
width: `${component.style?.width || 150}px`,
height: `${component.style?.height || 24}px`,
zIndex: component.style?.positionZ || 1,
cursor: isDesignMode ? "pointer" : "default",
border: isSelected ? "2px solid #3b82f6" : "none",
outline: isSelected ? "none" : undefined,
};
// 클릭 핸들러
const handleClick = (e: React.MouseEvent) => {
if (isDesignMode) {
e.stopPropagation();
onClick?.(e);
} else {
// 실제 모드에서의 클릭 처리
componentConfig.onClick?.();
}
};
// className 생성
const className = ["text-display-component", isSelected ? "selected" : "", componentConfig.disabled ? "disabled" : ""]
.filter(Boolean)
.join(" ");
// DOM props 필터링 (React 관련 props 제거)
const {
component: _component,
isDesignMode: _isDesignMode,
isSelected: _isSelected,
isInteractive: _isInteractive,
screenId: _screenId,
tableName: _tableName,
onRefresh: _onRefresh,
onClose: _onClose,
formData: _formData,
onFormDataChange: _onFormDataChange,
componentConfig: _componentConfig,
...domProps
} = props;
// 텍스트 스타일 계산
const textStyle: React.CSSProperties = {
fontSize: componentConfig.fontSize || "14px",
fontWeight: componentConfig.fontWeight || "normal",
color: componentConfig.color || "#374151",
textAlign: componentConfig.textAlign || "left",
backgroundColor: componentConfig.backgroundColor || "transparent",
padding: componentConfig.padding || "0",
borderRadius: componentConfig.borderRadius || "0",
border: componentConfig.border || "none",
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent:
componentConfig.textAlign === "center"
? "center"
: componentConfig.textAlign === "right"
? "flex-end"
: "flex-start",
wordBreak: "break-word",
overflow: "hidden",
};
return (
<div style={componentStyle} className={className} {...domProps}>
{/* 라벨 렌더링 */}
{component.label && component.style?.labelDisplay !== false && (
<label
style={{
position: "absolute",
top: "-25px",
left: "0px",
fontSize: component.style?.labelFontSize || "14px",
color: component.style?.labelColor || "#374151",
fontWeight: "500",
}}
>
{component.label}
{component.required && <span style={{ color: "#ef4444" }}>*</span>}
</label>
)}
<div style={textStyle} onClick={handleClick} onDragStart={onDragStart} onDragEnd={onDragEnd}>
{componentConfig.text || "텍스트를 입력하세요"}
</div>
</div>
);
};
/**
* TextDisplay 래퍼 컴포넌트
* 추가적인 로직이나 상태 관리가 필요한 경우 사용
*/
export const TextDisplayWrapper: React.FC<TextDisplayComponentProps> = (props) => {
return <TextDisplayComponent {...props} />;
};