@gravity-ui/react-data-table 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,14 @@ Cell grouping is supported: rows are first sorted by grouped columns. Grouping i
7
7
  Multi-column sorting is also supported. Ctrl+Click on a column adds a column at the end
8
8
  of the sort list. A simple Click sorts the table by this column only. Sorting order is switched in the sequence: `none -> default -> reversed default -> none`.
9
9
 
10
+ ## Virtualization and React StrictMode
11
+
12
+ Virtualization (`settings.dynamicRender: true`) relies on `react-list`, which has a compatibility limitation with React 18+ StrictMode in development. During StrictMode's mount/unmount/remount check, the scroll listener is removed and not restored. Scrolling can then show empty areas in `uniform` and `variable` modes or stop rendering additional rows in `simple` mode.
13
+
14
+ This StrictMode remount check does not run in production builds.
15
+
16
+ `@gravity-ui/react-data-table` is in maintenance mode and will not receive new features. We recommend migrating to [@gravity-ui/table](https://github.com/gravity-ui/table).
17
+
10
18
  ## Properties
11
19
 
12
20
  | Property | Type | Required | Default | Description |
@@ -35,7 +43,7 @@ of the sort list. A simple Click sorts the table by this column only. Sorting or
35
43
 
36
44
  | Property | Type | Default | Description |
37
45
  | :------------------------------------------ | :----------------------------------------- | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
- | displayIndices | `Boolean` | `true` | Whether to show row indexes (starting from `startIndex`) |
46
+ | displayIndices | `Boolean \| {maxIndex: number}` | `true` | Whether to show row indexes (starting from `startIndex`). When set to an object with maxIndex, it controls the width of the index column based on the specified maximum index value rather than the actual data length |
39
47
  | stickyHead | `DataTable.FIXED DataTable.MOVING` | | Enable sticky header in one of two modes. The `DataTable.FIXED` mode is used if the table container is fixed relative to the page. If the page with a container is scrollable, better use `DataTable.MOVING`, but for this your browser needs to support `position: sticky`. Otherwise, sticky header will be completely disabled. |
40
48
  | stickyTop | `Number` | | Stick the header at the desired height (in the `DataTable.MOVING` mode). Use it if the scrollable container includes other content apart from the table. If the header fails to stick to the edge of the container, better use exactly positioned spacers so that the table content does not bulge out above the top of the header. |
41
49
  | stickyFooter | see stickyHead | | It's similar to `stickyHead` for `footerData` |
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import ReactList from 'react-list';
3
3
  import './DataTable.scss';
4
4
  import { HeightObserver } from './height-observer';
5
- import { Column, DataTableProps, HeadPosition, OrderType, Settings, SortedDataItem } from './types';
5
+ import { Column, DataTableProps, DisplayIndicesConfig, HeadPosition, OrderType, Settings, SortedDataItem } from './types';
6
6
  import { SlimColumn, getSortedData } from './util';
7
7
  interface CustomIcons {
8
8
  ICON_ASC: React.ReactNode;
@@ -27,7 +27,7 @@ export interface TableRowProps<T> {
27
27
  interface TableHeadProps<T> {
28
28
  dataColumns: DataColumns<T>;
29
29
  headColumns: HeadColumns<T>;
30
- displayIndices?: boolean;
30
+ displayIndices?: boolean | DisplayIndicesConfig;
31
31
  onSort?: TableProps<T>['onSort'];
32
32
  onResize?: TableProps<T>['onResize'];
33
33
  onColumnsUpdated?: (widths: number[]) => void;
@@ -41,12 +41,12 @@ declare class TableHead<T> extends React.Component<TableHeadProps<T>> {
41
41
  componentDidMount(): void;
42
42
  componentDidUpdate(): void;
43
43
  componentWillUnmount(): void;
44
- render(): JSX.Element;
44
+ render(): React.JSX.Element;
45
45
  _calculateColumnsWidth(): void;
46
46
  onSort(column?: SlimColumn, multisort?: boolean): void;
47
47
  _getOnSortClick(column: HeadCellColumn<T>): ((event: React.MouseEvent<HTMLTableHeaderCellElement>) => void) | undefined;
48
- renderHeadCell: (headCell: HeadCellsType<T>) => JSX.Element;
49
- renderHeadLevel: (row: HeadColumnsItem<T>, rowIndex: number) => JSX.Element;
48
+ renderHeadCell: (headCell: HeadCellsType<T>) => React.JSX.Element;
49
+ renderHeadLevel: (row: HeadColumnsItem<T>, rowIndex: number) => React.JSX.Element;
50
50
  dataRowsRef: (ref: HTMLTableSectionElement) => void;
51
51
  _getColumnRef: (index: number) => (node: HTMLTableHeaderCellElement) => void;
52
52
  _getRenderedColumn: (index?: number) => HTMLTableCellElement | undefined;
@@ -79,10 +79,10 @@ declare class StickyHead<T> extends React.Component<StickyHeadProps<T>, StickyHe
79
79
  state: StickyHeadState;
80
80
  heightObserver?: HeightObserver;
81
81
  _node?: HTMLElement;
82
- render(): JSX.Element;
82
+ render(): React.JSX.Element;
83
83
  setScrollLeft(scrollLeft: number): void;
84
84
  setRightPosition(value: number): void;
85
- renderHeader(props: Omit<StickyHeadProps<T>, 'mode' | 'top'>): JSX.Element;
85
+ renderHeader(props: Omit<StickyHeadProps<T>, 'mode' | 'top'>): React.JSX.Element;
86
86
  onDataRowsHeightChange: (height: number) => void;
87
87
  updateWidths(newWidths?: number[]): void;
88
88
  _nodeRef: (node: HTMLDivElement) => void;
@@ -111,12 +111,12 @@ declare class StickyFooter<T> extends React.PureComponent<StickyFooterProps<T>,
111
111
  componentDidMount(): void;
112
112
  componentDidUpdate(): void;
113
113
  componentWillUnmount(): void;
114
- render(): JSX.Element | null;
114
+ render(): React.JSX.Element | null;
115
115
  _nodeFixedRef: (node: HTMLDivElement) => void;
116
116
  _nodeMovingRef: (node: HTMLDivElement) => void;
117
117
  setScrollLeft(scrollLeft: number): void;
118
118
  setRightPosition(value: number): void;
119
- renderFooter(renderedRows: React.ReactNode): JSX.Element;
119
+ renderFooter(renderedRows: React.ReactNode): React.JSX.Element;
120
120
  updateWidths(newWidths?: number[]): void;
121
121
  }
122
122
  interface TableProps<T> {
@@ -158,7 +158,7 @@ declare class Table<T> extends React.PureComponent<TableProps<T>, TableState> {
158
158
  componentDidMount(): void;
159
159
  componentDidUpdate(): void;
160
160
  componentWillUnmount(): void;
161
- render(): JSX.Element;
161
+ render(): React.JSX.Element;
162
162
  _refBody: (node: HTMLDivElement) => void;
163
163
  _refBox: (node: HTMLDivElement) => void;
164
164
  _refHead: (node: TableHead<T>) => void;
@@ -169,20 +169,20 @@ declare class Table<T> extends React.PureComponent<TableProps<T>, TableState> {
169
169
  _onColumnsUpdated: (widths: number[]) => void;
170
170
  syncHeadWidths(): void;
171
171
  _getEmptyRow(): any;
172
- renderHead(): JSX.Element;
173
- renderStickyHead(): JSX.Element;
174
- renderStickyFooter(): JSX.Element;
172
+ renderHead(): React.JSX.Element;
173
+ renderStickyHead(): React.JSX.Element;
174
+ renderStickyFooter(): React.JSX.Element;
175
175
  onMovingHeaderDataRowsHeightChange: (height: number) => void;
176
176
  onMovingFooterHeightChange: (height: number) => void;
177
- renderRow: (vIndex: number) => JSX.Element;
178
- renderFooterRow: (rowData: T, index: number) => JSX.Element;
179
- renderHeaderRow: (rowData: T, index: number) => JSX.Element;
180
- renderRowImpl: (row: T, index: number, { onRowClick, odd, span, footer, headerData }?: RenderRowImplOptions<T>) => JSX.Element;
181
- renderTable: (items: React.ReactNode[], ref?: any) => JSX.Element;
182
- renderTableDynamic(): JSX.Element;
183
- renderTableSimple(): JSX.Element;
184
- renderHeaderRows(): JSX.Element[] | undefined;
185
- renderFooterRows(): JSX.Element[] | undefined;
177
+ renderRow: (vIndex: number) => React.JSX.Element;
178
+ renderFooterRow: (rowData: T, index: number) => React.JSX.Element;
179
+ renderHeaderRow: (rowData: T, index: number) => React.JSX.Element;
180
+ renderRowImpl: (row: T, index: number, { onRowClick, odd, span, footer, headerData }?: RenderRowImplOptions<T>) => React.JSX.Element;
181
+ renderTable: (items: React.ReactNode[], ref?: any) => React.JSX.Element;
182
+ renderTableDynamic(): React.JSX.Element;
183
+ renderTableSimple(): React.JSX.Element;
184
+ renderHeaderRows(): React.JSX.Element[] | undefined;
185
+ renderFooterRows(): React.JSX.Element[] | undefined;
186
186
  getStickyFooterMode(): HeadPositionInner;
187
187
  }
188
188
  interface RenderRowImplOptions<T> {
@@ -200,7 +200,7 @@ interface CellProps<T> {
200
200
  footer?: boolean;
201
201
  headerData?: boolean;
202
202
  }
203
- type InternalProps<T> = DataTableProps<T> & typeof DataTableView.defaultProps;
203
+ type InternalProps<T> = DataTableProps<T> & Omit<typeof DataTableView.defaultProps, 'settings'> & Required<Pick<DataTableProps<T>, 'settings'>>;
204
204
  interface DataTableViewState<T> extends SortOrderWithSortColumns {
205
205
  indexColumn?: Column<T>;
206
206
  settings: ReturnType<typeof DataTableView.calculateSettings>;
@@ -230,7 +230,7 @@ declare class DataTableView<T> extends React.Component<DataTableProps<T>, DataTa
230
230
  static calculateSettings(nextSettings: Settings): {
231
231
  stickyHead: HeadPositionInner;
232
232
  stickyFooter: HeadPositionInner;
233
- displayIndices: boolean;
233
+ displayIndices: boolean | DisplayIndicesConfig;
234
234
  stickyTop?: number | "auto" | undefined;
235
235
  syncHeadOnResize?: boolean | undefined;
236
236
  stickyBottom?: number | "auto" | undefined;
@@ -253,12 +253,12 @@ declare class DataTableView<T> extends React.Component<DataTableProps<T>, DataTa
253
253
  stripedRows?: boolean | undefined;
254
254
  headerMod?: "pre" | "multiline" | undefined;
255
255
  };
256
- static getIndexColumn<T extends HasHeaderFooterIndex>({ startIndex, data, visibleRowIndex, }: InternalProps<T>): Column<T>;
256
+ static getIndexColumn<T extends HasHeaderFooterIndex>({ startIndex, data, visibleRowIndex, settings, }: InternalProps<T>): Column<T>;
257
257
  static getDerivedStateFromProps<T extends HasHeaderFooterIndex>(nextProps: InternalProps<T>): {
258
258
  settings: {
259
259
  stickyHead: HeadPositionInner;
260
260
  stickyFooter: HeadPositionInner;
261
- displayIndices: boolean;
261
+ displayIndices: boolean | DisplayIndicesConfig;
262
262
  stickyTop?: number | "auto" | undefined;
263
263
  syncHeadOnResize?: boolean | undefined;
264
264
  stickyBottom?: number | "auto" | undefined;
@@ -288,7 +288,7 @@ declare class DataTableView<T> extends React.Component<DataTableProps<T>, DataTa
288
288
  settings: {
289
289
  stickyHead: HeadPositionInner;
290
290
  stickyFooter: HeadPositionInner;
291
- displayIndices: boolean;
291
+ displayIndices: boolean | DisplayIndicesConfig;
292
292
  stickyTop?: number | "auto" | undefined;
293
293
  syncHeadOnResize?: boolean | undefined;
294
294
  stickyBottom?: number | "auto" | undefined;
@@ -318,7 +318,7 @@ declare class DataTableView<T> extends React.Component<DataTableProps<T>, DataTa
318
318
  settings: {
319
319
  stickyHead: HeadPositionInner;
320
320
  stickyFooter: HeadPositionInner;
321
- displayIndices: boolean;
321
+ displayIndices: boolean | DisplayIndicesConfig;
322
322
  stickyTop?: number | "auto" | undefined;
323
323
  syncHeadOnResize?: boolean | undefined;
324
324
  stickyBottom?: number | "auto" | undefined;
@@ -345,9 +345,9 @@ declare class DataTableView<T> extends React.Component<DataTableProps<T>, DataTa
345
345
  };
346
346
  state: DataTableViewState<T>;
347
347
  table?: Table<T>;
348
- render(): JSX.Element;
348
+ render(): React.JSX.Element;
349
349
  _tableRef: (node: Table<T>) => void;
350
- renderMemoizedCell: ({ column, value, row, index, footer, headerData }: CellProps<T>) => JSX.Element;
350
+ renderMemoizedCell: ({ column, value, row, index, footer, headerData }: CellProps<T>) => React.JSX.Element;
351
351
  getColumn: (column: Column<T>, columnIndex: number) => {
352
352
  resizeable: boolean;
353
353
  sortable: boolean;
@@ -355,7 +355,7 @@ declare class DataTableView<T> extends React.Component<DataTableProps<T>, DataTa
355
355
  _getValue: (row: T) => any;
356
356
  _getTitle: (row: T) => any;
357
357
  _getSortValue: (row: T) => any;
358
- _renderValue: (({ value, row, index, footer, headerData }: Omit<CellProps<T>, 'column'>) => JSX.Element) | (({ value }: Partial<CellProps<T>>) => any);
358
+ _renderValue: (({ value, row, index, footer, headerData }: Omit<CellProps<T>, 'column'>) => React.JSX.Element) | (({ value }: Partial<CellProps<T>>) => any);
359
359
  _getOnClick: ((data: {
360
360
  row: T;
361
361
  index: number;
@@ -457,7 +457,7 @@ export default class DataTable<T> extends React.PureComponent<DataTableProps<T>,
457
457
  componentDidMount(): void;
458
458
  componentDidUpdate(prevProps: Readonly<DataTableProps<T>>): void;
459
459
  componentDidCatch(error: unknown): void;
460
- render(): JSX.Element;
460
+ render(): React.JSX.Element;
461
461
  _tableRef: (node: DataTableView<T>) => void;
462
462
  resize(): void;
463
463
  }
@@ -608,8 +608,10 @@ class DataTableView extends React.Component {
608
608
  static calculateSettings(nextSettings) {
609
609
  return Object.assign(Object.assign(Object.assign({}, DataTableView.defaultProps.settings), nextSettings), { stickyHead: DataTableView.normalizeStickyHead(nextSettings.stickyHead), stickyFooter: DataTableView.normalizeStickyHead(nextSettings.stickyFooter) });
610
610
  }
611
- static getIndexColumn({ startIndex, data, visibleRowIndex, }) {
612
- const lastIndex = startIndex + data.length + 1;
611
+ static getIndexColumn({ startIndex, data, visibleRowIndex, settings, }) {
612
+ const lastIndex = typeof settings.displayIndices === 'object'
613
+ ? settings.displayIndices.maxIndex
614
+ : startIndex + data.length + 1;
613
615
  return {
614
616
  name: INDEX_COLUMN,
615
617
  header: '#',
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  interface ResizeHandlerProps {
3
3
  getColumn: (index?: number) => HTMLTableCellElement | undefined;
4
4
  columnIndex?: number;
@@ -7,5 +7,5 @@ interface ResizeHandlerProps {
7
7
  minWidth?: number;
8
8
  onResize?: (columnId: string, width: number) => void;
9
9
  }
10
- export declare function ResizeHandler({ getColumn, columnIndex, columnId, minWidth, maxWidth, onResize, }: ResizeHandlerProps): JSX.Element;
10
+ export declare function ResizeHandler({ getColumn, columnIndex, columnId, minWidth, maxWidth, onResize, }: ResizeHandlerProps): React.JSX.Element;
11
11
  export {};
@@ -67,8 +67,11 @@ export interface Column<T> {
67
67
  resizeMaxWidth?: number;
68
68
  }
69
69
  export type DynamicInnerRefT = ReactList;
70
+ export interface DisplayIndicesConfig {
71
+ maxIndex: number;
72
+ }
70
73
  export interface Settings {
71
- displayIndices?: boolean;
74
+ displayIndices?: boolean | DisplayIndicesConfig;
72
75
  stickyHead?: HeadPosition;
73
76
  stickyTop?: 'auto' | number;
74
77
  syncHeadOnResize?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/react-data-table",
3
- "version": "2.1.1",
3
+ "version": "3.0.0",
4
4
  "description": "DataTable component",
5
5
  "keywords": [
6
6
  "table"
@@ -62,7 +62,7 @@
62
62
  "@gravity-ui/prettier-config": "^1.0.1",
63
63
  "@gravity-ui/stylelint-config": "^2.0.0",
64
64
  "@gravity-ui/tsconfig": "^1.0.0",
65
- "@gravity-ui/uikit": "^6.1.1",
65
+ "@gravity-ui/uikit": "^8.0.0",
66
66
  "@storybook/addon-actions": "^7.3.1",
67
67
  "@storybook/addon-essentials": "^7.3.1",
68
68
  "@storybook/addon-interactions": "^7.3.1",
@@ -70,8 +70,8 @@
70
70
  "@storybook/preset-scss": "^1.0.3",
71
71
  "@storybook/react": "^7.3.1",
72
72
  "@storybook/react-webpack5": "^7.3.1",
73
- "@types/react": "16.14.21",
74
- "@types/react-dom": "16.9.14",
73
+ "@types/react": "18.3.31",
74
+ "@types/react-dom": "18.3.7",
75
75
  "@types/react-list": "0.8.7",
76
76
  "@typescript-eslint/eslint-plugin": "^5.50.0",
77
77
  "copyfiles": "2.4.1",
@@ -82,8 +82,8 @@
82
82
  "postcss": "^8.4.28",
83
83
  "prettier": "2.5.1",
84
84
  "prop-types": "^15.8.1",
85
- "react": "16.14.0",
86
- "react-dom": "16.14.0",
85
+ "react": "^18.3.1",
86
+ "react-dom": "^18.3.1",
87
87
  "sass": "1.65",
88
88
  "sass-loader": "^13.3.2",
89
89
  "simple-git-hooks": "2.9",
@@ -94,7 +94,7 @@
94
94
  "typescript": "^5.1.6"
95
95
  },
96
96
  "peerDependencies": {
97
- "react": ">=16.14.0"
97
+ "react": ">=18.0.0"
98
98
  },
99
99
  "publishConfig": {
100
100
  "access": "public"