Skip to Content

Grid

TanStack Table 기반의 선언적 데이터 그리드 컴포넌트입니다.


개요

Grid 컴포넌트는 <TableColumn> 자식 컴포넌트로 열을 선언적으로 정의하고, TanStack Table을 내부 엔진으로 사용하여 정렬, 페이지네이션, 행 선택 등을 지원합니다.

주요 특징

  • 선언적 API: <TableColumn> children으로 열 구성
  • 페이지네이션: Foundation Pagination 기반, 페이지 크기 선택 및 직접 이동 지원
  • 행 선택: 체크박스(다중) / 라디오(단일) 모드
  • 정렬: 클라이언트/서버 사이드 정렬 지원
  • 셀 유형: link, button, range(progress/rate), 조건부 서식
  • 커스텀 렌더링: renderCell prop으로 자유로운 셀 커스터마이징
  • 그룹 컬럼: <TableColumn> 중첩으로 멀티행 헤더 지원
  • 컨럼 표시/숨김: columnVisibility로 컨럼별 표시 여부 제어
  • 개인화 (Personalization): 컨럼 순서/크기/표시 상태 저장 및 복원 (비동기 저장소 지원)
  • 디자인 토큰: Foundation 토큰 시스템 호환

기본 사용

<Grid>datagetRowId를 전달하고, <TableColumn>으로 열을 정의합니다.

ID
상품명
가격
1
상품1
1,000
2
상품2
2,500

행 선택

체크박스 (다중 선택)

selectable + selectionMode="checkbox"로 다중 행 선택을 활성화합니다.

ID
상품명
1
상품1
2
상품2
3
상품3

라디오 (단일 선택)

selectionMode="radio"로 단일 행 선택을 활성화합니다.

ID
상품명
1
상품1
2
상품2

페이지네이션

pageSize, pageSizeOptions, useGoToPage으로 페이지네이션을 구성합니다.

ID
이름
1
항목 1
2
항목 2
3
항목 3
4
항목 4
5
항목 5
30

셀 유형 (uiType)

TableColumn의 uiType prop으로 셀 표시 유형을 지정합니다.

링크
재고율
350/500

조건부 서식

conditionalFormatting으로 조건에 따라 셀 스타일을 적용합니다.

ID
재고
1
50
2
200
3
400

그룹 컬럼 (멀티행 헤더)

<TableColumn> 안에 <TableColumn>을 중첩하면 그룹 컬럼(멀티행 헤더)을 구성할 수 있습니다. 그룹 컬럼의 field는 생략하고 title만 지정합니다.

주소
이름
도시
우편번호
상태
홍길동
서울06100
active
김영희
부산48060
inactive
이철수
대전34100
active

커스텀 셀 렌더링

renderCell prop으로 셀을 자유롭게 커스터마이징합니다.

ID
상태
1
● 활성
2
● 비활성

API Reference

Grid Props

PropTypeDefaultDescription
dataT[][]테이블에 표시할 데이터 배열
getRowId(row: T) => string-행 고유 ID 추출 함수 (필수)
childrenReactNode-<TableColumn> 자식 컴포넌트들
loadingbooleanfalse로딩 상태 표시
heightnumber | string-그리드 높이
classNamestring-그리드 컨테이너 CSS 클래스
selectablebooleanfalse행 선택 활성화
selectionMode"checkbox" | "radio""checkbox"선택 방식
selectedRowsstring[]-선택된 행 ID 배열 (controlled)
paginationbooleantrue페이지네이션 표시 여부
pageSizenumber20페이지당 행 수
pageSizeOptionsnumber[][10, 20, 50, 100]페이지 크기 선택 목록
useGoToPagebooleanfalse페이지 직접 이동 입력란 표시
manualPaginationbooleanfalse서버 사이드 페이징 여부
manualSortingbooleanfalse서버 사이드 정렬 여부
showRowNumberbooleanfalse행 번호 열 표시
stripedbooleanfalse줄무늬 행 표시
fullSizebooleanfalse화면 가득 채움
enableColumnResizebooleantrue열 너비 조절 활성화
columnVisibilityRecord<string, boolean>-컨럼 표시/숨김 상태 (controlled)
onColumnVisibilityChange(visibility: Record<string, boolean>) => void-컨럼 표시 변경 콜백
personalizationGridPersonalizationConfig-개인화 저장/복원 설정
onScrollEnd() => void-스크롤 하단 도달 시 콜백 (무한스크롤)
backgroundColorstring-그리드 배경색

