Skip to content

axisj/axboot-datagrid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

283 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@axboot/datagrid

DataGrid, DataSheet for React

NPM version NPM downloads

Install

npm i @axboot/datagrid

Development

npm i
npm run dev

Open 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:ui

Build

# Demo app bundle (Vite)
npm run build

# Publishable library bundle (CJS + ESM + types + style)
npm run build:library

Publish

# 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:library

GitHub Actions Auto Publish

  • Workflow file: .github/workflows/publish-npm.yml
  • Trigger: push tag v* (example: v1.6.4) or manual workflow_dispatch
  • Required secret: NPM_TOKEN
  • Safety check: tag version must match package.json version

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

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 inside item.values.
  • AXDGColumn.key supports both string and string[].
    • key: 'writer'
    • key: ['user', 'profile', 'name'] (nested value path)
  • itemRender receives both:
    • value: current cell value by column.key
    • values: full row model (T)
  • columns[i].left is internal layout value computed by AXDataGrid; 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.tsAXDGProps<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);
  }}
/>

About

:octocat: DataGrid, DataSheet for React

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors