es-grid-template 1.9.61 → 1.9.62

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.
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import './base-table/styles.scss';
3
3
  import type { TableProps } from "../grid-component/type";
4
- declare const InternalTable: <RecordType extends object>(props: TableProps<RecordType>) => JSX.Element;
4
+ import type { BaseRecord } from "./interfaces";
5
+ declare const InternalTable: <RecordType extends BaseRecord>(props: TableProps<RecordType>) => JSX.Element;
5
6
  export default InternalTable;
@@ -68,6 +68,7 @@ const InternalTable = props => {
68
68
  toolbarItems,
69
69
  defaultValue,
70
70
  commandSettings,
71
+ headerData,
71
72
  ...rest
72
73
  } = props;
73
74
  const tableRef = useRef(null);
@@ -314,51 +315,29 @@ const InternalTable = props => {
314
315
  type: changeType,
315
316
  newState,
316
317
  prevState,
317
- option,
318
- field,
319
- indexCol,
320
- indexRow,
321
- key
318
+ field
322
319
  } = args;
323
320
  if (changeType === 'blur') {
324
- const handleChangeCallback = callbackData => {
325
- const callbackRecord = callbackData;
326
- Object.entries(callbackRecord).forEach(([name, value]) => {
327
- setValue(name, value);
328
- });
329
- onSubmit(callbackRecord);
330
- };
331
- if (onHeaderCellChange) {
332
- if (onHeaderCellChange.length > 1) {
333
- onHeaderCellChange({
334
- field,
335
- indexCol,
336
- type: 'onChange',
337
- value: newState,
338
- option,
339
- indexRow,
340
- rowData: record,
341
- rowId: key,
342
- // rowsData: [...dataSource],
343
- rowsData: [...convertData],
344
- sumValue: []
345
- }, handleChangeCallback);
346
- } else {
347
- onHeaderCellChange({
348
- field,
349
- indexCol,
350
- type: 'onChange',
351
- option,
352
- value: newState,
353
- indexRow,
354
- rowData: record,
355
- rowId: key,
356
- rowsData: [...convertData],
357
- sumValue: []
358
- }, handleChangeCallback);
321
+ // const handleChangeCallback = (callbackData: RecordType[]) => {
322
+ // const callbackRecord = callbackData
359
323
 
360
- // onSubmit(record)
361
- }
324
+ // Object.entries(callbackRecord).forEach(
325
+ // ([name, value]: any) => {
326
+ // setValue(name, value)
327
+
328
+ // }
329
+ // )
330
+
331
+ // onSubmit(callbackRecord)
332
+
333
+ // }
334
+
335
+ if (onHeaderCellChange) {
336
+ const newObj = {
337
+ ...headerData,
338
+ [field]: newState
339
+ };
340
+ onHeaderCellChange(newObj);
362
341
  }
363
342
  }
364
343
  if (prevState && newState && prevState !== newState && changeType === 'enter') {
@@ -465,7 +444,8 @@ const InternalTable = props => {
465
444
  onSubmit,
466
445
  triggerPaste,
467
446
  handleCellChange,
468
- handleHeaderCellChange
447
+ handleHeaderCellChange,
448
+ headerData
469
449
  })).use(features.paginationFeature({
470
450
  pagination
471
451
  }));
@@ -6,8 +6,8 @@ import { TableDOMHelper } from './helpers/TableDOMUtils';
6
6
  import type { ResolvedUseVirtual, VerticalRenderRange, VirtualEnum } from './interfaces';
7
7
  import type { LoadingContentWrapperProps } from './loading';
8
8
  import type { BaseTableCSSVariables } from './styles';
9
- import type { CommandClick, ExpandedRowRender, IFormat, IFTheme, RenderExpandIcon, RowClassName } from '../../grid-component/type';
10
- export type PrimaryKey = string | ((row: any) => string);
9
+ import type { AnyObject, CommandClick, ExpandedRowRender, IFormat, IFTheme, RenderExpandIcon, RowClassName } from '../../grid-component/type';
10
+ export type PrimaryKey<RecordType = AnyObject> = keyof RecordType | ((row: RecordType) => keyof RecordType);
11
11
  export type ColumnResizeMode = 'onChange' | 'onEnd';
