@azrico/reactgrid

中文文档
2.2.1发布于 2026/10/31TypeScriptCommonJS

React data grid on TanStack Table

原始使用文档
文档目录19 节
  1. Usage
  2. Props
  3. Data
  4. Columns
  5. Sort and filter
  6. Rows
  7. Tree and details
  8. Selection
  9. Editing
  10. Keyboard and events
  11. Misc
  12. Column definition
  13. Grid API
  14. DOM classes
  15. Saved column widths
  16. Accessibility
  17. Themes
  18. CSS variables
  19. example

@azrico/reactgrid

Private React data grid package for Azrideus' projects.

Usage

import { AzGrid } from '@azrico/reactgrid';
import '@azrico/reactgrid/dist/src/themes/azgrid-theme.css'; // optional colours

const columns = [{ name: 'name', header: 'Name', defaultFlex: 1 }];
const rows = [{ __table_id: '1', name: 'Alice' }];

<AzGrid theme="light" columns={columns} dataSource={rows} />;

The component imports grid.css (layout and structure, no colours) itself. azgrid-theme.css is the optional token preset: it paints every element from the --azgrid-* variables below with built-in light and dark fallbacks. Without it the grid renders unpainted and inherits the page's colours, so you can ship your own stylesheet against the stable azgrid__* class names instead.

Peer dependencies: react, @tanstack/react-table (>= 8.20) and @tanstack/react-virtual (>= 3.10). Upgrading from 1.x? Read MIGRATION-2.0.md: gridOptions is gone and every option is a top-level prop.

Props

Every x / defaultX / onXChange trio works controlled (pass x) or uncontrolled (pass defaultX).

Data

PropTypeDescription
dataSourceany[] | { data, count? } | (params) => rows | PromiseRows, or a loader called with { skip, limit, filterValue, sortInfo }. A loader returns rows or { data, count }.
loadingbooleanShows the load mask.
looseCacheCheckbooleanIgnore the dataSource identity when deciding whether the cache is still valid.
paginationfalse | 'local' | 'remote'remote asks the dataSource for each page, local pages the loaded rows.
limit / defaultLimit / onLimitChangenumberPage size.
skip / defaultSkip / onSkipChangenumberOffset of the current page.
pageSizesnumber[]Choices of the page size select.
remoteFilter / remoteSortbooleanSend the filters or the sort to the dataSource instead of applying them to the loaded rows.

Columns

PropTypeDescription
columns(LooseColumnDefinition | string)[]Column definitions, see Column definition.
columnExtensionsLooseColumnDefinition[]Merged into the column of the same name, existing values win.
customColumns{ name, render }[]Replaces the render of the column of the same name.
editableColumnsstring[]Names of the columns made editable.
leftColumns / rightColumnsstring[]Columns pinned to the start or end edge.
clipScrolledCellsbooleanCuts scrolled cells where pinned columns cover them, instead of painting the pinned cells opaque, so pinned cells can keep a translucent background. Default false.
gridIdstringSaves resized widths, see Saved column widths.
resizable / sortablebooleanDefaults for columns that don't set their own (default true).
filterablebooleanShows the filter row. Default true when a column is filterable or a filter value is given.
onColumnResize({ column, width }) => voidCalled when a resize ends.
onColumnVisibleChange({ column, visible }) => voidCalled when the column menu hides or shows a column.
columnMenubooleanHeader menu with sort and show/hide entries (default true).
columnMenuItems(column, api) => menu itemsEntries appended to the header menu of every column.

Sort and filter

PropTypeDescription
sortInfo / defaultSortInfo / onSortInfoChange{ name, dir: 1 | -1 } | nullSingle-column sort. Header clicks cycle ascending, descending, none.
filterValue / defaultFilterValue / onFilterValueChange{ name, operator, type, value }[]Filter row values.
filterTypes{ [type]: { operators: { name, fn }[] } }Merged over the built-in filter types. fn({ value, filterValue, data }) returns a boolean.
filterDelaynumberMs to wait after typing in a filter before it applies (default 250).
advancedFilterFieldsstring[]Columns searched by the quick-search box above the grid.
advancedFilterLabel / advancedFilterPlaceholderReactNodeLabel and placeholder of the quick-search box.

Built-in operators: string contains, eq, neq, startsWith, endsWith; number eq, neq, gt, gte, lt, lte, inrange; select eq, inlist; bool eq.

