es-grid-template 1.9.93 → 1.9.95

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/es/grid-component/GridRefreshButton.css +9 -9
  3. package/es/grid-component/hooks/rowFocus.d.ts +11 -0
  4. package/es/grid-component/hooks/rowFocus.js +25 -0
  5. package/es/grid-component/index.d.ts +2 -2
  6. package/es/grid-component/type.d.ts +10 -0
  7. package/es/group-component/TableContainer.js +2 -0
  8. package/es/group-component/TableContainerEdit.js +2 -0
  9. package/es/group-component/body/TableBodyCell.js +4 -0
  10. package/es/group-component/body/TableBodyCellEdit.js +4 -0
  11. package/es/group-component/body/TableBodyCellEmpty.js +4 -0
  12. package/es/group-component/body/TableBodyRow.js +6 -3
  13. package/es/group-component/body/TableBodyRowGroupCell.js +4 -0
  14. package/es/group-component/hook/utils.d.ts +3 -3
  15. package/es/group-component/useContext.d.ts +2 -0
  16. package/es/index.d.ts +1 -1
  17. package/es/table-component/TableContainer.js +2 -0
  18. package/es/table-component/TableContainerEdit.js +2 -0
  19. package/es/table-component/body/TableBody.js +4 -0
  20. package/es/table-component/body/TableBodyCell.js +4 -0
  21. package/es/table-component/body/TableBodyCellEdit.js +4 -0
  22. package/es/table-component/body/TableBodyRow.js +12 -4
  23. package/es/table-component/useContext.d.ts +2 -0
  24. package/es/table-virtuoso/InternalTable.js +54 -11
  25. package/es/table-virtuoso/body/TableBodyCell.js +4 -0
  26. package/es/table-virtuoso/body/TableBodyCellRowGroup.js +4 -0
  27. package/es/table-virtuoso/body/TableBodyRow.js +4 -1
  28. package/es/table-virtuoso/table/Grid.js +37 -8
  29. package/es/table-virtuoso/table/TableContainer.js +2 -0
  30. package/es/table-virtuoso/useContext.d.ts +2 -0
  31. package/lib/grid-component/GridRefreshButton.css +9 -9
  32. package/lib/grid-component/hooks/rowFocus.d.ts +11 -0
  33. package/lib/grid-component/hooks/rowFocus.js +32 -0
  34. package/lib/grid-component/index.d.ts +2 -2
  35. package/lib/grid-component/type.d.ts +10 -0
  36. package/lib/group-component/TableContainer.js +2 -0
  37. package/lib/group-component/TableContainerEdit.js +2 -0
  38. package/lib/group-component/body/TableBodyCell.js +4 -0
  39. package/lib/group-component/body/TableBodyCellEdit.js +4 -0
  40. package/lib/group-component/body/TableBodyCellEmpty.js +4 -0
  41. package/lib/group-component/body/TableBodyRow.js +6 -3
  42. package/lib/group-component/body/TableBodyRowGroupCell.js +4 -0
  43. package/lib/group-component/hook/utils.d.ts +9 -9
  44. package/lib/group-component/useContext.d.ts +2 -0
  45. package/lib/index.d.ts +1 -1
  46. package/lib/table-component/TableContainer.js +2 -0
  47. package/lib/table-component/TableContainerEdit.js +2 -0
  48. package/lib/table-component/body/TableBody.js +4 -0
  49. package/lib/table-component/body/TableBodyCell.js +4 -0
  50. package/lib/table-component/body/TableBodyCellEdit.js +4 -0
  51. package/lib/table-component/body/TableBodyRow.js +12 -4
  52. package/lib/table-component/useContext.d.ts +2 -0
  53. package/lib/table-virtuoso/InternalTable.js +53 -10
  54. package/lib/table-virtuoso/body/TableBodyCell.js +4 -0
  55. package/lib/table-virtuoso/body/TableBodyCellRowGroup.js +4 -0
  56. package/lib/table-virtuoso/body/TableBodyRow.js +4 -1
  57. package/lib/table-virtuoso/table/Grid.js +37 -8
  58. package/lib/table-virtuoso/table/TableContainer.js +2 -0
  59. package/lib/table-virtuoso/useContext.d.ts +2 -0
  60. package/package.json +2 -2
@@ -8,7 +8,7 @@ import 'dayjs/locale/vi';
8
8
  import { faker } from '@faker-js/faker';
9
9
  import useMergedState from "rc-util/es/hooks/useMergedState";
