fix: 화면 편집기에서 버튼 컴포넌트 선택 가능하도록 수정

- 문제: 버튼 컴포넌트 클릭 시 버튼 동작이 실행되어 선택되지 않음
- 해결:
  1. ButtonPrimaryComponent에서 디자인 모드일 때 <button> 대신 <div>로 렌더링
  2. ScreenDesigner의 ScreenPreviewProvider에서 isPreviewMode를 false로 설정
  3. 디자인 모드에서는 버튼 액션이 실행되지 않고 onClick만 전달되도록 수정
- 영향: button-primary 타입 버튼이 화면 편집기에서 정상적으로 선택 가능
This commit is contained in:
kjs 2025-11-10 15:36:18 +09:00
parent 2d832c56b6
commit cdf9c0e562
4 changed files with 85 additions and 43 deletions

View File

@ -563,7 +563,7 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
{/* 위젯 타입 - 동적 렌더링 (파일 컴포넌트 제외) */}
{type === "widget" && !isFileComponent(component) && (
<div className="pointer-events-none h-full w-full">
<div className="h-full w-full">
<WidgetRenderer
component={component}
isDesignMode={isDesignMode}

View File

@ -4124,7 +4124,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
}
return (
<ScreenPreviewProvider isPreviewMode={true}>
<ScreenPreviewProvider isPreviewMode={false}>
<div className="bg-background flex h-full w-full flex-col">
{/* 상단 슬림 툴바 */}
<SlimToolbar

View File

@ -14,10 +14,17 @@ export const ButtonWidget: React.FC<WebTypeComponentProps> = ({
required,
className,
style,
isDesignMode = false, // 디자인 모드 플래그
...restProps
}) => {
const handleClick = () => {
const handleClick = (e: React.MouseEvent) => {
// 디자인 모드에서는 아무것도 하지 않고 그냥 이벤트 전파
if (isDesignMode) {
return;
}
// 버튼 클릭 시 동작 (추후 버튼 액션 시스템과 연동)
// console.log("Button clicked:", config);
console.log("Button clicked:", config);
// onChange를 통해 클릭 이벤트 전달
if (onChange) {
@ -25,6 +32,25 @@ export const ButtonWidget: React.FC<WebTypeComponentProps> = ({
}
};
// 디자인 모드에서는 div로 렌더링하여 버튼 동작 완전 차단
if (isDesignMode) {
return (
<div
onClick={handleClick} // 클릭 핸들러 추가하여 이벤트 전파
className={`flex items-center justify-center rounded-md bg-blue-600 px-4 text-sm font-medium text-white ${className || ""} `}
style={{
...style,
width: "100%",
height: "100%",
cursor: "pointer", // 선택 가능하도록 포인터 표시
}}
title={config?.tooltip || placeholder}
>
{config?.label || config?.text || value || placeholder || "버튼"}
</div>
);
}
return (
<button
type="button"

View File

@ -528,14 +528,8 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
}
}
return (
<>
<div style={componentStyle} className={className} {...safeDomProps}>
<button
type={componentConfig.actionType || "button"}
disabled={componentConfig.disabled || false}
className="transition-colors duration-150 hover:opacity-90 active:scale-95 transition-transform"
style={{
// 공통 버튼 스타일
const buttonElementStyle: React.CSSProperties = {
width: "100%",
height: "100%",
minHeight: "40px",
@ -562,14 +556,36 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
...(isInteractive && component.style ? Object.fromEntries(
Object.entries(component.style).filter(([key]) => key !== 'width' && key !== 'height')
) : {}),
}}
};
const buttonContent = processedConfig.text !== undefined ? processedConfig.text : component.label || "버튼";
return (
<>
<div style={componentStyle} className={className} {...safeDomProps}>
{isDesignMode ? (
// 디자인 모드: div로 렌더링하여 선택 가능하게 함
<div
className="transition-colors duration-150 hover:opacity-90"
style={buttonElementStyle}
onClick={handleClick}
>
{buttonContent}
</div>
) : (
// 일반 모드: button으로 렌더링
<button
type={componentConfig.actionType || "button"}
disabled={componentConfig.disabled || false}
className="transition-colors duration-150 hover:opacity-90 active:scale-95 transition-transform"
style={buttonElementStyle}
onClick={handleClick}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
>
{/* 🔧 빈 문자열도 허용 (undefined일 때만 기본값 적용) */}
{processedConfig.text !== undefined ? processedConfig.text : component.label || "버튼"}
{buttonContent}
</button>
)}
</div>
{/* 확인 다이얼로그 - EditModal보다 위에 표시하도록 z-index 최상위로 설정 */}