Rows

PropTypeDescription
rowHeightnumber | ({ data, rowIndex }) => numberRow height in px (default 35). The function form sets each row's height.
headerHeightnumberHeader height in px.
rowClassName / rowStylevalue or (rowProps) => valueClasses and style of a row.
onRenderRow(rowProps) => voidCalled for every rendered row. Keys you add to rowProps become DOM attributes.
showZebraRows / showHoverRowsbooleanStriped rows and hover paint.
emptyTextReactNodeShown when there are no rows.
footer{ render: { [column]: node }, colspan?: { [column]: n } }One footer row that sticks to the bottom.
highlightedRowrow or row idRow drawn with the active style.
onRowReorder({ rows, data, fromIndex, toIndex }) => voidLets the user reorder rows (see below).

Row reorder

With onRowReorder the user can drag a row to a new position with the mouse, or move the active row with Alt+ArrowUp / Alt+ArrowDown. The grid doesn't change its data: rows is a new array of the loaded top-level rows in their new order (the same row objects), pass it back as the dataSource. data is the moved row, fromIndex and toIndex its index in the loaded rows before and after the move.

const [rows, setRows] = React.useState(initialRows);
<AzGrid columns={columns} dataSource={rows} onRowReorder={({ rows }) => setRows(rows)} />;

