컴포넌트/패널 외 영역 (Div, Span)

GridDiv (그리드 디비전)

VanillaFront 2026. 9. 18. 22:25

Va.GridDiv — CSS Grid 기반 격자 레이아웃 컨테이너

CSS Grid를 이용해 셀 단위 격자 레이아웃을 만드는 컨테이너입니다. Va.Component를 직접 상속받으며 display: grid가 자동 적용되어, 실제 데이터 그리드(Va.Grid)와는 다른 목적의 정적 격자 레이아웃(카드 나열, 폼 격자 배치, 스프레드시트 스타일 표 등)에 사용됩니다.

클래스 정보

Va.GridDiv extends Va.Component
tagName: 'gridDiv' (실제 렌더링은 <div>)
isContainer: true
isEnableRoot: true
파일: va_griddiv.js (별도 모듈)

짝을 이루는 3형제

va_griddiv.js 하나에 세 컴포넌트가 함께 정의되어 있으며, 함께 사용하는 것이 표준 패턴입니다:

컴포넌트CSS 클래스역할

Va.GridDiv va-grid-div 격자 컨테이너 (루트)
Va.GridDivH va-grid-div-header 헤더 셀 (배경색 강조)
Va.GridDivB va-grid-div-body 바디 셀 (일반 콘텐츠)

기본 사용법

{
    tagName: 'gridDiv',
    style: {
        gridTemplateColumns: '100px 200px 1fr',
        gridTemplateRows: 'auto auto'
    },
    tags: [
        { tagName: 'gridDivH', text: '코드' },
        { tagName: 'gridDivH', text: '이름' },
        { tagName: 'gridDivH', text: '설명' },
        { tagName: 'gridDivB', text: '001' },
        { tagName: 'gridDivB', text: '홍길동' },
        { tagName: 'gridDivB', text: '개발팀장' }
    ]
}

Va.Grid와의 차이 — 핵심 구분

항목Va.GridVa.GridDiv

목적 데이터 그리드 (행/열, 정렬, 스크롤, DataManager 연동) 정적 격자 레이아웃 (CSS Grid)
사용 서버 데이터 조회 결과 표시 카드 나열, 폼 격자, 정적 표
이벤트 onRowClick, onCellClick, onSort 등 풍부 click, contextmenu만
파일 va_grid.js (대형) va_griddiv.js (소형)
동적 데이터 ○ (setData) × (JSON tag 트리)

요약: 데이터 조회/편집 UI라면 Va.Grid, 시각적 격자 배치라면 Va.GridDiv.

속성

속성타입설명

text String 순수 텍스트
innerHTML String HTML 문자열
appearance String CSS 클래스로 부여됨 ('primary', 'outline' 등)
layout, style, class, hidden — 공통 속성

격자 정의는 style로: gridTemplateColumns, gridTemplateRows, gap 등 CSS Grid 속성을 style로 지정합니다.

이벤트

이벤트발생 시점콜백 인자

click 클릭 시 (sender, element, evt)
contextmenu 우클릭 시 (sender, element, evt)

세 컴포넌트 모두 동일한 이벤트만 지원합니다.

메서드

  • setText(text) — 텍스트 변경 후 업데이트
  • setInnerHTML(html) — HTML 변경 후 업데이트
  • Va.Component 공통 메서드

자동 적용되는 CSS

.va-grid-div {
    display: grid;
    background: var(--colorBackground);
    border-top: 0.5px solid var(--colorNeutralStroke);
    border-left: 0.5px solid var(--colorNeutralStroke);
}

.va-grid-div-header {
    background: var(--colorBackground3);
    display: flex; align-items: center; justify-content: center;
    padding: 0.2rem 0.4rem;
    border-right/bottom: 0.1rem solid var(--colorNeutralStroke);
}

.va-grid-div-body {
    display: flex; align-items: center; justify-content: start;
    padding: 0.4rem;
    border-right/bottom: 0.1rem solid var(--colorNeutralStroke);
}

appearance 변형:

  • appearance: 'primary' → 헤더가 primary 색 배경
  • appearance: 'outline' → 헤더 배경 투명

사용 시점 — 언제 쓰나

  • 정적 표 형태 정보 표시 — 스펙 시트, 속성 목록, 규격 정보
  • 폼 격자 배치 — 라벨과 필드가 규칙적으로 배열되는 폼
  • 카드 그리드 — 동일 크기 카드들의 격자 나열
  • 비교 표 — 요금제 비교, 사양 비교 등
  • 캘린더 셀 격자 — 월 캘린더의 날짜 셀

사용하지 말아야 할 때

  • 서버 데이터 조회 결과 그리드 → Va.Grid
  • 정렬/필터/편집 기능이 필요한 표 → Va.Grid
  • 자유 flex 레이아웃 → Va.Div + layout
  • 단순 텍스트 그루핑 → Va.Div

자주 쓰는 조합 예시

스펙 시트 (2열 라벨-값)

