topgrid 시작 가이드
topgrid 는 TanStack Table v8 기반의 React 그리드 라이브러리다. 핵심 그리드와 셀 렌더러, 정렬/필터, Excel/CSV/PDF 내보내기, Vue 어댑터를 제공하는 무료 MIT 패키지 7종을 쓸 수 있고, 다단 헤더·변경 추적·Excel-style 범위 편집 같은 고급 기능은 상용 Pro 패키지로 확장한다. (전체 31 패키지 구성은 아키텍처 참고.)
- npm scope:
@topgrid/* - 권장 환경: React 18/19 + TypeScript + Tailwind CSS
- 정확한 export·시그니처 전체는 API 레 퍼런스 참고
1. 어떤 패키지가 필요한가
| 사용 사례 | 권장 패키지 |
|---|---|
| 단순 데이터 표시 (정렬/필터 없음) | @topgrid/grid-core + @topgrid/grid-renderers |
| 정렬 + 필터 + 검색 | + @topgrid/grid-features |
| Excel/CSV/PDF 다운로드 | + @topgrid/grid-export |
| 다단 헤더 (월/일/요일 등) | + @topgrid/grid-pro-header (Pro) |
| 인라인 편집 + 변경 추적 + 저장 | + @topgrid/grid-pro-tracking (Pro) |
| Excel-style 범위 선택 + 키보드 | + @topgrid/grid-pro-range (Pro) |
| Master-Detail (펼치기) + 우클릭 메뉴 | + @topgrid/grid-pro-master (Pro) |
| Group / Sum / Avg 집계 | + @topgrid/grid-pro-agg (Pro) |
| 차트·시각화 (셀 스파크라인 ~ 엔터프라이즈 17종, React/Vue) | + 차트 패키지 → 차트 (Pro) |
- 무료 MIT 7 패키지 (
grid-core/grid-core-headless/grid-renderers/grid-features/grid-sizing/grid-export/grid-vue) 는 자유 사용. - Pro 패키지는 라이선스 키가 필요하다. 미설정 시 그리드 우상단에
"Unlicensed @topgrid/grid"watermark 가 표시되며, 기능 자체는 동작한다.
2. Hello World — 5분 안에 그리드 표시
2.1 설치
# Vite + React 프로젝트 가정
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
# topgrid + peer deps
npm install @topgrid/grid-core @topgrid/grid-renderers \
@tanstack/react-table @tanstack/react-virtual
# Tailwind CSS (renderer 의 className 사용을 위해)
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Peer dependency:
react ^18.0.0 || ^19.0.0
react-dom ^18.0.0 || ^19.0.0
@tanstack/react-table ^8.0.0
@tanstack/react-virtual ^3.0.0 (가상화 사용 시)
2.2 Tailwind 설정
모든 셀 렌더러는 Tailwind className 으로만 스타일링된다. 패키지 안의 클래스가 빌드에
포함되도록 content 에 패키지 경로를 추가한다.
// tailwind.config.js
export default {
content: [
'./src/**/*.{js,ts,jsx,tsx}',
'./node_modules/@topgrid/**/*.{js,mjs}', // ★ topgrid 클래스 인식
],
theme: { extend: {} },
plugins: [],
};
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
2.3 첫 그리드
권장: 고수준 createColumns — TanStack ColumnDef 지식 없이 { id, name, type } 로
선언하면, type 에 맞는 셀 렌더러가 자동 배선된다(facade @topgrid/grid 가 기본 렌더러를 wiring).
import { Grid, createColumns } from '@topgrid/grid'; // facade = 렌더러 자동 배선
interface User {
id: number;
name: string;
email: string;
age: number;
}
const columns = createColumns<User>([
{ id: 'name', name: '이름', type: 'text', width: '150' },
{ id: 'email', name: '이메일', type: 'text', width: '250' },
{ id: 'age', name: '나이', type: 'number', align: 'right', width: '80' },
]);
const data: User[] = [
{ id: 1, name: '김철수', email: 'chulsoo@example.com', age: 30 },
{ id: 2, name: '이영희', email: 'younghee@example.com', age: 28 },
{ id: 3, name: '박민수', email: 'minsoo@example.com', age: 35 },
];
export default function App() {
return (
<div className="p-8">
<h1 className="text-2xl font-bold mb-4">사용자 목록</h1>
<Grid<User>
data={data}
columns={columns}
getRowId={(u) => String(u.id)} // ★ 안정적 행 식별 (아래 주의 참고)
enableSort
/>
</div>
);
}
npm run dev
→ 브라우저에 그리드가 표시되고, 컬럼 헤더 클릭 시 정렬이 동작한다.
★ getRowId 를 지정하라. 미지정 시 행 식별이 배열 인덱스로 떨어져, 선택(selection)·행 재정렬·셀 변경 플래시가 정렬/필터 후 엉뚱한 행을 추적한다(가장 흔한 함정). dev 모드에서 이 조건이면 경고가 출력된다.
getRowId={(row) => row.<고유키>}권장.정렬 prop 은
enableSort(enableSorting아님 — TanStack 옵션명과 다름).저수준 경로: TanStack 의
ColumnDef<User>[]를columns에 직접 넘겨 완전 제어할 수도 있다 (accessorFn·커스텀 cell 등). 이때만@tanstack/react-table지식이 필요하다.
3. 점진적 확장
3.1 페이지네이션
GridPagination 은 그리드와 별도 컴포넌트로 배치한다.
import { Grid, GridPagination, useGridState } from '@topgrid/grid-core';
function App() {
const grid = useGridState<User>({
initialPagination: { pageIndex: 0, pageSize: 10 },
});
return (
<>
<Grid<User>
data={data}
columns={columns}
enablePagination
state={{ pagination: grid.pagination }}
onPaginationChange={grid.setPagination}
/>
<GridPagination
table={grid.table}
mode="client"
pageSizeOptions={[10, 20, 50]}
showTotalCount
/>
</>
);
}
3.2 필터 + 검색 (@topgrid/grid-features)
import { TextFilter, GlobalSearchInput, textFilterFn } from '@topgrid/grid-features';
const columns: ColumnDef<User>[] = [
{
id: 'name',
accessorKey: 'name',
header: ({ column }) => (
<div className="flex items-center gap-1">
이름
<TextFilter column={column} defaultOperator="contains" />
</div>
),
filterFn: textFilterFn,
},
// ...
];
// 그리드 위에 글로벌 검색
<GlobalSearchInput table={table} placeholder="전체 검색..." />
다중 정렬이 필요하면
useMultiSort를 사용한다. 이 훅은@topgrid/grid-features에서 export 된다 (정렬 우선순위 배지SortBadge와 초기화 버튼SortClearButton은@topgrid/grid-core에 있다).
3.3 셀 렌더러 (@topgrid/grid-renderers)
import { NumberCell, StatusBadgeCell, LinkCell } from '@topgrid/grid-renderers';
const columns: ColumnDef<User>[] = [
{
id: 'name',
accessorKey: 'name',
header: '이름',
cell: (info) => (
<LinkCell value={String(info.getValue())} onClick={() => goToDetail(info.row.original.id)} />
),
},
{
id: 'age',
accessorKey: 'age',
header: '나이',
cell: (info) => <NumberCell value={info.getValue() as number} unit="세" />,
},
{
id: 'status',
accessorKey: 'status',
header: '