Files
vexplor/frontend/lib/registry/components/v2-text-display/TextDisplayComponent.tsx
DDD1542 942eb079e8 feat: ScreenModal 및 V2 컴포넌트 레이아웃 개선
- ScreenModal 컴포넌트의 모달 크기 조정을 위해 헤더 및 푸터 높이를 수정하고, 여백을 최소화하여 디자인 일치를 도모하였습니다.
- V2 컴포넌트에서 라벨 높이를 계산하여 절대 위치로 배치하도록 변경하였으며, 입력 필드 및 선택 컴포넌트의 구조를 개선하여 일관된 사용자 경험을 제공하였습니다.
- 플레이스홀더 기능을 추가하여 날짜 선택 시 사용자 편의성을 높였습니다.
- 관련 CSS 클래스를 업데이트하여 반응형 디자인을 강화하였습니다.
2026-02-04 11:26:51 +09:00

102 lines
3.3 KiB
TypeScript

"use client";
import React from "react";
import { ComponentRendererProps } from "../../types";
import { TextDisplayConfig } from "./types";
import { filterDOMProps } from "@/lib/utils/domPropsFilter";
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 domProps = filterDOMProps(props);
// 텍스트 스타일 계산
const textStyle: React.CSSProperties = {
fontSize: componentConfig.fontSize || "14px",
fontWeight: componentConfig.fontWeight || "normal",
color: componentConfig.color || "#212121",
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",
whiteSpace: "nowrap", // ← 한 줄로 유지 // ← 넘치는 부분 숨김
textOverflow: "ellipsis", // ← 넘치면 ... 표시 (선택사항)
transition: "all 0.2s ease-in-out",
boxShadow: "none",
};
return (
<div style={componentStyle} className={className} {...domProps}>
{/* v2-text-display는 텍스트 표시 전용이므로 별도 라벨 불필요 */}
<div style={textStyle} onClick={handleClick} onDragStart={onDragStart} onDragEnd={onDragEnd}>
{componentConfig.text || "텍스트를 입력하세요"}
</div>
</div>
);
};
/**
* TextDisplay 래퍼 컴포넌트
* 추가적인 로직이나 상태 관리가 필요한 경우 사용
*/
export const TextDisplayWrapper: React.FC<TextDisplayComponentProps> = (props) => {
return <TextDisplayComponent {...props} />;
};