10
10
  import { getCoreRowModel, getExpandedRowModel, getGroupedRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
11
- import { addRowIdArray, convertFlatColumn1, convertToObj, convertToObjTrue, filterDataByColumns, findAllChildrenKeys2, flatColumns2, getAllRowKey, getDiffent2Array, getFixedFields, getInvisibleColumns, groupArrayByColumns, isTreeArray, removeKeys } from "./hook/utils";
11
+ import { addRowIdArray, convertFlatColumn1, convertToObj, convertToObjTrue, filterDataByColumns, findAllChildrenKeys2, flattenArray, flattenData, flatColumns2, getAllRowKey, getDiffent2Array, getFixedFields, getInvisibleColumns, groupArrayByColumns, isTreeArray, removeKeys } from "./hook/utils";
12
12
  // import { convertToTanStackColumns } from './hook/useColumns'
13
13
  import { removeInvisibleColumns } from "../grid-component/hooks";
14
14
  import Grid from "./table/Grid";
@@ -82,6 +82,7 @@ const InternalTable = props => {
82
82
  const [columnResizeMode] = React.useState('onChange');
83
83
  const [columnResizeDirection] = React.useState('ltr');
84
84
  const [rowSelection, setRowSelection] = React.useState({});
85
+ const pruneSelection = selectionSettings?.pruneSelection === true;
85
86
 
86
87
  // const [grouping, setGrouping] = React.useState<GroupingState>([])
87
88
 
@@ -118,6 +119,9 @@ const InternalTable = props => {
118
119
  return isTreeArray(originData);
119
120
  }, [originData]);
120
121
  React.useEffect(() => {
122
+ if (pruneSelection) {
123
+ return;
124
+ }
121
125
  if (groupColumns && groupColumns.length > 0 && groupSetting?.client !== false && isDataOriginTree === false) {
122
126
  const abc = groupArrayByColumns(originData, groupColumns);
123
127
  const rs = filterDataByColumns(abc, filterStates, sorterStates, []);
@@ -126,9 +130,48 @@ const InternalTable = props => {
126
130
  const rs = filterDataByColumns(originData, filterStates, sorterStates, []);
127
131
  setTableData(rs);
128
132
  }
129
- }, [groupColumns, originData, filterStates, sorterStates, groupSetting?.client, isDataOriginTree]);
133
+ }, [groupColumns, originData, filterStates, sorterStates, groupSetting?.client, isDataOriginTree, pruneSelection]);
130
134
  // }, [groupColumns, originData, filterStates, sorterStates, groupSetting?.client])
131
135
 
136
+ // Resolve the opt-in view before paint, including inline grouping arrays.
137
+ const groupColumnsKey = JSON.stringify(groupColumns ?? []);
138
+ const viewData = React.useMemo(() => {
139
+ if (!pruneSelection) {
140
+ return tableData;
141
+ }
142
+ const groups = JSON.parse(groupColumnsKey);
143
+ const grouped = groups.length && groupSetting?.client !== false && !isDataOriginTree ? groupArrayByColumns(originData, groups) : originData;
144
+ return filterDataByColumns(grouped, filterStates, sorterStates, []);
145
+ }, [pruneSelection, tableData, groupColumnsKey, originData, groupSetting?.client, isDataOriginTree, filterStates, sorterStates]);
146
+ const effectiveRowSelection = React.useMemo(() => {
147
+ if (!pruneSelection || props.loading) {
148
+ return rowSelection;
149
+ }
150
+ const ids = new Set(flattenArray(viewData).map(row => String(row.rowId)));
151
+ const next = Object.fromEntries(Object.entries(rowSelection).filter(([selectedId, checked]) => checked && ids.has(selectedId)));
152
+
153
+ // A group can stay checked only if its remaining real children are checked.
154
+ const checkGroups = rows => {
155
+ rows.forEach(row => {
156
+ if (row.isGroupRow && next[String(row.rowId)]) {
157
+ const children = flattenData('children', row.children ?? []).filter(child => !child.isGroupRow && !selectionSettings?.getCheckboxProps?.(child)?.disabled);
158
+ if (!children.length || children.some(child => !next[String(child.rowId)])) {
159
+ delete next[String(row.rowId)];
160
+ }
161
+ }
162
+ if (Array.isArray(row.children)) {
163
+ checkGroups(row.children);
164
+ }
165
+ });
166
+ };
167
+ checkGroups(viewData);
168
+ return Object.keys(next).length === Object.keys(rowSelection).length ? rowSelection : next;
169
+ }, [pruneSelection, props.loading, rowSelection, viewData, selectionSettings?.getCheckboxProps]);
170
+ React.useEffect(() => {
171
+ if (effectiveRowSelection !== rowSelection) {
172
+ setRowSelection(prev => prev === rowSelection ? effectiveRowSelection : prev);
173
+ }
174
+ }, [effectiveRowSelection, rowSelection]);
132
175
  React.useEffect(() => {
133
176
  // setColumns(updateWidthsByOther(propsColumns, columns))
134
177
  setColumns(propsColumns);
@@ -142,8 +185,8 @@ const InternalTable = props => {
142
185
  });
143
186
  }, [t, columns, format, editAble]);