12
12
  export type ExpandableConfig<RecordType> = {
13
13
  expandedRowKeys?: readonly Key[];
@@ -1,4 +1,5 @@
1
1
  import { Subscription } from 'rxjs';
2
+ import { ColumnTable } from '../../grid-component';
2
3
  /** styled-components 类库的版本,ali-react-table 同时支持 v3 和 v5 */
3
4
  export declare const STYLED_VERSION: string;
4
5
  export declare const STYLED_REF_PROP: string;
@@ -19,3 +20,4 @@ export declare function syncScrollLeft(elements: HTMLElement[], callback: (scrol
19
20
  */
20
21
  export declare function shallowEqual<T>(objA: T, objB: T): boolean;
21
22
  export declare function getParentElement(element: any, selector: any): any;
23
+ export declare function getColumnsAtLevel(columns: ColumnTable[], level: number): ColumnTable[];
@@ -1,7 +1,6 @@
1
1
  import { asyncScheduler, BehaviorSubject, defer, fromEvent, Subscription } from 'rxjs';
2
2
  import { map, throttleTime } from 'rxjs/operators';
3
3
  import * as styledComponents from 'styled-components';
4
-
5
4
  /** styled-components 类库的版本,ali-react-table 同时支持 v3 和 v5 */
6
5
  export const STYLED_VERSION = styledComponents.createGlobalStyle != null ? 'v5' : 'v3';
7
6
  export const STYLED_REF_PROP = STYLED_VERSION === 'v3' ? 'innerRef' : 'ref';
@@ -151,4 +150,16 @@ export function getParentElement(element, selector) {
151
150
  }
152
151
  }
153
152
  return getParent(element, selector);
153
+ }
154
+ export function getColumnsAtLevel(columns, level) {
155
+ if (level === 0) {
156
+ return columns;
157
+ }
158
+ const result = [];
159
+ for (const column of columns) {
160
+ if (column.children?.length) {
161
+ result.push(...getColumnsAtLevel(column.children, level - 1));
162
+ }
163
+ }
164
+ return result;
154
165
  }
@@ -1,7 +1,11 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
2
  import type React from 'react';
3
3
  import type { ColumnTemplate, CommandItem, EditType, FilterOperator, IColumnType, IFormat, ITextAlign, TypeFilter } from '../grid-component/type';
4
+ import type { PrimaryKey } from './base-table/table';
4
5
  export type CellProps = React.TdHTMLAttributes<HTMLTableCellElement>;
6
+ export type BaseRecord = {
7
+ rowId: PrimaryKey;
8
+ };
5
9
  export type FilterState = {
6
10
  field: any;
7
11
  key: any;
@@ -1,9 +1,10 @@
1
1
  /// <reference types="react" />
2
+ import type { PrimaryKey } from './base-table/table';
2
3
  import type { ArtColumn } from './interfaces';
3
4
  declare function safeRenderHeader(column: ArtColumn): import("react").ReactNode;
4
5
  declare function safeRenderHeaderContent(column: ArtColumn, t?: any): any;
5
6
  declare function safeGetValue(column: ArtColumn, record: any, rowIndex: number): any;
6
- declare function safeGetRowKey(primaryKey: string | ((record: any) => string), record: any, rowIndex: number): string;
7
+ declare function safeGetRowKey(primaryKey: PrimaryKey, record: any, rowIndex: number): string;
7
8
  declare function safeGetCellProps(column: ArtColumn, record: any, rowIndex: number): import("./interfaces").CellProps;
8
9
  declare function safeRender(column: ArtColumn, record: any, rowIndex: number): any;
9
10
  export declare const internals: {
@@ -71,6 +71,7 @@ export interface ColumnFeatureOptions {
71
71
  handleCellChange: any;
72
72
  handleHeaderCellChange?: any;
73
73
  dataErrors?: any[];
74
+ headerData?: any;
74
75
  }
75
76
  export declare function columnCustom(opts: ColumnFeatureOptions): (pipeline: TablePipeline) => TablePipeline;
76
77
  export {};
@@ -16,6 +16,7 @@ import HeaderEditCell from "../../base-table/cell/HeaderEditCell";
16
16
  import { stateKeyResize, stateKeyColumnFilter, stateKeyFilter, stateKeyPagination, stateKeySorter, stateKeyTooltip, stateKeyTypePaste, stateKeyVisible,
17
17
  // state For edit
18
18
  stateKeyEndCell, stateKeyEndPasteCell, stateKeyStartCell, stateKeyStartPasteCell, stateKeyFocusedCell, stateKeyIsEditing, stateKeyIsPasting, stateKeyIsSelecting } from "../../utils/constants";
19
+ import { getColumnsAtLevel } from "../../base-table/utils";
19
20
  // import { getMaxDepth } from '../../utils/utility';
20
21
 
21
22
  function clamp(min, x, max) {
@@ -59,7 +60,8 @@ export function columnCustom(opts) {
59
60
  onSubmit,
60
61
  handleCellChange,
61
62
  handleHeaderCellChange,
62
- dataErrors
63
+ dataErrors,
64
+ headerData
63
65
  // originData
64
66
 
65
67
  // currentPage = 1,
@@ -87,8 +89,7 @@ export function columnCustom(opts) {
87
89
  const allRows = pipeline.getDataSource(); // flat data
88
90
 
89
91
  const leafColumns = collectNodes(pipeline.getColumns(), 'leaf-only');
90
- // const originCols = pipeline.getColumns()
91
-
92
+ const originCols = pipeline.getColumns();
92
93
  const rowIds = getKeys(allRows, 'rowId');
93
94
  const colIds = getKeys(leafColumns, 'field');
94
95
  const rowIndexMap = getRowIndexMap(allRows);
@@ -292,7 +293,7 @@ export function columnCustom(opts) {
292
293
 
293
294
  // Chức năng edit
294
295
 
295
- const handleEdit = (e, record, col, editType, isKeyDown) => {
296
+ const handleEdit = (e, record, col, editType, isKeyDown, isHeader) => {
296
297
  pipeline.setStateAtKey(stateKeyIsEditing, true);
297
298
  reset?.();
298
299
  if (!isObjEmpty(record)) {
@@ -314,6 +315,15 @@ export function columnCustom(opts) {
314
315
  }
315
316
  }, 10);
316
317
  }
318
+ if (focusedCell?.rowId && isHeader) {
319
+ setTimeout(() => {
320
+ const textarea = document.querySelector(`.ui-rc-grid-table-header-row .header-cell-editable[data-col-key="${focusedCell.colId}"] textarea`);
321
+ if (textarea) {
322
+ textarea.focus();
323
+ textarea.setSelectionRange(textarea.value.length, textarea.value.length);
324
+ }
325
+ }, 10);
326
+ }
317
327
  };
318
328
  const triggerDragPaste = (pasteState, ctrlKey) => {
319
329
  const tmpCols = [...leafColumns];
@@ -769,7 +779,7 @@ export function columnCustom(opts) {
769
779
  if (e.key === 'Enter') {
770
780
  e.preventDefault();
771
781
  e.stopPropagation();
772
- handleEdit(e, record, column, editType);
782
+ handleEdit(e, record, column, editType, false);
773
783
  return;
774
784
  }
775
785
  if (e.key.length === 1 && !e.ctrlKey) {
@@ -778,6 +788,168 @@ export function columnCustom(opts) {
778
788
  handleEdit(e, record, column, editType, true);
779
789
  }
780
790
  };
791
+ const handleHeaderKeyDown = (e, rowId, colId, rowIndex, column, record, editType) => {
792
+ if (e.key === 'Tab') {
793
+ const currentHeaderRowCols = getColumnsAtLevel(originCols, rowIndex);
794
+ const currentHeaderRowColsEditAble = currentHeaderRowCols ? currentHeaderRowCols.filter(it => it.headerEditEnable) : undefined;
795
+ const nextCol = currentHeaderRowColsEditAble ? getNextColumn(currentHeaderRowColsEditAble, focusedCell.colId) : undefined;
796
+ const nextHeaderRowCols = getColumnsAtLevel(originCols, rowIndex + 1);
797
+ const nextHeaderRowColsEditAble = nextHeaderRowCols ? nextHeaderRowCols.filter(it => it.headerEditEnable) : undefined;
798
+ const nextRow = nextHeaderRowColsEditAble ? nextHeaderRowColsEditAble : undefined;
799
+ const checkEnd = nextCol && currentHeaderRowColsEditAble ? getNextColumn1(currentHeaderRowColsEditAble, nextCol.column.field) : undefined;
800
+ if (!checkEnd) {
801
+ e.preventDefault();
802
+ e.stopPropagation();
803
+ }
804
+ if (nextCol?.column && !nextCol.isWrapped) {
805
+ const nextCellPosition = {
806
+ rowId,
807
+ colId: nextCol.column.field
808
+ };
809
+ pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition);
810
+ pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition);
811
+ pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition);
812
+ } else {
813
+ // Nếu là cột cuối cùng, có thể nhảy xuống dòng tiếp theo
814
+
815
+ // const currentRowIndex = allRows.findIndex(r => r.rowId === rowId);
816
+ // const nextRow = allRows[currentRowIndex + 1];
817
+
818
+ const firstCol = nextRow?.[0];
819
+ if (nextRow && firstCol) {
820
+ const nextRowId = `header-field-${rowIndex + 1}`;
821
+ const nextCellPosition = {
822
+ rowId: nextRowId,
823
+ colId: firstCol.field
824
+ };
825
+ pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition);
826
+ pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition);
827
+ pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition);
828
+ if (tableRef) {
829
+ // tableRef?.current?.artTableWrapperRef?.current?.scrollLeft = 0
830
+
831
+ // const wrapper = tableRef.current?.artTableWrapperRef?.current;
832
+ const wrapper = tableRef.current?.domHelper?.stickyScroll;
833
+ if (!wrapper) return;
834
+ wrapper.scrollLeft = 0;
835
+ }
836
+ } else {
837
+ e.preventDefault();
838
+ e.stopPropagation();
839
+ }
840
+ }
841
+ return;
842
+ }
843
+
844
+ // if (e.key === 'ArrowRight') {
845
+
846
+ // // e.preventDefault();
847
+ // // e.stopPropagation()
848
+
849
+ // const nextCol = getNextColumn(leafColumns, column.field)
850
+
851
+ // if (nextCol.column && !nextCol.isWrapped) {
852
+
853
+ // const nextCellPosition = { rowId, colId: nextCol.column.field }
854
+
855
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
856
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
857
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
858
+
859
+ // }
860
+
861
+ // return
862
+ // }
863
+
864
+ // if (e.key === 'ArrowLeft') {
865
+
866
+ // // e.preventDefault()
867
+ // // e.stopPropagation()
868
+
869
+ // const prevCol = getPrevColumn(leafColumns, column.field)
870
+
871
+ // if (prevCol) {
872
+
873
+ // const nextCellPosition = { rowId, colId: prevCol.field }
874
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
875
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
876
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
877
+
878
+ // }
879
+ // return
880
+ // }
881
+
882
+ // if (e.key === 'ArrowDown') {
883
+
884
+ // // e.preventDefault()
885
+ // // e.stopPropagation()
886
+
887
+ // const nextRow = allRows[rowIndex + 1]
888
+
889
+ // if (nextRow) {
890
+ // const nextRowId = nextRow.rowId
891
+
892
+ // const nextCellPosition = { rowId: nextRowId, colId }
893
+ // // setFocusedCell?.({ rowId: nextRowId, colId });
894
+ // // setStartCell?.({ rowId: nextRowId, colId });
895
+ // // setEndCell?.({ rowId: nextRowId, colId });
896
+
897
+ // // setRangeState?.(getSelectedCellMatrix(table, { rowId: nextRowId, colId }, { rowId: nextRowId, colId }))
898
+
899
+ // // columnVirtualizer.scrollToIndex(nextCol.getIndex(), { align: 'center' })
900
+ // // rowVirtualizer.scrollToIndex(nextRow.index, { align: 'center' })
901
+
902
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
903
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
904
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
905
+
906
+ // // const rowElement: any = document.querySelector(`.ui-rc-grid-table-row[data-row-key="${nextRowId}"]`)
907
+
908
+ // // const cellFocus = rowElement?.querySelector('.ui-rc-grid-cell')
909
+
910
+ // }
911
+
912
+ // return
913
+ // }
914
+
915
+ // if (e.key === 'ArrowUp') {
916
+
917
+ // // e.preventDefault()
918
+ // // e.stopPropagation()
919
+
920
+ // const nextRow = allRows[rowIndex - 1]
921
+
922
+ // if (nextRow) {
923
+ // const nextRowId = nextRow.rowId
924
+
925
+ // const nextCellPosition = { rowId: nextRowId, colId }
926
+
927
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
928
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
929
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
930
+
931
+ // }
932
+
933
+ // return
934
+ // }
935
+
936
+ // if (e.key === 'Delete') {
937
+ // handleDeleteContent?.()
938
+ // return
939
+ // }
940
+
941
+ if (e.key === 'Enter') {
942
+ e.preventDefault();
943
+ e.stopPropagation();
944
+ handleEdit(e, record, column, editType, false, true);
945
+ return;
946
+ }
947
+ if (e.key.length === 1 && !e.ctrlKey) {
948
+ e.preventDefault();
949
+ e.stopPropagation();
950
+ handleEdit(e, record, column, editType, true, true);
951
+ }
952
+ };
781
953
  const handleChange = (record, column, indexCol) => {
782
954
  const currentRowIndex = allRows.findIndex(r => r.rowId === record.rowId);
783
955
  const formState = getValues();
@@ -798,6 +970,26 @@ export function columnCustom(opts) {
798
970
  });
799
971
  } else {}
800
972
  };
973
+ const handleHeaderChange = (record, column, indexCol) => {
974
+ const currentRowIndex = allRows.findIndex(r => r.rowId === record.rowId);
975
+ const formState = getValues();
976
+ const itemState = getValues(column.field);
977
+ const prevState = record[column.field];
978
+ const newState = itemState;
979
+ if (newState !== prevState) {
980
+ handleHeaderCellChange?.({
981
+ key: record.rowId,
982
+ field: column.field,
983
+ record: formState,
984
+ prevState,
985
+ newState,
986
+ option: newState,
987
+ indexCol: indexCol,
988
+ indexRow: currentRowIndex,
989
+ type: 'blur'
990
+ });
991
+ } else {}
992
+ };
801
993
  const handlePointDoubleClick = (e, column, record) => {
802
994
  e.preventDefault();
803
995
  e.stopPropagation();
@@ -1042,15 +1234,19 @@ export function columnCustom(opts) {
1042
1234
  const htmlTooltip = headerCustomTooltip;
1043
1235
  const headerEditType = col.headerEditType;
1044
1236
  const headerRowIndex = params.path.findIndex(it => it.field === col.field);
1045
- const tmpValue = allRows.length > 0 ? allRows[0][col.field] : undefined;
1237
+ const headerRowId = `header-field-${headerRowIndex}`;
1238
+
1239
+ // const headerRecord: any = { ...col, rowId: `field-${headerRowIndex}`, [col.field]: tmpValue, children: undefined }
1240
+
1046
1241
  const headerRecord = {
1047
- ...col,
1048
- rowId: `field-${headerRowIndex}`,
1049
- [col.field]: tmpValue,
1050
- children: undefined
1242
+ [col.field]: headerData?.[col.field] ?? ''
1051
1243
  };
1052
- const cellHeaderEditing = isEditing && headerRecord.rowId === focusedCell.rowId && col.field === focusedCell.colId;
1053
- const isCellSelect = startCell?.rowId === headerRecord.rowId && startCell?.colId === col.field;
1244
+ const headerValue = headerData?.[col.field] ?? '';
1245
+ const cellHeaderEditing = isEditing && headerRowId === focusedCell.rowId && col.field === focusedCell.colId;
1246
+ const isCellSelect = headerRowId === focusedCell.rowId && startCell?.colId === col.field;
1247
+ const aa = getColumnsAtLevel(originCols, headerRowIndex);
1248
+ const aaEditAble = aa ? aa.filter(it => it.headerEditEnable) : undefined;
1249
+ const nextHeaderCol = aaEditAble ? getNextColumn(aaEditAble, focusedCell.colId) : undefined;
1054
1250
 
1055
1251
  // Cell thường có thể filter và sort được
1056
1252
  return {
@@ -1097,7 +1293,7 @@ export function columnCustom(opts) {
1097
1293
  startCell: startCell,
1098
1294
  handleSubmit: handleSubmit,
1099
1295
  onSubmit: onSubmit
1100
- })) : col.headerEditEnable ? /*#__PURE__*/React.createElement(React.Fragment, null, tmpValue) : col.headerTemplate ? /*#__PURE__*/React.createElement(React.Fragment, null, typeof col.headerTemplate === 'function' ? col.headerTemplate(col) : col.headerTemplate) : /*#__PURE__*/React.createElement(React.Fragment, null, prevTitle))), !col.headerEditEnable && (!nonActionColumn.includes(col.field) && !col?.children || col?.children && col?.children.length < 1) && /*#__PURE__*/React.createElement("span", {
1296
+ })) : col.headerEditEnable ? /*#__PURE__*/React.createElement(React.Fragment, null, headerValue) : col.headerTemplate ? /*#__PURE__*/React.createElement(React.Fragment, null, typeof col.headerTemplate === 'function' ? col.headerTemplate(col) : col.headerTemplate) : /*#__PURE__*/React.createElement(React.Fragment, null, prevTitle))), !col.headerEditEnable && (!nonActionColumn.includes(col.field) && !col?.children || col?.children && col?.children.length < 1) && /*#__PURE__*/React.createElement("span", {
1101
1297
  className: "ui-rc-header-trigger d-flex gap-50"
1102
1298
  }, canSort && /*#__PURE__*/React.createElement("div", {
1103
1299
  style: {
@@ -1148,9 +1344,20 @@ export function columnCustom(opts) {
1148
1344
  headerCellProps: mergeCellProps(col.headerCellProps ?? {}, {
1149
1345
  'data-tooltip-id': `${id}-tooltip-content`,
1150
1346
  'data-tooltip-content': htmlTooltip,
1347
+ // @ts-ignore
1348
+ 'data-col-key': col.field,
1349
+ ref: el => {
1350
+ if (focusedCell?.rowId === headerRowId && focusedCell?.colId === col.field && !isEditing) {
1351
+ el?.focus({
1352
+ preventScroll: true
1353
+ });
1354
+ }
1355
+ },
1356
+ tabIndex: focusedCell?.rowId === headerRowId && focusedCell?.colId === col.field ? 1 : col.field === nextHeaderCol?.column?.field ? 1 : -1,
1151
1357
  style: {
1152
1358
  overflow: 'visible',
1153
1359
  position: 'relative',
1360
+ outline: 'none',
1154
1361
  padding: cellHeaderEditing ? 0 : undefined
1155
1362
  },
1156
1363
  className: classNames('', {
@@ -1163,7 +1370,7 @@ export function columnCustom(opts) {
1163
1370
  }),
1164
1371
  onMouseDown: () => {
1165
1372
  if (col.headerEditEnable) {
1166
- handleMouseDown(headerRecord.rowId, col.field);
1373
+ handleMouseDown(headerRowId, col.field);
1167
1374
  }
1168
1375
  },
1169
1376
  onDoubleClick: e => {
@@ -1174,8 +1381,81 @@ export function columnCustom(opts) {
1174
1381
  e.preventDefault();
1175
1382
  return;
1176
1383
  }
1177
- if (headerRecord.rowId === focusedCell.rowId && col.field === focusedCell.colId && col.headerEditEnable) {
1178
- handleEdit(e, headerRecord, col, headerEditType ?? 'text');
1384
+ if (headerRowId === focusedCell.rowId && col.field === focusedCell.colId && col.headerEditEnable) {
1385
+ handleEdit(e, headerRecord, col, headerEditType ?? 'text', false, true);
1386
+ }
1387
+ },
1388
+ onKeyDown: e => {
1389
+ // prevCellProps?.onKeyDown?.(e)
1390
+ // chưa editing
1391
+ if (!isEditing) {
1392
+ handleHeaderKeyDown(e, headerRowId, col.field, headerRowIndex, col, headerRecord, headerEditType ?? 'text');
1393
+ } else {
1394
+ if (e.shiftKey && e.key === 'Enter') {
1395
+ e.preventDefault();
1396
+ e.stopPropagation();
1397
+ } else {
1398
+ if (e.key === 'Enter') {
1399
+ e.preventDefault();
1400
+ e.stopPropagation();
1401
+
1402
+ // const currentRowIndex = allRows.findIndex(r => r.rowId === headerRowId);
1403
+ // const nextRow = allRows[currentRowIndex + 1];
1404
+
1405
+ // if (nextRow) {
1406
+ // const nextCellPosition = { rowId: nextRow.rowId, colId: col.field }
1407
+
1408
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
1409
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
1410
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
1411
+
1412
+ handleHeaderChange(headerRecord, col, startIndex);
1413
+ pipeline.setStateAtKey(stateKeyIsEditing, false);
1414
+
1415
+ // }
1416
+ }
1417
+ if (e.key === 'Tab') {
1418
+ e.preventDefault();
1419
+
1420
+ // const nextCol = getNextColumn(allCols, col.field)
1421
+
1422
+ if (nextHeaderCol?.column?.field && !nextHeaderCol?.isWrapped) {
1423
+ const nextCellPosition = {
1424
+ rowId: headerRowId,
1425
+ colId: nextHeaderCol.column.field
1426
+ };
1427
+ pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition);
1428
+ pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition);
1429
+ pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition);
1430
+
1431
+ // columnVirtualizer.scrollToIndex(nextCol.getIndex(), { align: 'center' })
1432
+ } else {
1433
+ // Nếu là cột cuối cùng, có thể nhảy xuống dòng tiếp theo
1434
+
1435
+ // const currentRowIndex = allRows.findIndex(r => r.rowId === headerRowId);
1436
+ // const nextRow = allRows[currentRowIndex + 1];
1437
+
1438
+ // const firstCol = nextCol.column
1439
+
1440
+ // if (nextRow) {
1441
+
1442
+ // const nextCellPosition = { rowId: nextRow.rowId, colId: firstCol.field }
1443
+
1444
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
1445
+
1446
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
1447
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
1448
+
1449
+ // // columnVirtualizer.scrollToIndex(nextRowCol.getIndex())
1450
+
1451
+ // // rowVirtualizer.scrollToIndex(nextRow.index, { align: 'auto' })
1452
+
1453
+ // }
1454
+ }
1455
+ handleHeaderChange(headerRecord, col, startIndex);
1456
+ pipeline.setStateAtKey(stateKeyIsEditing, false);
1457
+ }
1458
+ }
1179
1459
  }
1180
1460
  }
1181
1461
  }),
@@ -1330,7 +1610,7 @@ export function columnCustom(opts) {
1330
1610
  return;
1331
1611
  }
1332
1612
  if (record.rowId === focusedCell.rowId && col.field === focusedCell.colId && canEdit) {
1333
- handleEdit(e, record, col, editType ?? 'text');
1613
+ handleEdit(e, record, col, editType ?? 'text', false);
1334
1614
  }
1335
1615
  },
1336
1616
  onKeyDown: e => {
@@ -478,6 +478,7 @@ export type TableProps<RecordType = AnyObject> = {
478
478
  showEmptyText?: boolean;
479
479
  /** Cấu hình command column */
480
480
  commandSettings?: CommandSettings;
481
+ headerData?: object;
481
482
  /**
482
483
  * Func khi click command
483
484
  * Ví dụ: Edit, Delete, Copy...
@@ -525,7 +526,7 @@ export type TableProps<RecordType = AnyObject> = {
525
526
  * handleCallback dùng để cập nhật giá trị sau khi xử lý custom
526
527
  */
527
528
  onCellChange?: (args: CellChangeArgs<RecordType>, handleCallback: (rowData: any, index: any, value?: any) => void) => void;
528
- onHeaderCellChange?: (args: CellChangeArgs<RecordType>, handleCallback: (rowData: any, index: any, value?: any) => void) => void;
529
+ onHeaderCellChange?: (data: object) => void;
529
530
  /** Callback click cell */
530
531
  onCellClick?: (args: ICellClick, callback?: any) => void;
531
532
  /** Xác định row có được edit hay không */
@@ -196,10 +196,10 @@ export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordTyp
196
196
  value: any;
197
197
  rowData: RecordType;
198
198
  }) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | import("react").ReactNode);
199
- onCellStyles?: Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position">);
200
- onCellHeaderStyles?: Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position">);
199
+ onCellStyles?: Omit<CSSProperties, "width" | "minWidth" | "left" | "right" | "position" | "display"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "width" | "minWidth" | "left" | "right" | "position" | "display">);
200
+ onCellHeaderStyles?: Omit<CSSProperties, "width" | "minWidth" | "left" | "right" | "position" | "display"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "width" | "minWidth" | "left" | "right" | "position" | "display">);
201
201
  onCell?: (rowData: RecordType, index: number) => import("react").TdHTMLAttributes<HTMLTableCellElement>;
