fix: tabs-component 충돌 해결 - origin/main 버전으로 복원
배지 기능(HEAD)을 제거하고 origin/main 버전을 유지함. 충돌 시 작성하지 않은 파일은 main 버전을 그대로 사용. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
afeca4fa00
commit
87b8aec759
|
|
@ -32,8 +32,10 @@ const TabsDesignEditor: React.FC<{
|
||||||
// 🆕 탭 컴포넌트 size가 업데이트되면 resizeSize 초기화
|
// 🆕 탭 컴포넌트 size가 업데이트되면 resizeSize 초기화
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (resizeSize && lastResizedCompId && !resizingCompId) {
|
if (resizeSize && lastResizedCompId && !resizingCompId) {
|
||||||
const targetComp = activeTab?.components?.find((c) => c.id === lastResizedCompId);
|
const targetComp = activeTab?.components?.find(c => c.id === lastResizedCompId);
|
||||||
if (targetComp && targetComp.size?.width === resizeSize.width && targetComp.size?.height === resizeSize.height) {
|
if (targetComp &&
|
||||||
|
targetComp.size?.width === resizeSize.width &&
|
||||||
|
targetComp.size?.height === resizeSize.height) {
|
||||||
setResizeSize(null);
|
setResizeSize(null);
|
||||||
setLastResizedCompId(null);
|
setLastResizedCompId(null);
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +48,7 @@ const TabsDesignEditor: React.FC<{
|
||||||
"px-4 py-2 text-sm font-medium cursor-pointer transition-colors",
|
"px-4 py-2 text-sm font-medium cursor-pointer transition-colors",
|
||||||
isActive
|
isActive
|
||||||
? "bg-background border-b-2 border-primary text-primary"
|
? "bg-background border-b-2 border-primary text-primary"
|
||||||
: "text-muted-foreground hover:text-foreground hover:bg-muted/50",
|
: "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -73,7 +75,7 @@ const TabsDesignEditor: React.FC<{
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[activeTabId, component, onUpdateComponent, tabs],
|
[activeTabId, component, onUpdateComponent, tabs]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 10px 단위 스냅 함수
|
// 10px 단위 스냅 함수
|
||||||
|
|
@ -149,7 +151,7 @@ const TabsDesignEditor: React.FC<{
|
||||||
y: newY,
|
y: newY,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: c,
|
: c
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +175,7 @@ const TabsDesignEditor: React.FC<{
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
document.addEventListener("mousemove", handleMouseMove);
|
||||||
document.addEventListener("mouseup", handleMouseUp);
|
document.addEventListener("mouseup", handleMouseUp);
|
||||||
},
|
},
|
||||||
[activeTabId, component, onUpdateComponent, tabs, snapTo10],
|
[activeTabId, component, onUpdateComponent, tabs, snapTo10]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 리사이즈 시작 핸들러
|
// 리사이즈 시작 핸들러
|
||||||
|
|
@ -250,7 +252,7 @@ const TabsDesignEditor: React.FC<{
|
||||||
height: newHeight,
|
height: newHeight,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: c,
|
: c
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -274,13 +276,13 @@ const TabsDesignEditor: React.FC<{
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
document.addEventListener("mousemove", handleMouseMove);
|
||||||
document.addEventListener("mouseup", handleMouseUp);
|
document.addEventListener("mouseup", handleMouseUp);
|
||||||
},
|
},
|
||||||
[activeTabId, component, onUpdateComponent, tabs],
|
[activeTabId, component, onUpdateComponent, tabs]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-background flex h-full w-full flex-col overflow-hidden rounded-lg border">
|
<div className="flex h-full w-full flex-col overflow-hidden rounded-lg border bg-background">
|
||||||
{/* 탭 헤더 */}
|
{/* 탭 헤더 */}
|
||||||
<div className="bg-muted/30 flex items-center border-b">
|
<div className="flex items-center border-b bg-muted/30">
|
||||||
{tabs.length > 0 ? (
|
{tabs.length > 0 ? (
|
||||||
tabs.map((tab) => (
|
tabs.map((tab) => (
|
||||||
<div
|
<div
|
||||||
|
|
@ -293,13 +295,12 @@ const TabsDesignEditor: React.FC<{
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tab.label || "탭"}
|
{tab.label || "탭"}
|
||||||
{tab.components && tab.components.length > 0 && (
|
|
||||||
<span className="text-muted-foreground ml-1 text-xs">({tab.components.length})</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="text-muted-foreground px-4 py-2 text-sm">탭이 없습니다</div>
|
<div className="px-4 py-2 text-sm text-muted-foreground">
|
||||||
|
탭이 없습니다
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -312,7 +313,10 @@ const TabsDesignEditor: React.FC<{
|
||||||
onClick={() => onSelectTabComponent?.(activeTabId, "", {} as TabInlineComponent)}
|
onClick={() => onSelectTabComponent?.(activeTabId, "", {} as TabInlineComponent)}
|
||||||
>
|
>
|
||||||
{activeTab ? (
|
{activeTab ? (
|
||||||
<div ref={containerRef} className="absolute inset-0 overflow-auto p-2">
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className="absolute inset-0 overflow-auto p-2"
|
||||||
|
>
|
||||||
{activeTab.components && activeTab.components.length > 0 ? (
|
{activeTab.components && activeTab.components.length > 0 ? (
|
||||||
<div className="relative" style={{ minHeight: "100%", minWidth: "100%" }}>
|
<div className="relative" style={{ minHeight: "100%", minWidth: "100%" }}>
|
||||||
{activeTab.components.map((comp: TabInlineComponent) => {
|
{activeTab.components.map((comp: TabInlineComponent) => {
|
||||||
|
|
@ -341,8 +345,8 @@ const TabsDesignEditor: React.FC<{
|
||||||
};
|
};
|
||||||
|
|
||||||
// 드래그 중인 컴포넌트는 dragPosition 사용, 아니면 저장된 position 사용
|
// 드래그 중인 컴포넌트는 dragPosition 사용, 아니면 저장된 position 사용
|
||||||
const displayX = isDragging && dragPosition ? dragPosition.x : comp.position?.x || 0;
|
const displayX = isDragging && dragPosition ? dragPosition.x : (comp.position?.x || 0);
|
||||||
const displayY = isDragging && dragPosition ? dragPosition.y : comp.position?.y || 0;
|
const displayY = isDragging && dragPosition ? dragPosition.y : (comp.position?.y || 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -356,11 +360,7 @@ const TabsDesignEditor: React.FC<{
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
console.log("🔍 [탭 컴포넌트] 클릭:", {
|
console.log("🔍 [탭 컴포넌트] 클릭:", { activeTabId, compId: comp.id, hasOnSelectTabComponent: !!onSelectTabComponent });
|
||||||
activeTabId,
|
|
||||||
compId: comp.id,
|
|
||||||
hasOnSelectTabComponent: !!onSelectTabComponent,
|
|
||||||
});
|
|
||||||
onSelectTabComponent?.(activeTabId, comp.id, comp);
|
onSelectTabComponent?.(activeTabId, comp.id, comp);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -368,14 +368,14 @@ const TabsDesignEditor: React.FC<{
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-4 cursor-move items-center justify-between rounded-t border border-b-0 bg-gray-100 px-1",
|
"flex h-4 cursor-move items-center justify-between rounded-t border border-b-0 bg-gray-100 px-1",
|
||||||
isSelected ? "border-primary" : "border-gray-200",
|
isSelected ? "border-primary" : "border-gray-200"
|
||||||
)}
|
)}
|
||||||
style={{ width: comp.size?.width || 200 }}
|
style={{ width: comp.size?.width || 200 }}
|
||||||
onMouseDown={(e) => handleDragStart(e, comp)}
|
onMouseDown={(e) => handleDragStart(e, comp)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-0.5">
|
<div className="flex items-center gap-0.5">
|
||||||
<Move className="h-2.5 w-2.5 text-gray-400" />
|
<Move className="h-2.5 w-2.5 text-gray-400" />
|
||||||
<span className="max-w-[100px] truncate text-[9px] text-gray-500">
|
<span className="text-[9px] text-gray-500 truncate max-w-[100px]">
|
||||||
{comp.label || comp.componentType}
|
{comp.label || comp.componentType}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -406,17 +406,19 @@ const TabsDesignEditor: React.FC<{
|
||||||
{/* 실제 컴포넌트 렌더링 - 핸들 아래에 별도 영역 */}
|
{/* 실제 컴포넌트 렌더링 - 핸들 아래에 별도 영역 */}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative overflow-hidden rounded-b border bg-white shadow-sm",
|
"relative rounded-b border bg-white shadow-sm overflow-hidden",
|
||||||
isSelected ? "border-primary ring-primary/30 ring-2" : "border-gray-200",
|
isSelected
|
||||||
|
? "border-primary ring-2 ring-primary/30"
|
||||||
|
: "border-gray-200",
|
||||||
(isDragging || isResizing) && "opacity-80 shadow-lg",
|
(isDragging || isResizing) && "opacity-80 shadow-lg",
|
||||||
!(isDragging || isResizing) && "transition-all",
|
!(isDragging || isResizing) && "transition-all"
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
width: displayWidth,
|
width: displayWidth,
|
||||||
height: displayHeight,
|
height: displayHeight,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="pointer-events-none h-full w-full">
|
<div className="h-full w-full pointer-events-none">
|
||||||
<DynamicComponentRenderer
|
<DynamicComponentRenderer
|
||||||
component={componentData as any}
|
component={componentData as any}
|
||||||
isDesignMode={true}
|
isDesignMode={true}
|
||||||
|
|
@ -429,17 +431,17 @@ const TabsDesignEditor: React.FC<{
|
||||||
<>
|
<>
|
||||||
{/* 오른쪽 가장자리 (너비 조절) */}
|
{/* 오른쪽 가장자리 (너비 조절) */}
|
||||||
<div
|
<div
|
||||||
className="hover:bg-primary/10 pointer-events-auto absolute top-0 right-0 z-10 h-full w-2 cursor-ew-resize"
|
className="absolute top-0 right-0 w-2 h-full cursor-ew-resize pointer-events-auto z-10 hover:bg-primary/10"
|
||||||
onMouseDown={(e) => handleResizeStart(e, comp, "e")}
|
onMouseDown={(e) => handleResizeStart(e, comp, "e")}
|
||||||
/>
|
/>
|
||||||
{/* 아래 가장자리 (높이 조절) */}
|
{/* 아래 가장자리 (높이 조절) */}
|
||||||
<div
|
<div
|
||||||
className="hover:bg-primary/10 pointer-events-auto absolute bottom-0 left-0 z-10 h-2 w-full cursor-ns-resize"
|
className="absolute bottom-0 left-0 w-full h-2 cursor-ns-resize pointer-events-auto z-10 hover:bg-primary/10"
|
||||||
onMouseDown={(e) => handleResizeStart(e, comp, "s")}
|
onMouseDown={(e) => handleResizeStart(e, comp, "s")}
|
||||||
/>
|
/>
|
||||||
{/* 오른쪽 아래 모서리 (너비+높이 조절) */}
|
{/* 오른쪽 아래 모서리 (너비+높이 조절) */}
|
||||||
<div
|
<div
|
||||||
className="hover:bg-primary/20 pointer-events-auto absolute right-0 bottom-0 z-20 h-3 w-3 cursor-nwse-resize"
|
className="absolute bottom-0 right-0 w-3 h-3 cursor-nwse-resize pointer-events-auto z-20 hover:bg-primary/20"
|
||||||
onMouseDown={(e) => handleResizeStart(e, comp, "se")}
|
onMouseDown={(e) => handleResizeStart(e, comp, "se")}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
@ -452,14 +454,20 @@ const TabsDesignEditor: React.FC<{
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full flex-col items-center justify-center rounded border-2 border-dashed border-gray-300 bg-gray-50/50">
|
<div className="flex h-full w-full flex-col items-center justify-center rounded border-2 border-dashed border-gray-300 bg-gray-50/50">
|
||||||
<Plus className="mb-2 h-8 w-8 text-gray-400" />
|
<Plus className="mb-2 h-8 w-8 text-gray-400" />
|
||||||
<p className="text-sm font-medium text-gray-500">컴포넌트를 드래그하여 추가</p>
|
<p className="text-sm font-medium text-gray-500">
|
||||||
<p className="mt-1 text-xs text-gray-400">좌측 패널에서 컴포넌트를 이 영역에 드롭하세요</p>
|
컴포넌트를 드래그하여 추가
|
||||||
|
</p>
|
||||||
|
<p className="mt-1 text-xs text-gray-400">
|
||||||
|
좌측 패널에서 컴포넌트를 이 영역에 드롭하세요
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<p className="text-muted-foreground text-sm">설정 패널에서 탭을 추가하세요</p>
|
<p className="text-sm text-muted-foreground">
|
||||||
|
설정 패널에서 탭을 추가하세요
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -469,8 +477,14 @@ const TabsDesignEditor: React.FC<{
|
||||||
|
|
||||||
// TabsWidget 래퍼 컴포넌트
|
// TabsWidget 래퍼 컴포넌트
|
||||||
const TabsWidgetWrapper: React.FC<any> = (props) => {
|
const TabsWidgetWrapper: React.FC<any> = (props) => {
|
||||||
const { component, isDesignMode, onUpdateComponent, onSelectTabComponent, selectedTabComponentId, ...restProps } =
|
const {
|
||||||
props;
|
component,
|
||||||
|
isDesignMode,
|
||||||
|
onUpdateComponent,
|
||||||
|
onSelectTabComponent,
|
||||||
|
selectedTabComponentId,
|
||||||
|
...restProps
|
||||||
|
} = props;
|
||||||
|
|
||||||
// componentConfig에서 탭 정보 추출
|
// componentConfig에서 탭 정보 추출
|
||||||
const tabsConfig = component.componentConfig || {};
|
const tabsConfig = component.componentConfig || {};
|
||||||
|
|
@ -501,7 +515,8 @@ const TabsWidgetWrapper: React.FC<any> = (props) => {
|
||||||
persistSelection: tabsConfig.persistSelection || false,
|
persistSelection: tabsConfig.persistSelection || false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TabsWidget = require("@/components/screen/widgets/TabsWidget").TabsWidget;
|
const TabsWidget =
|
||||||
|
require("@/components/screen/widgets/TabsWidget").TabsWidget;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full w-full">
|
<div className="h-full w-full">
|
||||||
|
|
@ -518,7 +533,8 @@ const TabsWidgetWrapper: React.FC<any> = (props) => {
|
||||||
ComponentRegistry.registerComponent({
|
ComponentRegistry.registerComponent({
|
||||||
id: "v2-tabs-widget",
|
id: "v2-tabs-widget",
|
||||||
name: "탭 컴포넌트",
|
name: "탭 컴포넌트",
|
||||||
description: "탭별로 컴포넌트를 자유롭게 배치할 수 있는 레이아웃 컴포넌트입니다.",
|
description:
|
||||||
|
"탭별로 컴포넌트를 자유롭게 배치할 수 있는 레이아웃 컴포넌트입니다.",
|
||||||
category: ComponentCategory.LAYOUT,
|
category: ComponentCategory.LAYOUT,
|
||||||
webType: "text" as any,
|
webType: "text" as any,
|
||||||
component: TabsWidgetWrapper,
|
component: TabsWidgetWrapper,
|
||||||
|
|
@ -580,12 +596,20 @@ ComponentRegistry.registerComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
// 에디터 모드에서의 렌더링 - 탭 선택 및 컴포넌트 드롭 지원
|
// 에디터 모드에서의 렌더링 - 탭 선택 및 컴포넌트 드롭 지원
|
||||||
renderEditor: ({ component, isSelected, onClick, onDragStart, onDragEnd }) => {
|
renderEditor: ({
|
||||||
|
component,
|
||||||
|
isSelected,
|
||||||
|
onClick,
|
||||||
|
onDragStart,
|
||||||
|
onDragEnd,
|
||||||
|
}) => {
|
||||||
const tabsConfig = (component as any).componentConfig || {};
|
const tabsConfig = (component as any).componentConfig || {};
|
||||||
const tabs: TabItem[] = tabsConfig.tabs || [];
|
const tabs: TabItem[] = tabsConfig.tabs || [];
|
||||||
|
|
||||||
// 에디터 모드에서 선택된 탭 상태 관리
|
// 에디터 모드에서 선택된 탭 상태 관리
|
||||||
const [activeTabId, setActiveTabId] = useState<string>(tabs[0]?.id || "");
|
const [activeTabId, setActiveTabId] = useState<string>(
|
||||||
|
tabs[0]?.id || ""
|
||||||
|
);
|
||||||
|
|
||||||
const activeTab = tabs.find((t) => t.id === activeTabId);
|
const activeTab = tabs.find((t) => t.id === activeTabId);
|
||||||
|
|
||||||
|
|
@ -596,19 +620,19 @@ ComponentRegistry.registerComponent({
|
||||||
"px-4 py-2 text-sm font-medium cursor-pointer transition-colors",
|
"px-4 py-2 text-sm font-medium cursor-pointer transition-colors",
|
||||||
isActive
|
isActive
|
||||||
? "bg-background border-b-2 border-primary text-primary"
|
? "bg-background border-b-2 border-primary text-primary"
|
||||||
: "text-muted-foreground hover:text-foreground hover:bg-muted/50",
|
: "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="bg-background flex h-full w-full flex-col overflow-hidden rounded-lg border"
|
className="flex h-full w-full flex-col overflow-hidden rounded-lg border bg-background"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
onDragStart={onDragStart}
|
onDragStart={onDragStart}
|
||||||
onDragEnd={onDragEnd}
|
onDragEnd={onDragEnd}
|
||||||
>
|
>
|
||||||
{/* 탭 헤더 */}
|
{/* 탭 헤더 */}
|
||||||
<div className="bg-muted/30 flex items-center border-b">
|
<div className="flex items-center border-b bg-muted/30">
|
||||||
{tabs.length > 0 ? (
|
{tabs.length > 0 ? (
|
||||||
tabs.map((tab) => (
|
tabs.map((tab) => (
|
||||||
<div
|
<div
|
||||||
|
|
@ -620,13 +644,12 @@ ComponentRegistry.registerComponent({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tab.label || "탭"}
|
{tab.label || "탭"}
|
||||||
{tab.components && tab.components.length > 0 && (
|
|
||||||
<span className="text-muted-foreground ml-1 text-xs">({tab.components.length})</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="text-muted-foreground px-4 py-2 text-sm">탭이 없습니다</div>
|
<div className="px-4 py-2 text-sm text-muted-foreground">
|
||||||
|
탭이 없습니다
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -653,8 +676,12 @@ ComponentRegistry.registerComponent({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex h-full flex-col items-center justify-center">
|
<div className="flex h-full flex-col items-center justify-center">
|
||||||
<span className="text-xs font-medium text-gray-600">{comp.label || comp.componentType}</span>
|
<span className="text-xs font-medium text-gray-600">
|
||||||
<span className="text-[10px] text-gray-400">{comp.componentType}</span>
|
{comp.label || comp.componentType}
|
||||||
|
</span>
|
||||||
|
<span className="text-[10px] text-gray-400">
|
||||||
|
{comp.componentType}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -662,21 +689,27 @@ ComponentRegistry.registerComponent({
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full flex-col items-center justify-center rounded border-2 border-dashed border-gray-300 bg-gray-50/50">
|
<div className="flex h-full w-full flex-col items-center justify-center rounded border-2 border-dashed border-gray-300 bg-gray-50/50">
|
||||||
<Plus className="mb-2 h-8 w-8 text-gray-400" />
|
<Plus className="mb-2 h-8 w-8 text-gray-400" />
|
||||||
<p className="text-sm font-medium text-gray-500">컴포넌트를 드래그하여 추가</p>
|
<p className="text-sm font-medium text-gray-500">
|
||||||
<p className="mt-1 text-xs text-gray-400">좌측 패널에서 컴포넌트를 이 영역에 드롭하세요</p>
|
컴포넌트를 드래그하여 추가
|
||||||
|
</p>
|
||||||
|
<p className="mt-1 text-xs text-gray-400">
|
||||||
|
좌측 패널에서 컴포넌트를 이 영역에 드롭하세요
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<p className="text-muted-foreground text-sm">설정 패널에서 탭을 추가하세요</p>
|
<p className="text-sm text-muted-foreground">
|
||||||
|
설정 패널에서 탭을 추가하세요
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 선택 표시 */}
|
{/* 선택 표시 */}
|
||||||
{isSelected && (
|
{isSelected && (
|
||||||
<div className="ring-primary pointer-events-none absolute inset-0 rounded-lg ring-2 ring-offset-2" />
|
<div className="pointer-events-none absolute inset-0 rounded-lg ring-2 ring-primary ring-offset-2" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -689,9 +722,11 @@ ComponentRegistry.registerComponent({
|
||||||
|
|
||||||
// 설정 패널
|
// 설정 패널
|
||||||
configPanel: React.lazy(() =>
|
configPanel: React.lazy(() =>
|
||||||
import("@/components/screen/config-panels/TabsConfigPanel").then((module) => ({
|
import("@/components/screen/config-panels/TabsConfigPanel").then(
|
||||||
default: module.TabsConfigPanel,
|
(module) => ({
|
||||||
})),
|
default: module.TabsConfigPanel,
|
||||||
|
})
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
// 검증 함수
|
// 검증 함수
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue