128 lines
3.8 KiB
TypeScript
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} />;
|
|
};
|