컴포넌트 추가방식 변경
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { ComponentRendererProps } from "@/types/component";
|
||||
import { RadioBasicConfig } from "./types";
|
||||
|
||||
export interface RadioBasicComponentProps extends ComponentRendererProps {
|
||||
config?: RadioBasicConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* RadioBasic 컴포넌트
|
||||
* radio-basic 컴포넌트입니다
|
||||
*/
|
||||
export const RadioBasicComponent: React.FC<RadioBasicComponentProps> = ({
|
||||
component,
|
||||
isDesignMode = false,
|
||||
isSelected = false,
|
||||
onClick,
|
||||
onDragStart,
|
||||
onDragEnd,
|
||||
config,
|
||||
className,
|
||||
style,
|
||||
...props
|
||||
}) => {
|
||||
// 컴포넌트 설정
|
||||
const componentConfig = {
|
||||
...config,
|
||||
...component.config,
|
||||
} as RadioBasicConfig;
|
||||
|
||||
// 스타일 계산 (위치는 RealtimePreviewDynamic에서 처리하므로 제외)
|
||||
const componentStyle: React.CSSProperties = {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
...component.style,
|
||||
...style,
|
||||
};
|
||||
|
||||
// 디자인 모드 스타일
|
||||
if (isDesignMode) {
|
||||
componentStyle.border = "1px dashed #cbd5e1";
|
||||
componentStyle.borderColor = isSelected ? "#3b82f6" : "#cbd5e1";
|
||||
}
|
||||
|
||||
// 이벤트 핸들러
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
onClick?.();
|
||||
};
|
||||
|
||||
// DOM에 전달하면 안 되는 React-specific props 필터링
|
||||
const {
|
||||
selectedScreen,
|
||||
onZoneComponentDrop,
|
||||
onZoneClick,
|
||||
componentConfig: _componentConfig,
|
||||
component: _component,
|
||||
isSelected: _isSelected,
|
||||
onClick: _onClick,
|
||||
onDragStart: _onDragStart,
|
||||
onDragEnd: _onDragEnd,
|
||||
size: _size,
|
||||
position: _position,
|
||||
style: _style,
|
||||
...domProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div style={componentStyle} className={className} {...domProps}>
|
||||
{/* 라벨 렌더링 */}
|
||||
{component.label && (
|
||||
<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={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: componentConfig.direction === "horizontal" ? "row" : "column",
|
||||
gap: "8px",
|
||||
padding: "8px",
|
||||
}}
|
||||
onClick={handleClick}
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd}
|
||||
>
|
||||
{(componentConfig.options || []).map((option, index) => (
|
||||
<label
|
||||
key={index}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "6px",
|
||||
cursor: "pointer",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name={component.id || "radio-group"}
|
||||
value={option.value}
|
||||
checked={component.value === option.value}
|
||||
disabled={componentConfig.disabled || false}
|
||||
required={componentConfig.required || false}
|
||||
style={{
|
||||
width: "16px",
|
||||
height: "16px",
|
||||
accentColor: "#3b82f6",
|
||||
}}
|
||||
onChange={(e) => {
|
||||
if (component.onChange) {
|
||||
component.onChange(e.target.value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span style={{ color: "#374151" }}>{option.label}</span>
|
||||
</label>
|
||||
))}
|
||||
{(!componentConfig.options || componentConfig.options.length === 0) && (
|
||||
<>
|
||||
<label style={{ display: "flex", alignItems: "center", gap: "6px", cursor: "pointer", fontSize: "14px" }}>
|
||||
<input
|
||||
type="radio"
|
||||
name={component.id || "radio-group"}
|
||||
value="option1"
|
||||
style={{ width: "16px", height: "16px", accentColor: "#3b82f6" }}
|
||||
/>
|
||||
<span>옵션 1</span>
|
||||
</label>
|
||||
<label style={{ display: "flex", alignItems: "center", gap: "6px", cursor: "pointer", fontSize: "14px" }}>
|
||||
<input
|
||||
type="radio"
|
||||
name={component.id || "radio-group"}
|
||||
value="option2"
|
||||
style={{ width: "16px", height: "16px", accentColor: "#3b82f6" }}
|
||||
/>
|
||||
<span>옵션 2</span>
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* RadioBasic 래퍼 컴포넌트
|
||||
* 추가적인 로직이나 상태 관리가 필요한 경우 사용
|
||||
*/
|
||||
export const RadioBasicWrapper: React.FC<RadioBasicComponentProps> = (props) => {
|
||||
return <RadioBasicComponent {...props} />;
|
||||
};
|
||||
Reference in New Issue
Block a user