컴포넌트/패널 외 영역 (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, ...)

참고