{
    tagName: 'gridDiv',
    style: { gridTemplateColumns: '120px 1fr' },
    tags: [
        { tagName: 'gridDivH', text: '이름' },
        { tagName: 'gridDivB', text: '홍길동' },
        { tagName: 'gridDivH', text: '부서' },
        { tagName: 'gridDivB', text: '개발팀' },
        { tagName: 'gridDivH', text: '이메일' },
        { tagName: 'gridDivB', text: 'hong@example.com' }
    ]
}

3열 헤더 + 여러 행 바디

{
    tagName: 'gridDiv',
    style: { gridTemplateColumns: '80px 150px 1fr' },
    tags: [
        // 헤더 행
        { tagName: 'gridDivH', text: '코드' },
        { tagName: 'gridDivH', text: '이름' },
        { tagName: 'gridDivH', text: '설명' },
        // 데이터 행 1
        { tagName: 'gridDivB', text: '001' },
        { tagName: 'gridDivB', text: '홍길동' },
        { tagName: 'gridDivB', text: '개발팀장' },
        // 데이터 행 2
        { tagName: 'gridDivB', text: '002' },
        { tagName: 'gridDivB', text: '김철수' },
        { tagName: 'gridDivB', text: '팀원' }
    ]
}

appearance 사용 (primary 헤더)

{
    tagName: 'gridDiv',
    appearance: 'primary',
    style: { gridTemplateColumns: 'repeat(4, 1fr)' },
    tags: [
        { tagName: 'gridDivH', text: '항목' },
        { tagName: 'gridDivH', text: '기본' },
        { tagName: 'gridDivH', text: '프로' },
        { tagName: 'gridDivH', text: '엔터프라이즈' },
        { tagName: 'gridDivB', text: '가격' },
        { tagName: 'gridDivB', text: '₩10,000' },
        { tagName: 'gridDivB', text: '₩50,000' },
        { tagName: 'gridDivB', text: '문의' }
    ]
}

폼 격자 배치 (라벨-필드 정렬)

{
    tagName: 'gridDiv',
    style: { gridTemplateColumns: '100px 1fr 100px 1fr', gap: 0 },
    tags: [
        { tagName: 'gridDivH', text: '이름' },
        { tagName: 'gridDivB', tags: [{ tagName: 'input', ref: 'refName' }] },
        { tagName: 'gridDivH', text: '부서' },
        { tagName: 'gridDivB', tags: [{ tagName: 'input', ref: 'refDept' }] },
        { tagName: 'gridDivH', text: '이메일' },
        { tagName: 'gridDivB', tags: [{ tagName: 'input', ref: 'refEmail' }], style: { gridColumn: 'span 3' } }
    ]
}

실전 예시 — 사용자 상세 정보 표시

config(){
    return {
        tagName: 'panel',
        tags: [{
            tagName: 'title',
            innerHTML: '사용자 상세 정보'
        },{
            tagName: 'gridDiv',
            appearance: 'primary',
            style: {
                gridTemplateColumns: '150px 1fr',
                width: '100%'
            },
            tags: [
                { tagName: 'gridDivH', text: '사용자 ID' },
                { tagName: 'gridDivB', text: 'user001' },
                { tagName: 'gridDivH', text: '이름' },
                { tagName: 'gridDivB', text: '홍길동' },
                { tagName: 'gridDivH', text: '부서' },
                { tagName: 'gridDivB', text: '개발팀' },
                { tagName: 'gridDivH', text: '가입일' },
                { tagName: 'gridDivB', text: '2026-01-15' },
                { tagName: 'gridDivH', text: '메모' },
                {
                    tagName: 'gridDivB',
                    innerHTML: '<strong>VIP 고객</strong> - 우선 응대 대상'
                }
            ]
        }]
    };
}

주의사항

  • Va.Grid와 혼동 금지 — 이름이 비슷하지만 완전히 다른 컴포넌트. GridDiv는 정적 CSS Grid 레이아웃, Grid는 데이터 그리드
  • 격자 정의는 style로 — gridTemplateColumns/gridTemplateRows 등은 style 속성으로 지정
  • 셀 순서대로 배치 — 자식 배열 순서가 격자에 좌→우, 위→아래 순으로 채워짐
  • 셀 병합 — 개별 셀에 style: { gridColumn: 'span 2' } 또는 gridRow: 'span N' 지정
  • 자동 border — 컨테이너에 top/left, 셀에 right/bottom을 그려 전체가 표처럼 보임. gap을 주면 자연스러운 표가 아니게 되니 주의
  • Va.GridDivH.update()의 버그 — 소스를 보면 innerHTML을 textContent로 넣는 부분이 먼저 실행된 후 다시 innerHTML로 덮어써지는 이중 처리 패턴이 있음. 결과적으론 innerHTML이 최종 반영되지만 첫 렌더링 시 잠깐 escape된 텍스트가 보일 수 있음

대안 비교

상황추천

정적 격자 레이아웃 (표/스펙) Va.GridDiv + H + B
서버 데이터 그리드 Va.Grid
트리 형태 그리드 Va.TreeGrid
동적 컬럼 그리드 Va.DynamicGrid
피벗 테이블 Va.PivotGrid
자유 flex 레이아웃 Va.Div + layout
카드 나열 (자동 줄바꿈) Va.Div + display: grid + grid-template-columns: repeat(auto-fill, ...)

참고