144
187
  const isDataTree = React.useMemo(() => {
145
- return isTreeArray(tableData);
146
- }, [tableData]);
188
+ return isTreeArray(viewData);
189
+ }, [viewData]);
147
190
  const columnPinning = React.useMemo(() => {
148
191
  return {
149
192
  left: getFixedFields(columns, 'left'),
@@ -203,11 +246,11 @@ const InternalTable = props => {
203
246
  };
204
247
  const table = useReactTable({
205
248
  _features: [OperatorFeature],
206
- data: tableData,
249
+ data: viewData,
207
250
  // data: mergedData,
208
251
  columns: mergedColumns,
209
252
  state: {
210
- rowSelection,
253
+ rowSelection: effectiveRowSelection,
211
254
  expanded,
212
255
  columnPinning,
213
256
  columnVisibility: columnsHiddenKeys ? convertToObj(columnsHiddenKeys) : columnVisibility,
@@ -282,20 +325,20 @@ const InternalTable = props => {
282
325
  React.useEffect(() => {
283
326
  if (expandable?.preserveExpandedOnDataChange) {
284
327
  // Chờ cây có dữ liệu mới khởi tạo; những lần thay đổi tableData sau đó không reset expanded.
285
- if (initializedExpansionRef.current || tableData.length === 0) {
328
+ if (initializedExpansionRef.current || viewData.length === 0) {
286
329
  return;
287
330
  }
288
331
  initializedExpansionRef.current = true;
289
332
  }
290
333
  if (defaultExpandAllRows) {
291
- const allKeys = findAllChildrenKeys2(tableData, rowKey, 'children');
334
+ const allKeys = findAllChildrenKeys2(viewData, rowKey, 'children');
292
335
  setExpanded(convertToObjTrue(allKeys));
293
336
  } else {
294
337
  if (defaultExpandedRowKeys) {
295
338
  setExpanded(convertToObjTrue(defaultExpandedRowKeys ?? []));
296
339
  }
297
340
  }
298
- }, [defaultExpandAllRows, defaultExpandedRowKeys, tableData, expandable?.preserveExpandedOnDataChange]);
341
+ }, [defaultExpandAllRows, defaultExpandedRowKeys, viewData, expandable?.preserveExpandedOnDataChange]);
299
342
  const triggerGroupColumns = groupedColumns => {
300
343
  // const abc = updateColumnsByGroup(columns, groupedColumns)
301
344
 
@@ -382,7 +425,7 @@ const InternalTable = props => {
382
425
  originData: originData
383
426
  // dataSource={mergedData}
384
427
  ,
385
- dataSource: tableData,
428
+ dataSource: viewData,
386
429
  locale: locale,
387
430
  format: format
388
431
  // columns={convertColumns(mergedColumns)}
@@ -417,7 +460,7 @@ const InternalTable = props => {
417
460
  columnSizing: columnSizing,
418
461
  columnSizingInfo: columnSizingInfo,
419
462
  setColumnSizing: setColumnSizing,
420
- rowSelection: rowSelection,
463
+ rowSelection: effectiveRowSelection,
421
464
  pagination: pagination
422
465
  })))));
423
466
  };
@@ -1,3 +1,4 @@
1
+ import { notifyArrowRowFocus } from "../../grid-component/hooks/rowFocus";
1
2
  import Space from "rc-master-ui/es/space";
2
3
  import { getCommonPinningStyles, getFormat } from "../hook/utils";
3
4
  import Checkbox from "rc-master-ui/es/checkbox/Checkbox";
@@ -151,6 +152,7 @@ const TableBodyCell = props => {
151
152
  id,
152
153
  prefix,
153
154
  focusedCell,
155
+ rowFocus,
154
156
  setFocusedCell,
155
157
  // endCell,
156
158
  // startCell,
@@ -382,6 +384,7 @@ const TableBodyCell = props => {
382
384
  colId: cell.column.id,
383
385
  rowId: nextId
384
386
  });
387
+ notifyArrowRowFocus(table.getRow(nextId).original, 'arrowDown', selectionSettings?.useArrow, rowFocus);
385
388
  const row = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
386
389
  const cellFocus = row?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
387
390
  if (cellFocus) {
@@ -395,6 +398,7 @@ const TableBodyCell = props => {
395
398
  colId: cell.column.id,
396
399
  rowId: nextId
397
400
  });
401
+ notifyArrowRowFocus(table.getRow(nextId).original, 'arrowUp', selectionSettings?.useArrow, rowFocus);
398
402
  const row = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
399
403
  const cellFocus = row?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
400
404
  if (cellFocus) {
@@ -1,3 +1,4 @@
1
+ import { notifyArrowRowFocus } from "../../grid-component/hooks/rowFocus";
1
2
  import { getCommonPinningStyles } from "../hook/utils";
2
3
  import classNames from "classnames";
3
4
  import React from "react";
@@ -16,6 +17,7 @@ const TableBodyCellRowGroup = props => {
16
17
  id,
17
18
  prefix,
18
19
  focusedCell,
20
+ rowFocus,
19
21
  setFocusedCell,
20
22
  expanded,
21
23
  setExpanded,
@@ -97,6 +99,7 @@ const TableBodyCellRowGroup = props => {
97
99
  colId: cell.column.id,
98
100
  rowId: nextId
99
101
  });
102
+ notifyArrowRowFocus(table.getRow(nextId).original, 'arrowDown', selectionSettings?.useArrow, rowFocus);
100
103
  const row = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
101
104
  const cellFocus = row?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
102
105
  if (cellFocus) {
@@ -110,6 +113,7 @@ const TableBodyCellRowGroup = props => {
110
113
  colId: cell.column.id,
111
114
  rowId: nextId
112
115
  });
116
+ notifyArrowRowFocus(table.getRow(nextId).original, 'arrowUp', selectionSettings?.useArrow, rowFocus);
113
117
  const row = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
114
118
  const cellFocus = row?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
115
119
  if (cellFocus) {
@@ -1,4 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import { getRowFocusHandlers } from "../../grid-component/hooks/rowFocus";
2
3
  import TableBodyCell from "./TableBodyCell";
3
4
  import { flexRender } from "@tanstack/react-table";
4
5
  import React from "react";
@@ -26,6 +27,7 @@ const TableBodyRow = ({
26
27
  const {
27
28
  prefix,
28
29
  recordDoubleClick,
30
+ rowFocus,
29
31
  focusedCell,
30
32
  rowClassName,
31
33
  onRowStyles,
@@ -60,7 +62,8 @@ const TableBodyRow = ({
60
62
  style: {
61
63
  ...rowStyles,
62
64
  height: rowheight
63
- },
65
+ }
66
+ }, getRowFocusHandlers(row.original, rowFocus), {
64
67
  onDoubleClick: e => {
65
68
  recordDoubleClick?.({
66
69
  e,
@@ -51,16 +51,46 @@ const Grid = props => {
51
51
  setColumnSizing,
52
52
  columnFilters,
53
53
  setColumnOrder,
54
- rowSelection,
55
54
  className: tableClassNames,
56
55
  ...rest
57
56
  } = props;
57
+ const selectedRowState = table.getState().rowSelection;
58
58
  const [isSelectionChange, setIsSelectionChange] = React.useState({
59
59
  isChange: false,
60
60
  type: '',
61
61
  rowData: {},
62
62
  rowsData: []
63
63
  });
64
+ const rowSelectedRef = React.useRef(rowSelected);
65
+ React.useEffect(() => {
66
+ rowSelectedRef.current = rowSelected;
67
+ }, [rowSelected]);
68
+ const pruneSelection = selectionSettings?.pruneSelection === true;
69
+ const selectedViewRows = React.useMemo(() => {
70
+ if (!pruneSelection || props.loading) {
71
+ return [];
72
+ }
73
+ return table.getCoreRowModel().flatRows.filter(row => !row.original.isGroupRow && selectedRowState[row.id]).map(row => row.original);
74
+ }, [pruneSelection, props.loading, table, dataSource, selectedRowState]);
75
+ const selectedViewIds = JSON.stringify(selectedViewRows.map(row => String(row.rowId)).sort());
76
+ const lastNotifiedSelection = React.useRef(null);
77
+
78
+ // Keep event handlers in sync with the view without another state/effect.
79
+ const selectionChange = pruneSelection && !props.loading ? {
80
+ ...isSelectionChange,
81
+ rowsData: selectedViewRows
82
+ } : isSelectionChange;
83
+ React.useEffect(() => {
84
+ if (!pruneSelection || props.loading || lastNotifiedSelection.current === selectedViewIds) {
85
+ return;
86
+ }
87
+ lastNotifiedSelection.current = selectedViewIds;
88
+ rowSelected?.({
89
+ type: isSelectionChange.isChange ? isSelectionChange.type : 'selectionPruned',
90
+ rowData: isSelectionChange.rowData,
91
+ selected: selectedViewRows
92
+ });
93
+ }, [pruneSelection, props.loading, selectedViewIds, selectedViewRows, rowSelected, isSelectionChange.isChange, isSelectionChange.type, isSelectionChange.rowData]);
64
94
  const [sorterChange, setSorterChange] = React.useState(false);
65
95
  const [filterChange, setFilterChange] = React.useState(false);
66
96
  const [isFullScreen, setIsFullScreen] = React.useState(false);
@@ -77,18 +107,17 @@ const Grid = props => {
77
107
  // }, [mergedSelectedKeys])
78
108
 
79
109
  React.useEffect(() => {
80
- if (isSelectionChange.isChange) {
81
- const aa = table.getState().rowSelection;
82
- const ids = Object.keys(aa);
110
+ if (!pruneSelection && isSelectionChange.isChange) {
111
+ const ids = Object.keys(selectedRowState);
83
112
  const ssss = filterByIds(ids, isSelectionChange.rowsData ?? []); // lấy rowsData của trang hiện tại
84
113
 
85
- rowSelected?.({
114
+ rowSelectedRef.current?.({
86
115
  type: isSelectionChange.type,
87
116
  rowData: isSelectionChange.rowData,
88
117
  selected: ssss.filter(x => !x.isGroupRow)
89
118
  });
90
119
  }
91
- }, [isSelectionChange, rowSelection, table.getState().rowSelection]);
120
+ }, [isSelectionChange, selectedRowState, pruneSelection]);
92
121
  React.useEffect(() => {
93
122
  if (sorterChange) {
94
123
  const aa = table.getState().sorting;
@@ -179,7 +208,7 @@ const Grid = props => {
179
208
  originData: originData,
180
209
  prefix: prefix,
181
210
  selectionSettings: selectionSettings,
182
- isSelectionChange: isSelectionChange,
211
+ isSelectionChange: selectionChange,
183
212
  setIsSelectionChange: setIsSelectionChange,
184
213
  setSorterChange: setSorterChange,
185
214
  setFilterChange: setFilterChange,
@@ -249,7 +278,7 @@ const Grid = props => {
249
278
  originData: originData,
250
279
  prefix: prefix,
251
280
  selectionSettings: selectionSettings,
252
- isSelectionChange: isSelectionChange,
281
+ isSelectionChange: selectionChange,
253
282
  setIsSelectionChange: setIsSelectionChange,
254
283
  setSorterChange: setSorterChange,
255
284
  setFilterChange: setFilterChange,
@@ -29,6 +29,7 @@ const TableContainer = props => {
29
29
  expandable,
30
30
  wrapSettings,
31
31
  recordDoubleClick,
32
+ rowFocus,
32
33
  // triggerFilter,
33
34
  selectionSettings,
34
35
  isSelectionChange,
@@ -273,6 +274,7 @@ const TableContainer = props => {
273
274
  originData,
274
275
  wrapSettings,
275
276
  recordDoubleClick,
277
+ rowFocus,
276
278
  selectionSettings,
277
279
  isSelectionChange,
278
280
  setIsSelectionChange,
@@ -1,3 +1,4 @@
1
+ import type { RowFocusEventArgs } from "../grid-component/type";
1
2
  import type { Dispatch, SetStateAction } from 'react';
2
3
  import type { ColumnTable, ExpandableConfig, IFormat, IGroupSetting, IWrapSettings, Locale, PaginationConfig, RangeState, RecordDoubleClickEventArgs, RowClassName, SelectionSettings, SourceFilter } from "../grid-component/type";
3
4
  import type { SubmitHandler } from "react-hook-form";
@@ -19,6 +20,7 @@ export interface IContext<T> {
19
20
  setExpanded: Dispatch<SetStateAction<ExpandedState>>;
20
21
  expanded: ExpandedState;
21
22
  recordDoubleClick?: (args: RecordDoubleClickEventArgs<T>) => void;
23
+ rowFocus?: (args: RowFocusEventArgs<T>) => void;
22
24
  selectionSettings?: SelectionSettings;
23
25
  isSelectionChange?: {
24
26
  isChange: boolean;
@@ -1,9 +1,9 @@
1
- .ui-rc-grid-refresh-spin {
2
- transform-origin: center;
3
- transform-box: fill-box;
4
- animation: ui-rc-grid-refresh-spin 0.8s linear infinite;
5
- }
6
-
7
- @keyframes ui-rc-grid-refresh-spin {
8
- to { transform: rotate(360deg); }
9
- }
1
+ .ui-rc-grid-refresh-spin {
2
+ transform-origin: center;
3
+ transform-box: fill-box;
4
+ animation: ui-rc-grid-refresh-spin 0.8s linear infinite;
5
+ }
6
+
7
+ @keyframes ui-rc-grid-refresh-spin {
8
+ to { transform: rotate(360deg); }
9
+ }
@@ -0,0 +1,11 @@
1
+ import type { MouseEvent } from 'react';
2
+ import type { RowFocusEventArgs } from '../type';
3
+ type RowFocus<T> = (args: RowFocusEventArgs<T>) => void;
4
+ /** Capture clicks even when a cell handles the event itself. */
5
+ export declare function getRowFocusHandlers<T>(rowData: T, rowFocus?: RowFocus<T>): {
6
+ onClickCapture: (event: MouseEvent<HTMLElement>) => void;
7
+ onContextMenuCapture: (event: MouseEvent<HTMLElement>) => void;
8
+ };
9
+ /** Notify arrow focus without changing the existing navigation or selection. */
10
+ export declare function notifyArrowRowFocus<T>(rowData: T, method: 'arrowUp' | 'arrowDown', useArrow?: boolean, rowFocus?: RowFocus<T>): void;
11
+ export {};
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getRowFocusHandlers = getRowFocusHandlers;
7
+ exports.notifyArrowRowFocus = notifyArrowRowFocus;
8
+ /** Capture clicks even when a cell handles the event itself. */
9
+ function getRowFocusHandlers(rowData, rowFocus) {
10
+ return {
11
+ onClickCapture: event => {
12
+ if (event.button === 0) rowFocus?.({
13
+ rowData,
14
+ method: 'mouseLeftClick'
15
+ });
16
+ },
17
+ onContextMenuCapture: event => {
18
+ if (event.button === 2) rowFocus?.({
19
+ rowData,
20
+ method: 'mouseRightClick'
21
+ });
22
+ }
23
+ };
24
+ }
25
+
26
+ /** Notify arrow focus without changing the existing navigation or selection. */
27
+ function notifyArrowRowFocus(rowData, method, useArrow, rowFocus) {
28
+ if (useArrow === true) rowFocus?.({
29
+ rowData,
30
+ method
31
+ });
32
+ }
@@ -1,5 +1,5 @@
1
1
  import TempTable from './TempTable';
2
- import type { ColumnsTable, TableProps, ColumnTable, CommandItem, ContextMenuItem } from './type';
2
+ import type { ColumnsTable, TableProps, ColumnTable, CommandItem, ContextMenuItem, RowFocusEventArgs } from './type';
3
3
  import type { ToolbarItem } from "rc-master-ui/es/toolbar";
4
- export type { ColumnsTable, TableProps, ColumnTable, ToolbarItem, CommandItem, ContextMenuItem };
4
+ export type { ColumnsTable, TableProps, ColumnTable, ToolbarItem, CommandItem, ContextMenuItem, RowFocusEventArgs };
5
5
  export default TempTable;
@@ -451,6 +451,8 @@ export type TableProps<RecordType = AnyObject> = {
451
451
  recordDoubleClick?: (args: RecordDoubleClickEventArgs<RecordType>) => void;
452
452
  /** Click vào row */
453
453
  recordClick?: (args: RecordDoubleClickEventArgs<RecordType>) => void;
454
+ /** Notify mouse clicks or enabled arrow-key navigation independently of row selection. */
455
+ rowFocus?: (args: RowFocusEventArgs<RecordType>) => void;
454
456
  /** Filter */
455
457
  /** Hiển thị filter nâng cao */
456
458
  showAdvanceFilter?: boolean;
@@ -789,6 +791,8 @@ export type IWrapSettings = {
789
791
  wrapMode?: IWrapMode;
790
792
  };
791
793
  export type SelectionSettings<T = AnyObject> = {
794
+ /** Invoke rowFocus on ArrowUp/ArrowDown. Defaults to false. */
795
+ useArrow?: boolean;
792
796
  mode?: 'checkbox' | 'radio';
793
797
  type?: 'single' | 'multiple';
794
798
  checkboxOnly?: boolean;
@@ -796,6 +800,8 @@ export type SelectionSettings<T = AnyObject> = {
796
800
  checkedStrategy?: 'all' | 'parent' | 'child';
797
801
  columnWidth?: number;
798
802
  hideSelectAll?: boolean;
803
+ /** When true, keep selection only for records in the current filtered data view. Default: false. */
804
+ pruneSelection?: boolean;
799
805
  selectedRowKeys?: Key[];
800
806
  defaultSelectedRowKeys?: Key[];
801
807
  getCheckboxProps?: (record: T) => Partial<Omit<CheckboxProps, 'checked' | 'defaultChecked'>>;
@@ -824,6 +830,10 @@ export type RowSelection<T> = {
824
830
  checkboxOnly?: boolean;
825
831
  arrowKey?: boolean;
826
832
  };
833
+ export type RowFocusEventArgs<RecordType> = {
834
+ rowData: RecordType;
835
+ method: 'mouseLeftClick' | 'mouseRightClick' | 'arrowUp' | 'arrowDown';
836
+ };
827
837
  export type RecordDoubleClickEventArgs<RecordType> = {
828
838
  rowData: RecordType;
829
839
  rowIndex: number | undefined;
@@ -38,6 +38,7 @@ const TableContainer = props => {
38
38
  expandable,
39
39
  wrapSettings,
40
40
  recordDoubleClick,
41
+ rowFocus,
41
42
  // triggerFilter,
42
43
  selectionSettings,
43
44
  isSelectionChange,
@@ -325,6 +326,7 @@ const TableContainer = props => {
325
326
  // triggerFilter,
326
327
  wrapSettings,
327
328
  recordDoubleClick,
329
+ rowFocus,
328
330
  selectionSettings,
329
331
  isSelectionChange,
330
332
  setIsSelectionChange,
@@ -86,6 +86,7 @@ const TableContainerEdit = props => {
86
86
  expandable,
87
87
  wrapSettings,
88
88
  recordDoubleClick,
89
+ rowFocus,
89
90
  // triggerFilter,
90
91
  selectionSettings,
91
92
  isSelectionChange,
@@ -2213,6 +2214,7 @@ const TableContainerEdit = props => {
2213
2214
  originData,
2214
2215
  wrapSettings,
2215
2216
  recordDoubleClick,
2217
+ rowFocus,
2216
2218
  selectionSettings: {
2217
2219
  ...selectionSettings,
2218
2220
  checkboxOnly: true
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
+ var _rowFocus = require("../../grid-component/hooks/rowFocus");
8
9
  var _space = _interopRequireDefault(require("rc-master-ui/es/space"));
9
10
  var _Command = _interopRequireDefault(require("../components/command/Command"));
10
11
  var _utils = require("../hook/utils");
@@ -164,6 +165,7 @@ const TableBodyCell = props => {
164
165
  id,
165
166
  prefix,
166
167
  focusedCell,
168
+ rowFocus,
167
169
  setFocusedCell,
168
170
  // endCell,
169
171
  // startCell,
@@ -462,6 +464,7 @@ const TableBodyCell = props => {
462
464
  colId: cell.column.id,
463
465
  rowId: nextId
464
466
  });
467
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextId).original, 'arrowDown', selectionSettings?.useArrow, rowFocus);
465
468
  const rowQr = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
466
469
  const cellFocus = rowQr?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
467
470
  if (cellFocus) {
@@ -475,6 +478,7 @@ const TableBodyCell = props => {
475
478
  colId: cell.column.id,
476
479
  rowId: nextId
477
480
  });
481
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextId).original, 'arrowUp', selectionSettings?.useArrow, rowFocus);
478
482
  const rowQr = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
479
483
  const cellFocus = rowQr?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
480
484
  if (cellFocus) {
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
+ var _rowFocus = require("../../grid-component/hooks/rowFocus");
8
9
  var _space = _interopRequireDefault(require("rc-master-ui/es/space"));
9
10
  var _Command = _interopRequireDefault(require("../components/command/Command"));
10
11
  var _utils = require("../hook/utils");
@@ -202,6 +203,7 @@ const TableBodyCellEdit = props => {
202
203
  editingKey,
203
204
  prefix,
204
205
  focusedCell,
206
+ rowFocus,
205
207
  rangeState,
206
208
  setFocusedCell,
207
209
  setEditingKey,
@@ -810,6 +812,7 @@ const TableBodyCellEdit = props => {
810
812
  rowId: nextRowId,
811
813
  colId
812
814
  });
815
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextRowId).original, 'arrowDown', selectionSettings?.useArrow, rowFocus);
813
816
  setStartCell?.({
814
817
  rowId: nextRowId,
815
818
  colId
@@ -857,6 +860,7 @@ const TableBodyCellEdit = props => {
857
860
  rowId: nextRowId,
858
861
  colId
859
862
  });
863
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextRowId).original, 'arrowUp', selectionSettings?.useArrow, rowFocus);
860
864
  setStartCell?.({
861
865
  rowId: nextRowId,
862
866
  colId
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
+ var _rowFocus = require("../../grid-component/hooks/rowFocus");
8
9
  var _utils = require("../hook/utils");
9
10
  var _classnames = _interopRequireDefault(require("classnames"));
10
11
  var _react = _interopRequireDefault(require("react"));
@@ -22,6 +23,7 @@ const TableBodyCellEmpty = props => {
22
23
  id,
23
24
  prefix,
24
25
  focusedCell,
26
+ rowFocus,
25
27
  setFocusedCell,
26
28
  setIsSelectionChange,
27
29
  isSelectionChange,
@@ -107,6 +109,7 @@ const TableBodyCellEmpty = props => {
107
109
  colId: cell.column.id,
108
110
  rowId: nextId
109
111
  });
112
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextId).original, 'arrowDown', selectionSettings?.useArrow, rowFocus);
110
113
  const row = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
111
114
  const cellFocus = row?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
112
115
  if (cellFocus) {
@@ -120,6 +123,7 @@ const TableBodyCellEmpty = props => {
120
123
  colId: cell.column.id,
121
124
  rowId: nextId
122
125
  });
126
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextId).original, 'arrowUp', selectionSettings?.useArrow, rowFocus);
123
127
  const row = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
124
128
  const cellFocus = row?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
125
129
  if (cellFocus) {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _rowFocus = require("../../grid-component/hooks/rowFocus");
9
10
  var _TableBodyCell = _interopRequireDefault(require("./TableBodyCell"));
10
11
  var _TableBodyCellEdit = _interopRequireDefault(require("./TableBodyCellEdit"));
11
12
  var _react = _interopRequireDefault(require("react"));
@@ -35,6 +36,7 @@ const TableBodyRow = ({
35
36
  const {
36
37
  prefix,
37
38
  recordDoubleClick,
39
+ rowFocus,
38
40
  focusedCell,
39
41
  rowClassName,
40
42
  rowEditable,
@@ -60,7 +62,7 @@ const TableBodyRow = ({
60
62
  const rowClass = typeof rowClassName === 'function' ? rowClassName(row.original, row.index, row.depth) : rowClassName;
61
63
  const rowStyles = typeof onRowStyles === 'function' ? onRowStyles(row.original, row) : onRowStyles;
62
64
  const isRowEditable = rowEditable ? rowEditable(row.original) : true;
63
- return /*#__PURE__*/_react.default.createElement("div", {
65
+ return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
64
66
  "data-index": virtualRow.index //needed for dynamic row height measurement
65
67
  ,
66
68
  ref: rowVirtualizer.measureElement //measure dynamic row height
@@ -86,7 +88,8 @@ const TableBodyRow = ({
86
88
  height: isEditing ? virtualRow.size : undefined,
87
89
  minHeight: isEditing ? undefined : virtualRow.size,
88
90
  ...rowStyles
89
- },
91
+ }
92
+ }, (0, _rowFocus.getRowFocusHandlers)(row.original, rowFocus), {
90
93
  onDoubleClick: e => {
91
94
  recordDoubleClick?.({
92
95
  e,
@@ -110,7 +113,7 @@ const TableBodyRow = ({
110
113
  field: colKey
111
114
  })(e);
112
115
  }
113
- }, fixedLeftColumns.length > 0 ? fixedLeftColumns.map(column => {
116
+ }), fixedLeftColumns.length > 0 ? fixedLeftColumns.map(column => {
114
117
  const cell = row.getVisibleCells().find(c => c.column.id === column.id);
115
118
  if (row.subRows && row.subRows.length === 0 && groupColumns?.includes(cell.column.id)) {
116
119
  return /*#__PURE__*/_react.default.createElement(_TableBodyCellEmpty.default, (0, _extends2.default)({}, rest, {
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
+ var _rowFocus = require("../../grid-component/hooks/rowFocus");
8
9
  var _space = _interopRequireDefault(require("rc-master-ui/es/space"));
9
10
  var _Command = _interopRequireDefault(require("../components/command/Command"));
10
11
  var _utils = require("../hook/utils");
@@ -164,6 +165,7 @@ const TableBodyCell = props => {
164
165
  id,
165
166
  prefix,
166
167
  focusedCell,
168
+ rowFocus,
167
169
  setFocusedCell,
168
170
  // endCell,
169
171
  // startCell,
@@ -442,6 +444,7 @@ const TableBodyCell = props => {
442
444
  colId: cell.column.id,
443
445
  rowId: nextId
444
446
  });
447
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextId).original, 'arrowDown', selectionSettings?.useArrow, rowFocus);
445
448
  const rowQr = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
446
449
  const cellFocus = rowQr?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
447
450
  if (cellFocus) {
@@ -455,6 +458,7 @@ const TableBodyCell = props => {
455
458
  colId: cell.column.id,
456
459
  rowId: nextId
457
460
  });
461
+ (0, _rowFocus.notifyArrowRowFocus)(table.getRow(nextId).original, 'arrowUp', selectionSettings?.useArrow, rowFocus);
458
462
  const rowQr = document.querySelector(`.ui-rc-grid-row[data-row-key="${nextId}"]`);
459
463
  const cellFocus = rowQr?.querySelector('.ui-rc-grid-cell:not(.ui-rc-grid-cell-selection)');
460
464
  if (cellFocus) {