Grid Events

EventTypeDescription
onRowClick(row: T, rowIndex: number) => void행 클릭
onRowDoubleClick(row: T, rowIndex: number) => void행 더블클릭
onLoad(params: GridLoadParams) => void데이터 로드 요청
onSortChange(sorting: SortingState) => void정렬 변경
onPageChange(pageIndex: number) => void페이지 변경
onPageSizeChange(pageSize: number) => void페이지 크기 변경
onSelectionChange(selectedIds: string[], selectedRows: T[]) => void선택 변경
onColumnResize(columnId: string, width: number) => void열 너비 변경

TableColumn Props

PropTypeDefaultDescription
fieldstring-데이터 필드명 (그룹 컬럼은 생략 가능)
titlestring-열 헤더 텍스트 (필수)
widthnumber-열 너비 (px)
minWidthnumber-최소 열 너비
sortablebooleanfalse정렬 가능 여부
visiblebooleantrue열 표시 여부
enabledbooleantrue열 활성화 여부
uiType"text" | "link" | "button" | "range" | …"text"셀 표시 유형
formatterTableColumnFormatter-값 포맷터 (천단위 구분 등)
conditionalFormattingTableColumnConditionalRule[]-조건부 서식 규칙
childrenReactNode-하위 <TableColumn> (그룹 컬럼용)
renderCell(value, row, rowIndex) => ReactNode-커스텀 셀 렌더 함수
onLinkClick(row: T) => void-uiType=“link” 클릭 콜백
onButtonClick(row: T) => void-uiType=“button” 클릭 콜백

컬럼 표시/숨김 (columnVisibility)

columnVisibilityonColumnVisibilityChange로 컬럼별 표시 여부를 제어합니다.

import { useState } from "react" import { Grid, TableColumn } from "@vortex/ui-cals" function ColumnVisibilityExample() { const [visibility, setVisibility] = useState<Record<string, boolean>>({ name: true, price: true, category: false, // 초기에 숨김 }) return ( <> {/* 토글 버튼 예시 */} <button onClick={() => setVisibility((v) => ({ ...v, category: !v.category }))}> 카테고리 {visibility.category ? "숨기기" : "보이기"} </button> <Grid data={data} getRowId={(row) => row.id} columnVisibility={visibility} onColumnVisibilityChange={setVisibility} > <TableColumn field="name" title="이름" /> <TableColumn field="price" title="가격" /> <TableColumn field="category" title="카테고리" /> </Grid> </> ) }

개인화 (Personalization)

personalization prop으로 컬럼 순서, 크기, 표시 상태를 저장/복원합니다. 비동기 저장소(IndexedDB 등)도 지원합니다.

import { Grid, TableColumn } from "@vortex/ui-cals" // 동기 저장소 (localStorage) const syncPersonalization = { getItem: () => { const saved = localStorage.getItem("grid-state") return saved ? JSON.parse(saved) : null }, setItem: (state) => localStorage.setItem("grid-state", JSON.stringify(state)), } // 비동기 저장소 (IndexedDB 등) const asyncPersonalization = { getItem: async () => { const db = await openMyDB() return await db.get("grid-state", "main-grid") }, setItem: async (state) => { const db = await openMyDB() await db.put("grid-state", state, "main-grid") }, } <Grid data={data} getRowId={(row) => row.id} personalization={asyncPersonalization} // Promise 반환도 OK > <TableColumn field="name" title="이름" /> <TableColumn field="price" title="가격" /> </Grid>

getItem()Promise를 반환하면 내부적으로 .then()으로 처리합니다.


접근성

권장 사항

  • <table> 시맨틱 요소를 사용하여 스크린 리더 호환
  • ✅ 로딩 시 aria-busy="true" 자동 적용
  • ✅ 체크박스/라디오는 키보드(Space)로 토글 가능
  • ✅ 페이지 탐색 버튼은 키보드로 접근 가능

관련 컴포넌트

Last updated on