202
- onCellFooterStyles?: Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "width" | "left" | "right" | "display" | "minWidth" | "position">);
202
+ onCellFooterStyles?: Omit<CSSProperties, "width" | "minWidth" | "left" | "right" | "position" | "display"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "width" | "minWidth" | "left" | "right" | "position" | "display">);
203
203
  getValue?: (row: any, rowIndex: number) => any;
204
204
  getCellProps?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").CellProps;
205
205
  headerCellProps?: import("./../../grid-component/type").CellProps;
@@ -25,7 +25,7 @@ export function AsyncSelect({
25
25
  }
26
26
  };
27
27
  return debounce(fetchOptions, debounceTimeout);
28
- }, [loadOptions, debounceTimeout]);
28
+ }, [debounceTimeout, loadOptions, defaultOptions, rowData]);
29
29
  useEffect(() => {
30
30
  setOptions(defaultOptions ?? []);
31
31
  }, [defaultOptions]);
@@ -199,7 +199,5 @@ export declare const getIds: <T extends {
199
199
  }>(data: T[]) => string[];
200
200
  export declare const getKeys: <T extends Record<string, any>, K extends keyof T>(data: T[], key: K) => T[K][];
201
201
  export declare const getRowIndexMap: (flatRows: any[]) => Map<string, number>;
