중첩 그리드로 복잡한 UI 구조 구현하기
다양한 계층 구조를 필요로 하는 웹 애플리케이션에서 gridstack.js는 강력한 레이아웃 솔루션을 제공합니다. 특히 중첩 그리드(nested grid) 기능은 하나의 위젯 내부에 또 다른 동적 그리드를 생성할 수 있게 해주어, 대시보드, 프로젝트 관리 시스템, 실시간 데이터 분석 인터페이스와 같은 복잡한 사용자 환경을 직관적으로 구성할 수 있습니다.
중첩 그리드란?
중첩 그리드는 특정 그리드 아이템 안에 독립적인 하위 그리드를 포함하는 구조입니다. 이 방식은 단순한 컨테이너가 아니라, 드래그 앤 드롭, 크기 조절, 반응형 리사이징 등 부모 그리드와 동일한 기능을 갖춘 자율적인 그리드 시스템을 의미합니다. 이를 통해 다음과 같은 시나리오에 최적화된 UI를 구축할 수 있습니다:
- 팀별 작업 항목을 그룹화한 프로젝트 보드
- KPI 요약 영역 내부에 상세 차트 패널 배치
- 계층형 조직도 또는 장비 모니터링 트리
기본 중첩 그리드 생성
gridstack.js에서는 subGridOpts 옵션을 사용해 하위 그리드를 정의할 수 있습니다. 아래 코드는 메인 컨테이너에 두 개의 위젯을 배치하고, 첫 번째 위젯 안에 자식 그리드를 포함하는 예시입니다.
const mainGrid = GridStack.init({
cellHeight: 80,
margin: 10
}, '.main-container');
mainGrid.addWidget({
x: 0, y: 0, w: 6, h: 5,
subGridOpts: {
children: [
{ x: 0, y: 0, w: 3, content: '하위 항목 A' },
{ x: 3, y: 0, w: 3, content: '하위 항목 B' }
],
cellHeight: 60,
margin: 5
},
content: '하위 그리드 포함 위젯'
});
동적 중첩 그리드 활성화
v7 이상 버전부터는 subGridDynamic: true 설정을 통해 사용자가 드래그 중인 위젯을 특정 아이템 위에 올렸을 때 자동으로 하위 그리드를 생성할 수 있습니다. 이 기능은 유연한 레이아웃 재구성에 매우 유용합니다.
mainGrid.addWidget({
x: 2, y: 1, w: 4, h: 4,
subGridDynamic: true,
content: '여기에 드래그하면 자동 그리드 생성'
});
계층 간 위젯 이동
중첩된 그리드 사이에서도 위젯을 자유롭게 이동할 수 있습니다. 예를 들어, 부모 그리드의 위젯을 자식 그리드로 드래그하거나, 서로 다른 하위 그리드 간 이동이 가능하며, 모든 동작은 DOM 구조와 데이터 상태를 일관되게 유지합니다.
실제 적용 사례
데이터 대시보드
상위 레벨에는 매출, 방문자 수, 전환율 등의 주요 지표를 배치하고, 각 지표 클릭 시 펼쳐지는 중첩 그리드에서 과거 추이, 지역별 분포, 비교 분석 차트 등을 표시할 수 있습니다.
태스크 관리 도구
프로젝트 카드 내부에 "진행 중", "완료", "보류" 세 개의 열로 구성된 하위 그리드를 배치하여, 팀원들이 태스크를 직접 드래그하여 상태를 업데이트할 수 있도록 합니다.
이벤트 핸들링
모든 그리드 계층은 자체 이벤트를 발생시킵니다. 중첩된 그리드에도 이벤트 리스너를 등록하여 동작을 감지할 수 있습니다.
function bindGridEvents(grid) {
grid.on('dragstop', function(event, element) {
console.log('이동 완료:', element);
});
grid.on('resizestop', function(event, element) {
console.log('크기 조정 완료:', element);
});
}
레이아웃 저장 및 복원
복잡한 중첩 구조도 쉽게 직렬화할 수 있습니다. save() 메서드는 현재 레이아웃과 모든 하위 그리드 정보를 JSON 형태로 출력합니다.
function exportLayout() {
const layoutData = mainGrid.save(true, true);
localStorage.setItem('dashboard-layout', JSON.stringify(layoutData));
}
function importLayout() {
const saved = localStorage.getItem('dashboard-layout');
if (saved) {
mainGrid.load(JSON.parse(saved));
}
}
성능 및 UX 최적화 전략
- 계층 깊이 제한: 가능한 계층 수는 무제한이지만, 일반적으로 2~3단계까지만 사용하는 것이 사용자 인지 부하를 줄이는 데 효과적입니다.
- 배치 업데이트: 여러 위젯을 동시에 조작할 때는
batchUpdate()를 사용하여 렌더링 성능을 개선하세요. - 지연 로딩: 중첩 그리드의 콘텐츠가 많은 경우, 해당 영역이 화면에 노출될 때까지 데이터 로딩을 지연시키는 것이 좋습니다.
문제 해결 팁
드래그 영역이 명확하지 않아 사용자가 어떤 계층에서 작업 중인지 혼동할 수 있습니다. 이를 방지하기 위해 CSS로 하이라이트 효과를 추가하거나, 드래그 중인 요소에 계층 경로를 시각적으로 표시하는 것이 바람직합니다.
마무리
gridstack.js의 중첩 그리드는 단순한 레이아웃을 넘어서, 계층적이고 동적인 사용자 인터페이스를 설계할 수 있는 핵심 도구입니다. 적절히 활용하면 직관적이면서도 확장 가능한 고급 UI를 신속하게 구축할 수 있습니다. 지금 바로 프로젝트에 적용해 보고, 다층 레이아웃의 잠재력을 극대화해 보세요.