@axboot/datagrid
v1.7.2
Published
DataGrid, DataSheet for React
Downloads
505
Readme
@axboot/datagrid
DataGrid, DataSheet for React
Install
npm i @axboot/datagridDevelopment
npm i
npm run devOpen http://localhost:5173 with your browser to see the demo app.
Testing
# Unit tests (Vitest)
npm test
# Unit tests in watch mode
npm run test:watch
# Consumer compatibility test (install + cjs/esm/types check)
npm run test:library:consumers
# E2E tests (Playwright)
npm run test:e2e
# E2E tests with UI runner
npm run test:e2e:uiBuild
# Demo app bundle (Vite)
npm run build
# Publishable library bundle (CJS + ESM + types + style)
npm run build:libraryPublish
# Build dist/cjs, dist/esm, dist/types and dist/package.json
npm run build:library
# Dry-run package file list from dist
npm run pack:library
# Publish dist package manually
npm run publish:libraryGitHub Actions Auto Publish
- Workflow file:
.github/workflows/publish-npm.yml - Trigger: push tag
v*(example:v1.6.4) or manualworkflow_dispatch - Required secret:
NPM_TOKEN - Safety check: tag version must match
package.jsonversion
Styling
import '@axboot/datagrid/style.css';or
Add the code below to your project.
[role='ax-datagrid'] {
--axdg-primary-color: #3b82f6;
--axdg-header-bg: #f3f4f5;
--axdg-header-color: #222;
--axdg-header-font-weight: 500;
--axdg-header-hover-bg: #e2e5e5;
--axdg-header-group-bg: #e9e9e9;
--axdg-footer-bg: #f3f4f5;
--axdg-summary-bg: #eaeef6;
--axdg-border-color-base: #d2d5d9;
--axdg-border-color-light: #d2d5d9;
--axdg-border-radius: 4px;
--axdg-row-selector-color: #ffffff;
--axdg-body-bg: #ffffff;
--axdg-body-odd-bg: #f8f8f8;
--axdg-body-hover-bg: #f3f4f5;
--axdg-body-hover-odd-bg: #eeeeee;
--axdg-body-active-bg: #e6f6ff;
--axdg-body-color: #444;
--axdg-scroll-size: 11px;
--axdg-scroll-track-bg: #f9f9f9;
--axdg-scroll-thumb-radius: 6px;
--axdg-scroll-thumb-bg: #c0c1c5;
--axdg-scroll-thumb-hover-bg: #a1a3a6;
--axdg-loading-bg: rgba(163, 163, 163, 0.1);
--axdg-loading-color: rgba(0, 0, 0, 0.1);
--axdg-loading-second-color: #767676;
--axdg-page-number-active-border-radius: 4px;
}
Usage
- codesandbox DEMO : https://codesandbox.io/p/devbox/basic-example-5ch6kt?embed=1&file=%2Fsrc%2FApp.tsx
Basic Example
import * as React from 'react';
import styled from '@emotion/styled';
import { AXDataGrid, AXDGColumn } from '@axboot/datagrid';
interface IListItem {
id: string;
title: string;
writer: string;
createAt: string;
}
const list = Array.from({ length: 1000 }).map((_, i) => ({
values: {
id: `ID_${i}`,
title: `title_${i}`,
writer: `writer_${i}`,
createAt: `2022-09-08`,
},
}));
function BasicExample() {
const [columns, setColumns] = React.useState<AXDGColumn<IListItem>[]>([
{ key: 'id', label: 'ID', width: 120 },
{
key: 'title',
label: '제목',
width: 260,
itemRender: ({ values }) => <>{values.writer} / {values.title}</>,
},
{ key: 'writer', label: '작성자', width: 120 },
{ key: 'createAt', label: '작성일', width: 140 },
]);
const [checkedRowKeys, setCheckedRowKeys] = React.useState<React.Key[]>([]);
return (
<Container>
<AXDataGrid<IListItem>
width={720}
height={420}
data={list}
columns={columns}
rowKey={'id'}
onChangeColumns={(columnIndex, { width, columns }) => {
console.log('onChangeColumns', columnIndex, width, columns);
setColumns(columns);
}}
rowChecked={{
checkedRowKeys,
onChange: (checkedIndexes, checkedRowKeys, checkedAll) => {
console.log('rowChecked changed', checkedIndexes, checkedRowKeys, checkedAll);
setCheckedRowKeys(checkedRowKeys);
},
}}
/>
</Container>
);
}
const Container = styled.div`
font-size: 13px;
`;
export default BasicExample;Important Data/Column Rules
- Row data type is
AXDGDataItem<T>and the real domain model is always insideitem.values. AXDGColumn.keysupports bothstringandstring[].key: 'writer'key: ['user', 'profile', 'name'](nested value path)
itemRenderreceives both:value: current cell value bycolumn.keyvalues: full row model (T)
columns[i].leftis internal layout value computed byAXDataGrid; do not manage it manually.
Common Scenarios
1) Frozen Columns
<AXDataGrid
width={900}
height={500}
frozenColumnIndex={2}
columns={columns}
data={data}
/>frozenColumnIndex 이전 컬럼(0, 1)은 고정 영역으로 렌더링됩니다.
2) Editable Cell
const columns: AXDGColumn<IListItem>[] = [
{
key: 'title',
label: '제목',
width: 240,
editable: true,
itemRender: ({ editable, value, handleSave, handleCancel }) => {
if (!editable) return <>{value}</>;
return (
<input
autoFocus
defaultValue={value}
onBlur={e => handleSave?.(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') handleSave?.((e.target as HTMLInputElement).value);
if (e.key === 'Escape') handleCancel?.();
}}
/>
);
},
},
];
<AXDataGrid editable editTrigger={'dblclick'} columns={columns} data={data} width={700} height={400} />;3) Sort + Page
<AXDataGrid
width={900}
height={560}
columns={columns}
data={rows}
sort={{
sortParams,
onChange: next => setSortParams(next),
}}
page={{
currentPage,
pageSize,
totalPages,
totalElements,
onChange: (nextPage, nextSize) => {
setCurrentPage(nextPage);
if (nextSize) setPageSize(nextSize);
},
}}
/>Props Reference (AXDataGrid)
아래는 자주 사용하는 Props 중심 정리입니다. 타입의 최종 기준은 @axboot-datagrid/types.ts의 AXDGProps<T>입니다.
Required
| Prop | Type | Description |
|---|---|---|
| width | number | 그리드 전체 너비 |
| height | number | 그리드 전체 높이 |
| columns | AXDGColumn<T>[] (width optional) | 컬럼 정의 |
Data / Selection / Row Focus
| Prop | Type | Description |
|---|---|---|
| data | AXDGDataItem<T>[] | 행 데이터 (values 래핑 필수) |
| rowKey | React.Key \| React.Key[] | 행 고유 키 필드 |
| selectedRowKey | React.Key \| React.Key[] | 포커스된 행 키 |
| rowChecked | AXDGRowChecked<T> | 체크박스/라디오 선택 제어 (onChange 필수) |
| getRowClassName | (ri, item) => string \| undefined | 행 단위 className 지정 |
rowSelection/selectedIds는 현재 API가 아닙니다.rowChecked를 사용해야 합니다.
Layout / Rendering
| Prop | Type | Description |
|---|---|---|
| headerHeight | number | 헤더 높이 (기본 30) |
| footerHeight | number | 페이지네이션 푸터 높이 (기본 30) |
| summaryHeight | number | summary 높이 (기본 30) |
| itemHeight | number | 본문 행 컨텐츠 높이 (기본 15) |
| itemPadding | number | 행 내부 패딩 (기본 7) |
| frozenColumnIndex | number | 고정 컬럼 경계 인덱스 |
| showLineNumber | boolean | 좌측 라인 번호 표시 |
| variant | 'default' \| 'vertical-bordered' | 스킨 변형 |
| loading | boolean | 전체 오버레이 로딩 |
| spinning | boolean | 바디 스피너 로딩 |
Column / Editing / Events
| Prop | Type | Description |
|---|---|---|
| columnsGroup | AXDGColumnGroup[] | 헤더 그룹 |
| onChangeColumns | (columnIndex, info) => void | 컬럼 폭/순서/그룹 변경 콜백 |
| onChangeData | (index, columnIndex, item, column) => void | 셀 편집 데이터 변경 콜백 |
| editable | boolean | 편집 모드 활성화 |
| editTrigger | 'click' \| 'dblclick' | 편집 진입 트리거 (기본 click) |
| onClick | (params) => void | 셀 클릭 이벤트 |
Extra Features
| Prop | Type | Description |
|---|---|---|
| sort | AXDGSortInfo | 정렬 상태/변경 콜백 |
| columnSortable | boolean | 컬럼 drag sort 제어 |
| page | AXDGPage | 페이지네이션 상태/콜백 |
| summary | { columns, position } | 상/하단 summary 행 |
| cellMergeOptions | { columnsMap } | 셀 병합 옵션 |
| reorder | AXDGReorderInfo<T> | 행 reorder 설정 |
| msg | { emptyList?: string } | 커스텀 메시지 |
Update Note
v1.5
- rowChecked 속성 추가 (rowChecked > isRadio, rowChecked > disabled)
<AXDataGrid<IListItem>
width={containerWidth}
height={containerHeight}
headerHeight={35}
data={sortedList}
columns={columns}
onChangeColumns={(columnIndex, { width, columns }) => {
console.log('onChangeColumnWidths', columnIndex, width, columns);
setColumns(columns);
}}
rowChecked={{
disabled: (ri, item) => ri === 0,
isRadio: true,
checkedRowKeys: checkedKeys,
onChange: (ids, keys, selectedAll) => {
console.log('onChange rowSelection', ids, keys, selectedAll);
setCheckedKeys(keys);
},
}}
sort={{
sortParams,
onChange: sortParams => {
console.log('onChange: sortParams', sortParams);
setSortParams(sortParams);
},
}}
showLineNumber
rowKey={'nation'}
/>V1.4
- columnsGroup 타입변경 기존 columnsIndex: []에서 start, end 지정 형태로 변경되었습니다.
[{ label: '묶음', groupStartIndex: 2, groupEndIndex: 4, align: 'center' }]- onChangeColumns 속성 변경
// onChangeColumns Type
onChangeColumns?: (
columnIndex: number | null,
info: {
width?: number;
columns: AXDGColumn<T>[];
columnsGroup?: AXDGColumnGroup[];
},
) => void;
// onChangeColumns에서 변경된 컬럼과 컬럼 그룹을 받을 수 있습니다
<AXDataGrid
/*...*/
onChangeColumns={(columnIndex, { columns, columnsGroup }) => {
console.log('onChangeColumnWidths', columnIndex, columns, columnsGroup);
setColumns(columns);
setColumnsGroup(columnsGroup);
}}
/>