202
- export declare function getRowIdsBetween3(flatRows: {
203
- rowId: string;
204
- }[], rowIndexMap: Map<string, number>, a: string, b: string): string[];
202
+ export declare function getRowIdsBetween3(flatRows: any[], rowIndexMap: Map<string, number>, a: string, b: string): string[];
205
203
  export {};
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import './base-table/styles.scss';
3
3
  import type { TableProps } from "../grid-component/type";
4
- declare const InternalTable: <RecordType extends object>(props: TableProps<RecordType>) => JSX.Element;
4
+ import type { BaseRecord } from "./interfaces";
5
+ declare const InternalTable: <RecordType extends BaseRecord>(props: TableProps<RecordType>) => JSX.Element;
5
6
  export default InternalTable;
@@ -73,6 +73,7 @@ const InternalTable = props => {
73
73
  toolbarItems,
74
74
  defaultValue,
75
75
  commandSettings,
76
+ headerData,
76
77
  ...rest
77
78
  } = props;
78
79
  const tableRef = (0, _react.useRef)(null);
@@ -319,51 +320,29 @@ const InternalTable = props => {
319
320
  type: changeType,
320
321
  newState,
321
322
  prevState,
322
- option,
323
- field,
324
- indexCol,
325
- indexRow,
326
- key
323
+ field
327
324
  } = args;
328
325
  if (changeType === 'blur') {
329
- const handleChangeCallback = callbackData => {
330
- const callbackRecord = callbackData;
331
- Object.entries(callbackRecord).forEach(([name, value]) => {
332
- setValue(name, value);
333
- });
334
- onSubmit(callbackRecord);
335
- };
336
- if (onHeaderCellChange) {
337
- if (onHeaderCellChange.length > 1) {
338
- onHeaderCellChange({
339
- field,
340
- indexCol,
341
- type: 'onChange',
342
- value: newState,
343
- option,
344
- indexRow,
345
- rowData: record,
346
- rowId: key,
347
- // rowsData: [...dataSource],
348
- rowsData: [...convertData],
349
- sumValue: []
350
- }, handleChangeCallback);
351
- } else {
352
- onHeaderCellChange({
353
- field,
354
- indexCol,
355
- type: 'onChange',
356
- option,
357
- value: newState,
358
- indexRow,
359
- rowData: record,
360
- rowId: key,
361
- rowsData: [...convertData],
362
- sumValue: []
363
- }, handleChangeCallback);
326
+ // const handleChangeCallback = (callbackData: RecordType[]) => {
327
+ // const callbackRecord = callbackData
364
328
 
365
- // onSubmit(record)
366
- }
329
+ // Object.entries(callbackRecord).forEach(
330
+ // ([name, value]: any) => {
331
+ // setValue(name, value)
332
+
333
+ // }
334
+ // )
335
+
336
+ // onSubmit(callbackRecord)
337
+
338
+ // }
339
+
340
+ if (onHeaderCellChange) {
341
+ const newObj = {
342
+ ...headerData,
343
+ [field]: newState
344
+ };
345
+ onHeaderCellChange(newObj);
367
346
  }
368
347
  }
369
348
  if (prevState && newState && prevState !== newState && changeType === 'enter') {
@@ -470,7 +449,8 @@ const InternalTable = props => {
470
449
  onSubmit,
471
450
  triggerPaste,
472
451
  handleCellChange,
473
- handleHeaderCellChange
452
+ handleHeaderCellChange,
453
+ headerData
474
454
  })).use(_pipeline.features.paginationFeature({
475
455
  pagination
476
456
  }));
@@ -6,8 +6,8 @@ import { TableDOMHelper } from './helpers/TableDOMUtils';
6
6
  import type { ResolvedUseVirtual, VerticalRenderRange, VirtualEnum } from './interfaces';
7
7
  import type { LoadingContentWrapperProps } from './loading';
8
8
  import type { BaseTableCSSVariables } from './styles';
9
- import type { CommandClick, ExpandedRowRender, IFormat, IFTheme, RenderExpandIcon, RowClassName } from '../../grid-component/type';
10
- export type PrimaryKey = string | ((row: any) => string);
9
+ import type { AnyObject, CommandClick, ExpandedRowRender, IFormat, IFTheme, RenderExpandIcon, RowClassName } from '../../grid-component/type';
10
+ export type PrimaryKey<RecordType = AnyObject> = keyof RecordType | ((row: RecordType) => keyof RecordType);
11
11
  export type ColumnResizeMode = 'onChange' | 'onEnd';