Reordering is off while the rows are sorted (the shown order isn't the data order), with allowChildRows and with pagination: 'remote'. A row with an open cell editor can't be dragged. Dragging uses native HTML5 drag and drop, so it works with a mouse, not on touch screens. A dragged row lands after a row below it and before a row above it. While dragging, the row gets azgrid__row--dragging and the row under the pointer azgrid__row--drop-after or --drop-before, drawn as a line in --azgrid-accent.

To fit n rows without a scrollbar, give the grid get_grid_height(n, rowHeight, headerHeight) px of height: headerHeight + 1 + n * rowHeight + 2 (the header's 1px bottom border and the grid's 1px top and bottom border of the default theme). Add the filter row, footer and pagination bar when they are shown.

Tree and details

PropTypeDescription
allowChildRowsbooleanRows with __children (or __parent__table_id) render as a tree.
expandedNodes / defaultExpandedNodes / onExpandedNodesChange{ [rowId]: boolean }Expanded tree nodes.
RowDetail({ data, rowIndex, rowId, toggle }) => ReactNodeRendered under an expanded row. Adds an expand column.
rowExpandHeightnumber | ({ data }) => numberHeight of the details block.
expandedRows / defaultExpandedRows / onExpandedRowsChange{ [rowId]: boolean }Rows whose details are open.

Selection

PropTypeDescription
selected / defaultSelected / onSelectionChangetrue | { [rowId]: row } | nullSelected rows. true means all rows.
multiSelectbooleanThe checkbox and its cell toggle the row, shift click selects a range.
toggleSelectionOnRowClickbooleanA click anywhere on a row toggles it like its checkbox. Without it a row click only makes the row active and doesn't change the selection.
checkboxColumnbooleanAdds a checkbox column with a select-all header.
checkboxOnlyRowSelectbooleanOnly the checkbox selects, a row click doesn't.
rowIndexColumnbooleanAdds a row number column.
cellSelection / defaultCellSelection / onCellSelectionChange{ "rowId,column": true }Cell selection.

Editing

PropTypeDescription
editableboolean | (value, cellProps) => booleanTurns editing on. The column's editable decides per column.
editStartEvent'click' | 'dblclick'Event that opens a cell editor (default 'dblclick'). Enter opens it on the active row.
onEditComplete({ value, columnId, rowId, data, rowIndex }) => voidCalled when Enter, Tab or blur completes an edit. The grid does not change the row, you own the data.
onEditStart / onEditCancel({ rowId, columnId }) => voidCalled when an editor opens, or when Escape cancels it.

Keyboard and events

PropTypeDescription
activeIndex / defaultActiveIndex / onActiveIndexChangenumberActive row. Arrow keys, Home, End, PageUp and PageDown move it. With onRowReorder, Alt+ArrowUp/ArrowDown move the row itself.
onKeyDown(event) => voidKey events of the grid root. They run after the grid's own handling unless you call preventDefault.
onRowClick / onRowDoubleClick(rowIndex, row) => voidRow clicks.
contextMenuItemsmenu items or (row) => itemsRow context menu, built on @azrico/controls.
contextMenuClassNamestringExtra classes of the row context menu, which is portaled to <body>.
hideContextMenubooleanLeaves the browser's context menu available.
longPressContextMenubooleanA touch held on a row for 500ms opens the row context menu, like a right-click, and the click that ends the press is swallowed (default true).
dontAutoCloseContextMenu / escapeClosesContextMenubooleanContext menu closing behaviour (both default false).

Misc

PropTypeDescription
gridRefMutableRefObject<AzGridApi | null>Receives the grid API.
theme'light' | 'dark' | stringTheme class, see Themes.
rtlbooleanLays the grid out right to left. Without it the grid stays left to right on RTL pages.
className / styleClasses and style of the grid container.
ariaLabelstringAccessible name of the grid.
delayedSizebooleanWaits for the container size before laying out, for animated containers.
childrenReactNodeRendered after the grid, inside its container.

Column definition

FieldDescription
nameKey of the value in the row. field, key and columnName are aliases.
headerHeader content. title is an alias.
type'string', 'number', 'select' or 'bool'. Picks the editor and the filter. combo, boolean and truefalse are aliases.
itemsOptions of a select column, plain values or { id, label } objects.
editableboolean or (value, cellProps) => boolean. Typed columns are editable by default.
renderEditor / editorPropsCustom editor (editorProps) => node, and extra props for the editor.
renderCustom cell content (cellProps) => node. cellProps has value, data, rowIndex, rowId, depth, selected and active.
onRender(cellProps, { data }) => void, runs before render and may change cellProps.className / cellProps.style.
classNameString or (cellProps) => string, added to every cell.
cellDOMProps / headerDOMPropsExtra DOM attributes. Yours win over the grid's.
ariaLabel(value, data) => string, the aria-label of the cells.
width / defaultWidth, minWidth, maxWidthWidths in px. A saved width replaces width.
flex / defaultFlexShare of the leftover width. A resized or saved width replaces it.
resizable, sortable, filterable, hideablePer-column switches.
sortComparator (a, b, rowA, rowB) => number, or false to disable sorting.
filterEditor / filterEditorProps'text', 'number', 'select', 'bool' or a component, and its props (placeholder, dataSource).
visible / defaultVisibleControlled or initial visibility.
pinned'left' or 'right'. Usually set through leftColumns / rightColumns.
textAlign'start', 'center' or 'end'.

Grid API

gridRef.current exposes:

MemberDescription
focus()Focuses the grid.
setActiveIndex(index) / getActiveIndex()Sets or reads the active row and scrolls it into view.
getDOMNode()The grid root element.
visibleColumnsVisible columns in display order.
getData()Loaded top-level rows. Children are in __children.
setOriginalData(rows)Replaces the loaded rows without calling the dataSource.
setItemAt(index, item, { replace? })Merges or replaces one loaded row.
setItemPropertyAt(index, property, value)Changes one value of a loaded row.
refresh() / refreshColumn(name)Re-renders every row, or the cells of one column.
reload()Drops the cache and calls the dataSource again.
startEdit({ rowId, columnId }) / cancelEdit()Opens or cancels an editor.
setSelected(value)Sets the row selection.
hideColumnMenu()Closes the header menu.

DOM classes

The grid renders stable BEM class names. Style or query them freely. They are exported as AZGRID_CLASSES.

ClassElement
azgridGrid root (role="grid"), with azgrid--rtl when rtl is set, azgrid--clip-scrolled with clipScrolledCells and azgrid--reorderable while rows can be reordered
azgrid__scrollerScroll container of header, body and footer
azgrid__header, azgrid__header-row, azgrid__header-cellHeader. Cells carry data-column
azgrid__sort-tool, azgrid__menu-tool, azgrid__resize-handleHeader cell tools
azgrid__filter-row, azgrid__filter-cellFilter row
azgrid__body, azgrid__row-wrapper, azgrid__rowBody and rows. Rows carry data-row-id
azgrid__cell, azgrid__cell-contentBody cells. Cells carry data-column
azgrid__row-index, azgrid__checkbox, azgrid__expander, azgrid__tree-toolBuilt-in columns and tools
azgrid__detailsRow details block
azgrid__editorWrapper of an open cell editor
azgrid__footer, azgrid__footer-cellFooter row
azgrid__paginationPagination toolbar
azgrid__load-mask, azgrid__emptyLoad mask and empty text
azgrid-row--menu-openRow whose context menu is open
azgrid-column-menuHeader menu popup (portaled to <body>, carries the theme class and data-column)
azgrid-column-menu__submenu"Columns" submenu popup, also has azgrid-column-menu
azgrid-column-menu__list, azgrid-column-menu__separatorItem list (role="menu") and the line between groups
azgrid-column-menu__itemMenu entry, with __icon, __label and (submenu trigger) __arrow children
azgrid-column-menu__text, azgrid-column-menu__elementtype: 'text' / type: 'element' entries of columnMenuItems

Header menu items get a modifier naming the entry: --sort-asc, --sort-desc, --unsort, --columns (submenu trigger), --column (a show/hide checkbox in the submenu, also carries data-column) and --custom (columnMenuItems). State modifiers: --active (current sort, or isActive of a custom item), --checked (visible column) and --open (submenu trigger while its submenu is shown).

Rows get --odd/--even, --selected, --active, --expanded and --editing modifiers, and --dragging, --drop-before/--drop-after during a row reorder. Cells get --selected, --active, --editing, --readonly, --pinned-left/--pinned-right and --pinned-edge modifiers. Header cells get --sortable, --sorted-asc/--sorted-desc and --resizing modifiers.

Saved column widths

Set gridId to keep the column widths a user resizes across reloads. Widths are saved in localStorage and matched to columns by name.

import { AzGrid, setGridStorageScope, clearColumnSizes } from '@azrico/reactgrid';

setGridStorageScope(user.id); // once, before the grids render, so users of one browser don't share widths

<AzGrid gridId="current-stock" columns={columns} dataSource={rows} />;

clearColumnSizes('current-stock'); // reset, takes effect when the grid remounts

A column's width is used as its defaultWidth when gridId is set, so it can be resized.

Accessibility

The grid exposes ARIA grid semantics, so screen readers and automation tools can read it from the accessibility tree.

ElementAttributes
Grid rootrole="grid", aria-rowcount (total rows incl. header; the full data count when paginated), aria-colcount (visible columns), aria-label, aria-readonly="true" when the grid isn't editable, aria-busy="true" while loading
Header rowrole="row", aria-rowindex="1"
Header cellsrole="columnheader", aria-colindex, aria-sort (ascending / descending / none, sortable columns only), data-column="<column id>"
Rowsrole="row", aria-rowindex (1-based, header is 1, includes the page offset), aria-selected when selection is enabled, data-row-id
Body cellsrole="gridcell", aria-colindex, data-column="<column name>", aria-readonly="true" when the cell can't be edited
Row-number cellsrole="rowheader"

New props:

  • ariaLabel?: string on the grid sets the accessible name of the grid.
  • ariaLabel?: (value, data) => string on a column sets aria-label on its cells. Use it for icons, badges or values whose visible text isn't descriptive.
const columns = [{ name: 'status', header: 'Status', ariaLabel: (value) => `Status: ${value}` }];

<AzGrid ariaLabel="Orders" columns={columns} dataSource={rows} />;

Override any cell attribute with the column's cellDOMProps / headerDOMProps. Values you set there are kept. An onRenderRow prop runs after the grid's own row attributes are set, so it can change them too.

Themes

Use theme="light" (default), theme="dark", or a custom name. The grid wrapper gets azgrid-scope and azgrid-theme-<name>; the portaled column and context menus (.azgrid-column-menu, .azgrid-context-menu) get the same theme class so they read the same variables. Custom names use light fallbacks for unspecified variables.

dark remains a deprecated alias. theme takes precedence.

Set --azgrid-* variables on a wrapper, :root, or a theme class. Each grid can use a different palette. Host variables always win: the theme file only declares --azgrid-preset-* fallbacks, never public defaults.

<div className="my-grid">
  <AzGrid theme="light" columns={columns} dataSource={rows} />
</div>
.my-grid {
  --azgrid-accent: #345b93;
  --azgrid-header-bg: #edf2f8;
  --azgrid-row-bg-hover: #e4ecf7;
}

Row states are painted in this order (later wins): zebra odd/even, tree rows, active, hover (also while the row's context menu is open), selected. Pinned cells copy the row's current background so they stay opaque while scrolling.

Check the stylesheets with node config/check-theme.cjs; regenerate the preset blocks and the table below with node config/generate-theme.cjs after editing the token manifest in that file.

CSS variables

All variables have light/dark fallbacks. Use valid CSS values for the named property. --azgrid-locked-column-shadow accepts a complete box-shadow value. --azgrid-header-height is not a token: the grid sets it on its root from the measured header so the filter row can stick under it.

VariableControls
--azgrid-bgGrid background
--azgrid-fgGrid text
--azgrid-borderGrid border and separators
--azgrid-font-familyGrid and control fonts
--azgrid-radiusGrid, input and menu corner radius; default 0
--azgrid-accentFocus outlines, sort arrows, resize handle, checkboxes, cell selection and the row reorder drop line
--azgrid-transparentTransparent structural surfaces (body, row wrapper, tool buttons)
--azgrid-muted-fgRead-only cells, inactive sort and menu tools, deleted-row strike
--azgrid-shadow-colorMenu shadow colour
--azgrid-header-bgHeader and footer background
--azgrid-header-fgHeader and footer text
--azgrid-header-borderHeader, filter row and footer separators
--azgrid-header-font-sizeHeader font size
--azgrid-header-text-transformHeader text transform
--azgrid-header-letter-spacingHeader letter spacing
--azgrid-header-font-weightHeader font weight
--azgrid-row-bg-evenEven and non-zebra rows
--azgrid-row-bg-oddOdd rows (zebra grids)
--azgrid-row-bg-hoverHovered rows, rows with an open menu, hovered buttons
--azgrid-row-fg-hoverHovered row text
--azgrid-row-bg-selectedSelected rows and cells
--azgrid-row-fg-selectedSelected row and cell text
--azgrid-row-bg-activeActive (focused) rows
--azgrid-cell-borderCell border colour
--azgrid-cell-border-widthCell border width
--azgrid-cell-paddingData and footer cell padding
--azgrid-filter-bgFilter row, input, editor and search background
--azgrid-filter-fgFilter input and editor text
--azgrid-filter-borderFilter input borders
--azgrid-filter-placeholderInput placeholder text
--azgrid-filter-focus-ringFocused input border and ring, open editor outline
--azgrid-pagination-bgPagination toolbar and control background
--azgrid-pagination-fgPagination text and icons
--azgrid-pagination-borderPagination control borders
--azgrid-menu-bgColumn and context menu background
--azgrid-menu-fgMenu text and icons
--azgrid-menu-borderMenu borders
--azgrid-menu-bg-hoverHovered and focused menu entries
--azgrid-scrollbar-trackScrollbar tracks
--azgrid-scrollbar-thumbScrollbar thumbs
--azgrid-empty-bgEmpty state background
--azgrid-empty-fgEmpty state text
--azgrid-loading-bgLoading overlay background
--azgrid-loading-fgLoading text
--azgrid-tree-bgTree grid row background
--azgrid-tree-fgTree grid text and expand tools
--azgrid-details-bgRow details background
--azgrid-locked-column-shadowPinned column edge shadow (complete box-shadow value)

example

See src/example.tsx for light, dark and a complete custom deco palette.

Custom renderers must style their own content. External menu portal containers need azgrid-scope, the matching azgrid-theme-<name> class and the host variables.

版本与发布记录

@azrico/reactgrid 共发布 182 个版本,首次发布于 2022/11/30;过去 12 个月发布了 30 个版本。

版本发布日期距今
2.2.1latest2026/10/312 天前
2.2.02026/10/303 天前
2.1.22026/10/304 天前
2.1.12026/10/268 天前
2.1.02026/10/268 天前
2.0.42026/10/268 天前

关于 @azrico/reactgrid 的常见问题

@azrico/reactgrid 是什么?

React数据网格上的TanStack表

如何安装 @azrico/reactgrid?

在项目目录运行 npm install @azrico/reactgrid,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:clsx(>=1.2.1)、react(>=18.2.0 || ^19.0.0)、@azrico/object(>=1.4.97)、react-use-size(>=3.0.1)、@azrico/controls(>=1.6.4)、@tanstack/react-table(>=8.20.0)、@tanstack/react-virtual(>=3.10.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@azrico/reactgrid 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@azrico/reactgrid 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@azrico/reactgrid 可以商用吗?

@azrico/reactgrid 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@azrico/reactgrid 还在维护吗?

最新版本 2.2.1 发布于 2026/10/31(2 天前);至今共发布 182 个版本,其中过去 12 个月发布了 30 个;首次发布于 2022/11/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。