DataGrid
정렬, 행 선택, 좌/우 고정, 컬럼·행 이동이 필요한 목록에 써요. 모양은 Table이 그리고, 상태는 DataGrid가 관리해요.
변형
Figma Data Grid Cell의 type이 columns[].type과 같아요. select·handle 열은 onSelectionChange·onRowOrderChange로 생겨요. 머리글을 눌러 정렬하고, 핸들을 끌어서 행을 옮겨 보세요.
| 순서 | 상태 | 만든 날 | 사용 | 동작 | |||
|---|---|---|---|---|---|---|---|
| production | 활성 | 12,480 | 2026-03-02 | ||||
| github-actions | 활성 | 3,215 | 2026-05-18 | ||||
| staging | 만료 예정 | 842 | 2026-07-09 | ||||
| local-dev | 폐기됨 | 0 | 2026-09-21 |
| 상태 | |||
|---|---|---|---|
| service-01 | 활성 | 0 | 2026-01-10 |
| service-02 | 활성 | 7,919 | 2026-02-11 |
| service-03 | 활성 | 15,838 | 2026-03-12 |
| service-04 | 활성 | 3,757 | 2026-04-13 |
| service-05 | 만료 예정 | 11,676 | 2026-05-14 |
| 상태 | |||
|---|---|---|---|
| production | 활성 | 12,480 | 2026-03-02 |
| github-actions | 활성 | 3,215 | 2026-05-18 |
| staging | 만료 예정 | 842 | 2026-07-09 |
| local-dev | 폐기됨 | 0 | 2026-09-21 |
| 상태 | |||
|---|---|---|---|
| 상태 | |||
|---|---|---|---|
API 키가 없어요 키를 만들면 여기에서 사용량을 볼 수 있어요. | |||
| 상태 | |||
|---|---|---|---|
API 키를 불러오지 못했어요 네트워크 연결을 확인하고 다시 시도해 주세요. | |||
사용법
- 보여 주기만 하는 표는 Table정렬, 선택, 고정, 이동 중 하나라도 필요할 때 DataGrid를 써요.
- rows에는 원본 값숫자는 number, 날짜는 ISO 문자열이에요. 쉼표와 날짜 형식은 type이 맞춰요.
- 선택은 bg/selected, hover는 bg/subtle고정 열 경계는 1px border/default이고 그림자는 쓰지 않아요.
- 고정 열에는 width다음 고정 열 위치를 계산할 때 써요.
- 위험한 actions는 AlertDialog로 확인onClick에서 바로 지우지 않고 확인 창을 열어요.
- 서버에서 나누면 rowCount현재 페이지 rows와 전체 개수를 넘기고, 정렬도 서버가 해요(onSortingChange).
- 클라이언트 컴포넌트 안에서 정의columns에 함수가 있어서 서버 컴포넌트에서 넘길 수 없어요.
Props
| prop | 값 | 기본값 |
|---|---|---|
| rows · getRowId | 행 데이터(원본 값)와 행 id | (필수) |
| columns | type: text · number · date · datetime · badge(tones) · switch(onChange) · actions(actions). 공통 header · width · minWidth · pinned · sortable | (필수) |
| aria-label | 표 이름 | (필수) |
| sorting · onSortingChange | { id, desc } 또는 null. 한 번에 한 열 | null |
| selection · onSelectionChange | 선택된 행 id 배열. 넘기면 체크박스 열이 생겨요 | — |
| columnOrder · onColumnOrderChange | 열 id 순서. 넘기면 머리글을 끌어서 옮겨요 | — |
| onRowOrderChange | (ids) => void. 넘기면 핸들 열이 생겨요 | — |
| loading | Skeleton 행 5개 + aria-busy | false |
| refreshing | 이전 행은 두고 본문 위에 bg/scrim-subtle 막 + 스피너. 누르자마자 보여요 | false |
| emptyState · errorState | 본문 자리에 보여 줄 EmptyState · ErrorState | — |
| pagination | 넘기면 아래에 Pagination. { page, pageSize, pageSizeOptions, showFirstLast, rowCount, … } | — |
코드
tsx
<DataGrid
aria-label="API 키"
rows={keys}
getRowId={row => row.id}
columns={[
{ field: 'name', header: '이름', type: 'text', pinned: 'left', width: 160, sortable: true },
{ field: 'requests', header: '요청 수', type: 'number', sortable: true },
{ field: 'status', header: '상태', type: 'badge', tones: { active: 'success', revoked: 'danger' }, labels: { active: '활성', revoked: '폐기됨' } },
{ field: 'enabled', header: '사용', type: 'switch', onChange: (row, on) => toggle(row.id, on) },
{ id: 'actions', type: 'actions', pinned: 'right', actions: [
{ label: '이름 바꾸기', icon: Pencil, onClick: rename },
{ label: '삭제', icon: Trash2, tone: 'danger', onClick: confirmDelete },
] },
]}
selection={selected} onSelectionChange={setSelected}
onRowOrderChange={ids => saveOrder(ids)}
pagination={{ defaultPageSize: 20 }}
emptyState={<EmptyState title="API 키가 없어요" action={<Button>API 키 만들기</Button>} />}
/>