feat: enhance split panel and tab component interactions

- Improved the drop handling logic for split panels and tabs, prioritizing the innermost container during drag-and-drop operations.
- Added internal state management for selected components within split panels to enhance user experience.
- Updated the rendering logic to ensure proper data attributes are set for design mode, facilitating better component identification.
- Enhanced the dynamic component rendering to support updates and selections for nested components within tabs and split panels.

Made-with: Cursor
This commit is contained in:
kjs
2026-03-12 09:49:17 +09:00
parent b1e50f2e0a
commit 014979bebf
9 changed files with 481 additions and 400 deletions

View File

@@ -271,8 +271,9 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const [dragPosition, setDragPosition] = useState<{ x: number; y: number } | null>(null);
const [resizingCompId, setResizingCompId] = useState<string | null>(null);
const [resizeSize, setResizeSize] = useState<{ width: number; height: number } | null>(null);
// 🆕 외부에서 전달받은 선택 상태 사용 (탭 컴포넌트와 동일 구조)
const selectedPanelComponentId = externalSelectedPanelComponentId || null;
// 내부 선택 상태 (외부 prop 없을 때 fallback)
const [internalSelectedCompId, setInternalSelectedCompId] = useState<string | null>(null);
const selectedPanelComponentId = externalSelectedPanelComponentId ?? internalSelectedCompId;
// 🆕 커스텀 모드: 분할패널 내 탭 컴포넌트의 선택 상태 관리
const [nestedTabSelectedCompId, setNestedTabSelectedCompId] = useState<string | undefined>(undefined);
const rafRef = useRef<number | null>(null);
@@ -3052,9 +3053,15 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
</div>
</div>
)}
<CardContent className="flex-1 overflow-auto p-4">
<CardContent
className="flex-1 overflow-auto p-4"
{...(isDesignMode ? {
"data-split-panel-container": "true",
"data-component-id": component.id,
"data-panel-side": "left",
} : {})}
>
{/* 좌측 데이터 목록/테이블/커스텀 */}
{console.log("🔍 [SplitPanel] 왼쪽 패널 displayMode:", componentConfig.leftPanel?.displayMode, "isDesignMode:", isDesignMode)}
{componentConfig.leftPanel?.displayMode === "custom" ? (
// 🆕 커스텀 모드: 패널 안에 자유롭게 컴포넌트 배치
<div
@@ -3158,10 +3165,10 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
}}
onClick={(e) => {
e.stopPropagation();
// 패널 컴포넌트 선택 시 탭 내 선택 해제
if (comp.componentType !== "v2-tabs-widget") {
setNestedTabSelectedCompId(undefined);
}
setInternalSelectedCompId(comp.id);
onSelectPanelComponent?.("left", comp.id, comp);
}}
>
@@ -3917,7 +3924,14 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
</div>
</div>
)}
<CardContent className="flex-1 overflow-auto p-4">
<CardContent
className="flex-1 overflow-auto p-4"
{...(isDesignMode ? {
"data-split-panel-container": "true",
"data-component-id": component.id,
"data-panel-side": "right",
} : {})}
>
{/* 추가 탭 컨텐츠 */}
{activeTabIndex > 0 ? (
(() => {
@@ -4289,6 +4303,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
if (comp.componentType !== "v2-tabs-widget") {
setNestedTabSelectedCompId(undefined);
}
setInternalSelectedCompId(comp.id);
onSelectPanelComponent?.("right", comp.id, comp);
}}
>