12
12
  export type ExpandableConfig<RecordType> = {
13
13
  expandedRowKeys?: readonly Key[];
@@ -1,4 +1,5 @@
1
1
  import { Subscription } from 'rxjs';
2
+ import { ColumnTable } from '../../grid-component';
2
3
  /** styled-components 类库的版本,ali-react-table 同时支持 v3 和 v5 */
3
4
  export declare const STYLED_VERSION: string;
4
5
  export declare const STYLED_REF_PROP: string;
@@ -19,3 +20,4 @@ export declare function syncScrollLeft(elements: HTMLElement[], callback: (scrol
19
20
  */
20
21
  export declare function shallowEqual<T>(objA: T, objB: T): boolean;
21
22
  export declare function getParentElement(element: any, selector: any): any;
23
+ export declare function getColumnsAtLevel(columns: ColumnTable[], level: number): ColumnTable[];
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.STYLED_VERSION = exports.STYLED_REF_PROP = exports.OVERSCAN_SIZE = exports.AUTO_VIRTUAL_THRESHOLD = void 0;
7
+ exports.getColumnsAtLevel = getColumnsAtLevel;
7
8
  exports.getParentElement = getParentElement;
8
9
  exports.getScrollbarSize = getScrollbarSize;
9
10
  exports.shallowEqual = shallowEqual;
@@ -164,4 +165,16 @@ function getParentElement(element, selector) {
164
165
  }
165
166
  }
166
167
  return getParent(element, selector);
168
+ }
169
+ function getColumnsAtLevel(columns, level) {
170
+ if (level === 0) {
171
+ return columns;
172
+ }
173
+ const result = [];
174
+ for (const column of columns) {
175
+ if (column.children?.length) {
176
+ result.push(...getColumnsAtLevel(column.children, level - 1));
177
+ }
178
+ }
179
+ return result;
167
180
  }
@@ -1,7 +1,11 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
2
  import type React from 'react';
3
3
  import type { ColumnTemplate, CommandItem, EditType, FilterOperator, IColumnType, IFormat, ITextAlign, TypeFilter } from '../grid-component/type';
4
+ import type { PrimaryKey } from './base-table/table';
4
5
  export type CellProps = React.TdHTMLAttributes<HTMLTableCellElement>;
6
+ export type BaseRecord = {
7
+ rowId: PrimaryKey;
8
+ };
5
9
  export type FilterState = {
6
10
  field: any;
7
11
  key: any;
@@ -1,9 +1,10 @@
1
1
  /// <reference types="react" />
2
+ import type { PrimaryKey } from './base-table/table';
2
3
  import type { ArtColumn } from './interfaces';
3
4
  declare function safeRenderHeader(column: ArtColumn): import("react").ReactNode;
4
5
  declare function safeRenderHeaderContent(column: ArtColumn, t?: any): any;
5
6
  declare function safeGetValue(column: ArtColumn, record: any, rowIndex: number): any;
6
- declare function safeGetRowKey(primaryKey: string | ((record: any) => string), record: any, rowIndex: number): string;
7
+ declare function safeGetRowKey(primaryKey: PrimaryKey, record: any, rowIndex: number): string;
7
8
  declare function safeGetCellProps(column: ArtColumn, record: any, rowIndex: number): import("./interfaces").CellProps;
8
9
  declare function safeRender(column: ArtColumn, record: any, rowIndex: number): any;
9
10
  export declare const internals: {
@@ -71,6 +71,7 @@ export interface ColumnFeatureOptions {
71
71
  handleCellChange: any;
72
72
  handleHeaderCellChange?: any;
73
73
  dataErrors?: any[];
74
+ headerData?: any;
74
75
  }
75
76
  export declare function columnCustom(opts: ColumnFeatureOptions): (pipeline: TablePipeline) => TablePipeline;
76
77
  export {};
@@ -19,6 +19,7 @@ var _useColumns = require("../../../table-component/hook/useColumns");
19
19
  var _EditCell = _interopRequireDefault(require("../../base-table/cell/EditCell"));
20
20
  var _HeaderEditCell = _interopRequireDefault(require("../../base-table/cell/HeaderEditCell"));
21
21
  var _constants = require("../../utils/constants");
22
+ var _utils3 = require("../../base-table/utils");
22
23
  // import { getMaxDepth } from '../../utils/utility';
23
24
 
24
25
  function clamp(min, x, max) {
@@ -62,7 +63,8 @@ function columnCustom(opts) {
62
63
  onSubmit,
63
64
  handleCellChange,
64
65
  handleHeaderCellChange,
65
- dataErrors
66
+ dataErrors,
67
+ headerData
66
68
  // originData
67
69
 
68
70
  // currentPage = 1,
@@ -90,8 +92,7 @@ function columnCustom(opts) {
90
92
  const allRows = pipeline.getDataSource(); // flat data
91
93
 
92
94
  const leafColumns = (0, _utils.collectNodes)(pipeline.getColumns(), 'leaf-only');
93
- // const originCols = pipeline.getColumns()
94
-
95
+ const originCols = pipeline.getColumns();
95
96
  const rowIds = (0, _utils2.getKeys)(allRows, 'rowId');
96
97
  const colIds = (0, _utils2.getKeys)(leafColumns, 'field');
97
98
  const rowIndexMap = (0, _utils2.getRowIndexMap)(allRows);
@@ -295,7 +296,7 @@ function columnCustom(opts) {
295
296
 
296
297
  // Chức năng edit
297
298
 
298
- const handleEdit = (e, record, col, editType, isKeyDown) => {
299
+ const handleEdit = (e, record, col, editType, isKeyDown, isHeader) => {
299
300
  pipeline.setStateAtKey(_constants.stateKeyIsEditing, true);
300
301
  reset?.();
301
302
  if (!(0, _hooks.isObjEmpty)(record)) {
@@ -317,6 +318,15 @@ function columnCustom(opts) {
317
318
  }
318
319
  }, 10);
319
320
  }
321
+ if (focusedCell?.rowId && isHeader) {
322
+ setTimeout(() => {
323
+ const textarea = document.querySelector(`.ui-rc-grid-table-header-row .header-cell-editable[data-col-key="${focusedCell.colId}"] textarea`);
324
+ if (textarea) {
325
+ textarea.focus();
326
+ textarea.setSelectionRange(textarea.value.length, textarea.value.length);
327
+ }
328
+ }, 10);
329
+ }
320
330
  };
321
331
  const triggerDragPaste = (pasteState, ctrlKey) => {
322
332
  const tmpCols = [...leafColumns];
@@ -772,7 +782,7 @@ function columnCustom(opts) {
772
782
  if (e.key === 'Enter') {
773
783
  e.preventDefault();
774
784
  e.stopPropagation();
775
- handleEdit(e, record, column, editType);
785
+ handleEdit(e, record, column, editType, false);
776
786
  return;
777
787
  }
778
788
  if (e.key.length === 1 && !e.ctrlKey) {
@@ -781,6 +791,168 @@ function columnCustom(opts) {
781
791
  handleEdit(e, record, column, editType, true);
782
792
  }
783
793
  };
794
+ const handleHeaderKeyDown = (e, rowId, colId, rowIndex, column, record, editType) => {
795
+ if (e.key === 'Tab') {
796
+ const currentHeaderRowCols = (0, _utils3.getColumnsAtLevel)(originCols, rowIndex);
797
+ const currentHeaderRowColsEditAble = currentHeaderRowCols ? currentHeaderRowCols.filter(it => it.headerEditEnable) : undefined;
798
+ const nextCol = currentHeaderRowColsEditAble ? (0, _utils2.getNextColumn)(currentHeaderRowColsEditAble, focusedCell.colId) : undefined;
799
+ const nextHeaderRowCols = (0, _utils3.getColumnsAtLevel)(originCols, rowIndex + 1);
800
+ const nextHeaderRowColsEditAble = nextHeaderRowCols ? nextHeaderRowCols.filter(it => it.headerEditEnable) : undefined;
801
+ const nextRow = nextHeaderRowColsEditAble ? nextHeaderRowColsEditAble : undefined;
802
+ const checkEnd = nextCol && currentHeaderRowColsEditAble ? (0, _utils2.getNextColumn1)(currentHeaderRowColsEditAble, nextCol.column.field) : undefined;
803
+ if (!checkEnd) {
804
+ e.preventDefault();
805
+ e.stopPropagation();
806
+ }
807
+ if (nextCol?.column && !nextCol.isWrapped) {
808
+ const nextCellPosition = {
809
+ rowId,
810
+ colId: nextCol.column.field
811
+ };
812
+ pipeline.setStateAtKey(_constants.stateKeyFocusedCell, nextCellPosition);
813
+ pipeline.setStateAtKey(_constants.stateKeyStartCell, nextCellPosition);
814
+ pipeline.setStateAtKey(_constants.stateKeyEndCell, nextCellPosition);
815
+ } else {
816
+ // Nếu là cột cuối cùng, có thể nhảy xuống dòng tiếp theo
817
+
818
+ // const currentRowIndex = allRows.findIndex(r => r.rowId === rowId);
819
+ // const nextRow = allRows[currentRowIndex + 1];
820
+
821
+ const firstCol = nextRow?.[0];
822
+ if (nextRow && firstCol) {
823
+ const nextRowId = `header-field-${rowIndex + 1}`;
824
+ const nextCellPosition = {
825
+ rowId: nextRowId,
826
+ colId: firstCol.field
827
+ };
828
+ pipeline.setStateAtKey(_constants.stateKeyFocusedCell, nextCellPosition);
829
+ pipeline.setStateAtKey(_constants.stateKeyStartCell, nextCellPosition);
830
+ pipeline.setStateAtKey(_constants.stateKeyEndCell, nextCellPosition);
831
+ if (tableRef) {
832
+ // tableRef?.current?.artTableWrapperRef?.current?.scrollLeft = 0
833
+
834
+ // const wrapper = tableRef.current?.artTableWrapperRef?.current;
835
+ const wrapper = tableRef.current?.domHelper?.stickyScroll;
836
+ if (!wrapper) return;
837
+ wrapper.scrollLeft = 0;
838
+ }
839
+ } else {
840
+ e.preventDefault();
841
+ e.stopPropagation();
842
+ }
843
+ }
844
+ return;
845
+ }
846
+
847
+ // if (e.key === 'ArrowRight') {
848
+
849
+ // // e.preventDefault();
850
+ // // e.stopPropagation()
851
+
852
+ // const nextCol = getNextColumn(leafColumns, column.field)
853
+
854
+ // if (nextCol.column && !nextCol.isWrapped) {
855
+
856
+ // const nextCellPosition = { rowId, colId: nextCol.column.field }
857
+
858
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
859
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
860
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
861
+
862
+ // }
863
+
864
+ // return
865
+ // }
866
+
867
+ // if (e.key === 'ArrowLeft') {
868
+
869
+ // // e.preventDefault()
870
+ // // e.stopPropagation()
871
+
872
+ // const prevCol = getPrevColumn(leafColumns, column.field)
873
+
874
+ // if (prevCol) {
875
+
876
+ // const nextCellPosition = { rowId, colId: prevCol.field }
877
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
878
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
879
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
880
+
881
+ // }
882
+ // return
883
+ // }
884
+
885
+ // if (e.key === 'ArrowDown') {
886
+
887
+ // // e.preventDefault()
888
+ // // e.stopPropagation()
889
+
890
+ // const nextRow = allRows[rowIndex + 1]
891
+
892
+ // if (nextRow) {
893
+ // const nextRowId = nextRow.rowId
894
+
895
+ // const nextCellPosition = { rowId: nextRowId, colId }
896
+ // // setFocusedCell?.({ rowId: nextRowId, colId });
897
+ // // setStartCell?.({ rowId: nextRowId, colId });
898
+ // // setEndCell?.({ rowId: nextRowId, colId });
899
+
900
+ // // setRangeState?.(getSelectedCellMatrix(table, { rowId: nextRowId, colId }, { rowId: nextRowId, colId }))
901
+
902
+ // // columnVirtualizer.scrollToIndex(nextCol.getIndex(), { align: 'center' })
903
+ // // rowVirtualizer.scrollToIndex(nextRow.index, { align: 'center' })
904
+
905
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
906
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
907
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
908
+
909
+ // // const rowElement: any = document.querySelector(`.ui-rc-grid-table-row[data-row-key="${nextRowId}"]`)
910
+
911
+ // // const cellFocus = rowElement?.querySelector('.ui-rc-grid-cell')
912
+
913
+ // }
914
+
915
+ // return
916
+ // }
917
+
918
+ // if (e.key === 'ArrowUp') {
919
+
920
+ // // e.preventDefault()
921
+ // // e.stopPropagation()
922
+
923
+ // const nextRow = allRows[rowIndex - 1]
924
+
925
+ // if (nextRow) {
926
+ // const nextRowId = nextRow.rowId
927
+
928
+ // const nextCellPosition = { rowId: nextRowId, colId }
929
+
930
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
931
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
932
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
933
+
934
+ // }
935
+
936
+ // return
937
+ // }
938
+
939
+ // if (e.key === 'Delete') {
940
+ // handleDeleteContent?.()
941
+ // return
942
+ // }
943
+
944
+ if (e.key === 'Enter') {
945
+ e.preventDefault();
946
+ e.stopPropagation();
947
+ handleEdit(e, record, column, editType, false, true);
948
+ return;
949
+ }
950
+ if (e.key.length === 1 && !e.ctrlKey) {
951
+ e.preventDefault();
952
+ e.stopPropagation();
953
+ handleEdit(e, record, column, editType, true, true);
954
+ }
955
+ };
784
956
  const handleChange = (record, column, indexCol) => {
785
957
  const currentRowIndex = allRows.findIndex(r => r.rowId === record.rowId);
786
958
  const formState = getValues();
@@ -801,6 +973,26 @@ function columnCustom(opts) {
801
973
  });
802
974
  } else {}
803
975
  };
976
+ const handleHeaderChange = (record, column, indexCol) => {
977
+ const currentRowIndex = allRows.findIndex(r => r.rowId === record.rowId);
978
+ const formState = getValues();
979
+ const itemState = getValues(column.field);
980
+ const prevState = record[column.field];
981
+ const newState = itemState;
982
+ if (newState !== prevState) {
983
+ handleHeaderCellChange?.({
984
+ key: record.rowId,
985
+ field: column.field,
986
+ record: formState,
987
+ prevState,
988
+ newState,
989
+ option: newState,
990
+ indexCol: indexCol,
991
+ indexRow: currentRowIndex,
992
+ type: 'blur'
993
+ });
994
+ } else {}
995
+ };
804
996
  const handlePointDoubleClick = (e, column, record) => {
805
997
  e.preventDefault();
806
998
  e.stopPropagation();
@@ -1045,15 +1237,19 @@ function columnCustom(opts) {
1045
1237
  const htmlTooltip = headerCustomTooltip;
1046
1238
  const headerEditType = col.headerEditType;
1047
1239
  const headerRowIndex = params.path.findIndex(it => it.field === col.field);
1048
- const tmpValue = allRows.length > 0 ? allRows[0][col.field] : undefined;
1240
+ const headerRowId = `header-field-${headerRowIndex}`;
1241
+
1242
+ // const headerRecord: any = { ...col, rowId: `field-${headerRowIndex}`, [col.field]: tmpValue, children: undefined }
1243
+
1049
1244
  const headerRecord = {
1050
- ...col,
1051
- rowId: `field-${headerRowIndex}`,
1052
- [col.field]: tmpValue,
1053
- children: undefined
1245
+ [col.field]: headerData?.[col.field] ?? ''
1054
1246
  };
1055
- const cellHeaderEditing = isEditing && headerRecord.rowId === focusedCell.rowId && col.field === focusedCell.colId;
1056
- const isCellSelect = startCell?.rowId === headerRecord.rowId && startCell?.colId === col.field;
1247
+ const headerValue = headerData?.[col.field] ?? '';
1248
+ const cellHeaderEditing = isEditing && headerRowId === focusedCell.rowId && col.field === focusedCell.colId;
1249
+ const isCellSelect = headerRowId === focusedCell.rowId && startCell?.colId === col.field;
1250
+ const aa = (0, _utils3.getColumnsAtLevel)(originCols, headerRowIndex);
1251
+ const aaEditAble = aa ? aa.filter(it => it.headerEditEnable) : undefined;
1252
+ const nextHeaderCol = aaEditAble ? (0, _utils2.getNextColumn)(aaEditAble, focusedCell.colId) : undefined;
1057
1253
 
1058
1254
  // Cell thường có thể filter và sort được
1059
1255
  return {
@@ -1100,7 +1296,7 @@ function columnCustom(opts) {
1100
1296
  startCell: startCell,
1101
1297
  handleSubmit: handleSubmit,
1102
1298
  onSubmit: onSubmit
1103
- })) : col.headerEditEnable ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, tmpValue) : col.headerTemplate ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, typeof col.headerTemplate === 'function' ? col.headerTemplate(col) : col.headerTemplate) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, prevTitle))), !col.headerEditEnable && (!_hooks.nonActionColumn.includes(col.field) && !col?.children || col?.children && col?.children.length < 1) && /*#__PURE__*/_react.default.createElement("span", {
1299
+ })) : col.headerEditEnable ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, headerValue) : col.headerTemplate ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, typeof col.headerTemplate === 'function' ? col.headerTemplate(col) : col.headerTemplate) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, prevTitle))), !col.headerEditEnable && (!_hooks.nonActionColumn.includes(col.field) && !col?.children || col?.children && col?.children.length < 1) && /*#__PURE__*/_react.default.createElement("span", {
1104
1300
  className: "ui-rc-header-trigger d-flex gap-50"
1105
1301
  }, canSort && /*#__PURE__*/_react.default.createElement("div", {
1106
1302
  style: {
@@ -1151,9 +1347,20 @@ function columnCustom(opts) {
1151
1347
  headerCellProps: (0, _utils.mergeCellProps)(col.headerCellProps ?? {}, {
1152
1348
  'data-tooltip-id': `${id}-tooltip-content`,
1153
1349
  'data-tooltip-content': htmlTooltip,
1350
+ // @ts-ignore
1351
+ 'data-col-key': col.field,
1352
+ ref: el => {
1353
+ if (focusedCell?.rowId === headerRowId && focusedCell?.colId === col.field && !isEditing) {
1354
+ el?.focus({
1355
+ preventScroll: true
1356
+ });
1357
+ }
1358
+ },
1359
+ tabIndex: focusedCell?.rowId === headerRowId && focusedCell?.colId === col.field ? 1 : col.field === nextHeaderCol?.column?.field ? 1 : -1,
1154
1360
  style: {
1155
1361
  overflow: 'visible',
1156
1362
  position: 'relative',
1363
+ outline: 'none',
1157
1364
  padding: cellHeaderEditing ? 0 : undefined
1158
1365
  },
1159
1366
  className: (0, _classnames.default)('', {
@@ -1166,7 +1373,7 @@ function columnCustom(opts) {
1166
1373
  }),
1167
1374
  onMouseDown: () => {
1168
1375
  if (col.headerEditEnable) {
1169
- handleMouseDown(headerRecord.rowId, col.field);
1376
+ handleMouseDown(headerRowId, col.field);
1170
1377
  }
1171
1378
  },
1172
1379
  onDoubleClick: e => {
@@ -1177,8 +1384,81 @@ function columnCustom(opts) {
1177
1384
  e.preventDefault();
1178
1385
  return;
1179
1386
  }
1180
- if (headerRecord.rowId === focusedCell.rowId && col.field === focusedCell.colId && col.headerEditEnable) {
1181
- handleEdit(e, headerRecord, col, headerEditType ?? 'text');
1387
+ if (headerRowId === focusedCell.rowId && col.field === focusedCell.colId && col.headerEditEnable) {
1388
+ handleEdit(e, headerRecord, col, headerEditType ?? 'text', false, true);
1389
+ }
1390
+ },
1391
+ onKeyDown: e => {
1392
+ // prevCellProps?.onKeyDown?.(e)
1393
+ // chưa editing
1394
+ if (!isEditing) {
1395
+ handleHeaderKeyDown(e, headerRowId, col.field, headerRowIndex, col, headerRecord, headerEditType ?? 'text');
1396
+ } else {
1397
+ if (e.shiftKey && e.key === 'Enter') {
1398
+ e.preventDefault();
1399
+ e.stopPropagation();
1400
+ } else {
1401
+ if (e.key === 'Enter') {
1402
+ e.preventDefault();
1403
+ e.stopPropagation();
1404
+
1405
+ // const currentRowIndex = allRows.findIndex(r => r.rowId === headerRowId);
1406
+ // const nextRow = allRows[currentRowIndex + 1];
1407
+
1408
+ // if (nextRow) {
1409
+ // const nextCellPosition = { rowId: nextRow.rowId, colId: col.field }
1410
+
1411
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
1412
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
1413
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
1414
+
1415
+ handleHeaderChange(headerRecord, col, startIndex);
1416
+ pipeline.setStateAtKey(_constants.stateKeyIsEditing, false);
1417
+
1418
+ // }
1419
+ }
1420
+ if (e.key === 'Tab') {
1421
+ e.preventDefault();
1422
+
1423
+ // const nextCol = getNextColumn(allCols, col.field)
1424
+
1425
+ if (nextHeaderCol?.column?.field && !nextHeaderCol?.isWrapped) {
1426
+ const nextCellPosition = {
1427
+ rowId: headerRowId,
1428
+ colId: nextHeaderCol.column.field
1429
+ };
1430
+ pipeline.setStateAtKey(_constants.stateKeyFocusedCell, nextCellPosition);
1431
+ pipeline.setStateAtKey(_constants.stateKeyStartCell, nextCellPosition);
1432
+ pipeline.setStateAtKey(_constants.stateKeyEndCell, nextCellPosition);
1433
+
1434
+ // columnVirtualizer.scrollToIndex(nextCol.getIndex(), { align: 'center' })
1435
+ } else {
1436
+ // Nếu là cột cuối cùng, có thể nhảy xuống dòng tiếp theo
1437
+
1438
+ // const currentRowIndex = allRows.findIndex(r => r.rowId === headerRowId);
1439
+ // const nextRow = allRows[currentRowIndex + 1];
1440
+
1441
+ // const firstCol = nextCol.column
1442
+
1443
+ // if (nextRow) {
1444
+
1445
+ // const nextCellPosition = { rowId: nextRow.rowId, colId: firstCol.field }
1446
+
1447
+ // pipeline.setStateAtKey(stateKeyFocusedCell, nextCellPosition)
1448
+
1449
+ // pipeline.setStateAtKey(stateKeyStartCell, nextCellPosition)
1450
+ // pipeline.setStateAtKey(stateKeyEndCell, nextCellPosition)
1451
+
1452
+ // // columnVirtualizer.scrollToIndex(nextRowCol.getIndex())
1453
+
1454
+ // // rowVirtualizer.scrollToIndex(nextRow.index, { align: 'auto' })
1455
+
1456
+ // }
1457
+ }
1458
+ handleHeaderChange(headerRecord, col, startIndex);
1459
+ pipeline.setStateAtKey(_constants.stateKeyIsEditing, false);
1460
+ }
1461
+ }
1182
1462
  }
1183
1463
  }
1184
1464
  }),
@@ -1333,7 +1613,7 @@ function columnCustom(opts) {
1333
1613
  return;
1334
1614
  }
1335
1615
  if (record.rowId === focusedCell.rowId && col.field === focusedCell.colId && canEdit) {
1336
- handleEdit(e, record, col, editType ?? 'text');
1616
+ handleEdit(e, record, col, editType ?? 'text', false);
1337
1617
  }
1338
1618
  },
1339
1619
  onKeyDown: e => {
@@ -478,6 +478,7 @@ export type TableProps<RecordType = AnyObject> = {
478
478
  showEmptyText?: boolean;
479
479
  /** Cấu hình command column */
480
480
  commandSettings?: CommandSettings;
481
+ headerData?: object;
481
482
  /**
482
483
  * Func khi click command
483
484
  * Ví dụ: Edit, Delete, Copy...
@@ -525,7 +526,7 @@ export type TableProps<RecordType = AnyObject> = {
525
526
  * handleCallback dùng để cập nhật giá trị sau khi xử lý custom
526
527
  */
527
528
  onCellChange?: (args: CellChangeArgs<RecordType>, handleCallback: (rowData: any, index: any, value?: any) => void) => void;
528
- onHeaderCellChange?: (args: CellChangeArgs<RecordType>, handleCallback: (rowData: any, index: any, value?: any) => void) => void;
529
+ onHeaderCellChange?: (data: object) => void;
529
530
  /** Callback click cell */
530
531
  onCellClick?: (args: ICellClick, callback?: any) => void;
531
532
  /** Xác định row có được edit hay không */
@@ -34,7 +34,7 @@ function AsyncSelect({
34
34
  }
35
35
  };
36
36
  return (0, _debounce.default)(fetchOptions, debounceTimeout);
37
- }, [loadOptions, debounceTimeout]);
37
+ }, [debounceTimeout, loadOptions, defaultOptions, rowData]);
38
38
  (0, _react.useEffect)(() => {
39
39
  setOptions(defaultOptions ?? []);
40
40
  }, [defaultOptions]);
@@ -199,7 +199,5 @@ export declare const getIds: <T extends {
199
199
  }>(data: T[]) => string[];
200
200
  export declare const getKeys: <T extends Record<string, any>, K extends keyof T>(data: T[], key: K) => T[K][];
201
201
  export declare const getRowIndexMap: (flatRows: any[]) => Map<string, number>;
202
- export declare function getRowIdsBetween3(flatRows: {
203
- rowId: string;
204
- }[], rowIndexMap: Map<string, number>, a: string, b: string): string[];
202
+ export declare function getRowIdsBetween3(flatRows: any[], rowIndexMap: Map<string, number>, a: string, b: string): string[];
205
203
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-grid-template",
3
- "version": "1.9.61",
3
+ "version": "1.9.62",
4
4
  "description": "es-grid-template",
5
5
  "keywords": [
6
6
  "react",