arthub-table 0.2.0-beta.8 → 0.2.1

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 (31) hide show
  1. package/dist/arthub-table.common.js +1 -1
  2. package/dist/arthub-table.common.js.map +1 -1
  3. package/dist/arthub-table.umd.js +1 -1
  4. package/dist/arthub-table.umd.js.map +1 -1
  5. package/dist/arthub-table.umd.min.js +1 -1
  6. package/dist/arthub-table.umd.min.js.map +1 -1
  7. package/dist/types/adapters/DataGridIntegration.d.ts +51 -0
  8. package/dist/types/adapters/columnAdapter.d.ts +7 -0
  9. package/dist/types/adapters/rowDataAdapter.d.ts +23 -0
  10. package/dist/types/core/ColumnHeader.d.ts +26 -0
  11. package/dist/types/core/DataGrid.d.ts +362 -4
  12. package/dist/types/core/Events.d.ts +0 -1
  13. package/dist/types/core/GroupRow.d.ts +46 -0
  14. package/dist/types/core/ImageManager.d.ts +21 -0
  15. package/dist/types/core/NestedGrid.d.ts +56 -1
  16. package/dist/types/core/StyleManager.d.ts +2 -0
  17. package/dist/types/core/constants.d.ts +1 -0
  18. package/dist/types/core/types.d.ts +14 -0
  19. package/dist/types/core/viewers/FileViewer.d.ts +3 -3
  20. package/dist/types/core/viewers/ImageViewer.d.ts +3 -3
  21. package/dist/types/core/viewers/ModuleViewer.d.ts +10 -9
  22. package/dist/types/core/viewers/PivotViewer.d.ts +42 -1
  23. package/dist/types/core/viewers/RelatedTaskViewer.d.ts +76 -0
  24. package/dist/types/core/viewers/TextViewerWithSwitcher.d.ts +22 -2
  25. package/dist/types/core/viewers/index.d.ts +3 -0
  26. package/dist/types/core/viewers/types.d.ts +115 -0
  27. package/dist/types/index.d.ts +1 -1
  28. package/dist/types/testing/TestHooks.d.ts +187 -24
  29. package/dist/types/testing/index.d.ts +1 -1
  30. package/dist/types/testing/installTestHooks.d.ts +4 -4
  31. package/package.json +5 -1
@@ -50,6 +50,7 @@ interface AutofillState {
50
50
  }
51
51
  interface RowDragState {
52
52
  isDragging: boolean;
53
+ dragStartX: number;
53
54
  dragStartY: number;
54
55
  draggedRowIndices: number[];
55
56
  dropIndicatorType: 'line' | 'overlay' | null;
@@ -104,6 +105,17 @@ interface ColumnContextMenuInfo {
104
105
  parentKey?: string;
105
106
  clientX: number;
106
107
  clientY: number;
108
+ /**
109
+ * 表头单元格在屏幕坐标系下的矩形(left/top/width/height)。
110
+ * 供外部把 popover(如右键菜单→筛选)锚点对齐到"该列表头下方左对齐"。
111
+ * 对 nested-child 列,矩形为子表头本身;对 fixed 左右冻结列,已按可视屏幕坐标换算。
112
+ */
113
+ headerBounds: {
114
+ left: number;
115
+ top: number;
116
+ width: number;
117
+ height: number;
118
+ };
107
119
  /** 当前选中的列 colId 集合(用于区分「表头右键菜单」和「选中列右键菜单」) */
108
120
  selectedColIds: string[];
109
121
  /** 当前选中的列原始 key 集合(colKey),方便业务层直接匹配 */
@@ -268,6 +280,25 @@ export interface DataGridOptions {
268
280
  /** NestedGrid 实际渲染的数据数组(行索引与 autofillRange 完全一致) */
269
281
  nestedGridData: any[];
270
282
  }) => void;
283
+ /** 嵌套子表内子行拖动排序回调(Alt + 拖拽触发,不跨外层行) */
284
+ onNestedRowDragReorder?: (params: {
285
+ parentRowData: any;
286
+ parentColKey: string;
287
+ parentRowIndex: number;
288
+ parentColIndex: number;
289
+ /** 被拖拽的子行索引(相对 nestedGridData) */
290
+ fromRowIndex: number;
291
+ /** 目标插入位置索引(相对 nestedGridData) */
292
+ toRowIndex: number;
293
+ /** 插入位置:front 插到目标行之前,tail 插到目标行之后 */
294
+ position: 'front' | 'tail';
295
+ /** 被拖拽子行数据 */
296
+ fromRowData: any;
297
+ /** 目标参考子行数据 */
298
+ toRowData: any;
299
+ /** NestedGrid 实际渲染的数据数组 */
300
+ nestedGridData: any[];
301
+ }) => void;
271
302
  /** 嵌套子表框选变化回调:选区跨子表或单子表变化时触发 */
272
303
  onNestedSelectionChange?: (params: {
273
304
  parentColKey: string;
@@ -362,6 +393,13 @@ export interface DataGridOptions {
362
393
  * Default: false (preserves existing behavior for backward compatibility).
363
394
  */
364
395
  disableClickOutside?: boolean;
396
+ /**
397
+ * 是否隐藏表头业务图标(TAPD / IOMC / fieldHint / link)。
398
+ * 对齐 DOM 表格的 hideIcon 能力:用户在 "显示表头图标" 开关关闭时,
399
+ * 表头区域的四种业务图标均不再绘制,但图标右侧的排序/筛选/设置图标不受影响。
400
+ * 默认 false(显示图标)。
401
+ */
402
+ hideHeaderIcons?: boolean;
365
403
  onTreeExpand?: (rowData: RowData, expanded: boolean) => void;
366
404
  onCellTextClick?: (rowData: RowData, colId: string) => void;
367
405
  onCellTotalNumClick?: (rowData: RowData, colId: string) => void;
@@ -390,6 +428,9 @@ export interface DataGridOptions {
390
428
  colId: string;
391
429
  colIndex: number;
392
430
  colTitle: string;
431
+ colKey: string;
432
+ colType?: string;
433
+ parentKey?: string;
393
434
  clientX: number;
394
435
  clientY: number;
395
436
  }) => void;
@@ -398,8 +439,17 @@ export interface DataGridOptions {
398
439
  colId: string;
399
440
  colIndex: number;
400
441
  colTitle: string;
442
+ colKey: string;
443
+ colType?: string;
444
+ parentKey?: string;
401
445
  clientX: number;
402
446
  clientY: number;
447
+ headerBounds: {
448
+ left: number;
449
+ top: number;
450
+ width: number;
451
+ height: number;
452
+ };
403
453
  }) => void;
404
454
  /** 嵌套列设置图标点击回调 */
405
455
  onNestedSettingsClick?: (info: {
@@ -500,7 +550,13 @@ export interface DataGridOptions {
500
550
  height: number;
501
551
  };
502
552
  }) => void;
503
- /** 折叠所有任务回调 */
553
+ /** 嵌套表格展开/收起回调:展开全部或收起按钮点击时触发,用于通知业务层更新数据 */
554
+ onNestedExpandToggle?: (info: {
555
+ parentRowData: any;
556
+ parentColKey: string;
557
+ parentRowIndex: number;
558
+ expanded: boolean;
559
+ }) => void;
504
560
  onCollapseAll?: () => void;
505
561
  /** 展开所有任务回调 */
506
562
  onExpandAll?: () => void;
@@ -606,6 +662,20 @@ export interface DataGridOptions {
606
662
  height: number;
607
663
  };
608
664
  }) => void;
665
+ /** 表头 fieldHint info icon hover 回调:鼠标悬停/离开字段提示图标时触发 */
666
+ onHeaderFieldHintIconHover?: (info: {
667
+ show: boolean;
668
+ colKey: string;
669
+ colIndex: number;
670
+ colTitle: string;
671
+ fieldHint: string;
672
+ position: {
673
+ x: number;
674
+ y: number;
675
+ width: number;
676
+ height: number;
677
+ };
678
+ }) => void;
609
679
  /** 表体 Link icon 点击回调:点击引用字段单元格的 link icon 时触发 */
610
680
  onLinkIconClick?: (info: {
611
681
  rowData: Record<string, any>;
@@ -774,6 +844,7 @@ declare class DataGrid {
774
844
  onNestedAutofillStart?: DataGridOptions['onNestedAutofillStart'];
775
845
  onNestedAutofillDragging?: DataGridOptions['onNestedAutofillDragging'];
776
846
  onNestedAutofillEnd?: DataGridOptions['onNestedAutofillEnd'];
847
+ onNestedRowDragReorder?: DataGridOptions['onNestedRowDragReorder'];
777
848
  onNestedSelectionChange?: DataGridOptions['onNestedSelectionChange'];
778
849
  onNestedSubHeadClick?: DataGridOptions['onNestedSubHeadClick'];
779
850
  onNestedCrossAutofillEnd?: DataGridOptions['onNestedCrossAutofillEnd'];
@@ -795,6 +866,8 @@ declare class DataGrid {
795
866
  enableKeyboardShortcuts: boolean;
796
867
  /** Whether to disable built-in "click outside to close editing" behavior */
797
868
  disableClickOutside: boolean;
869
+ /** 是否隐藏表头业务图标(TAPD / IOMC / fieldHint / link),对齐 DOM 表格 hideIcon */
870
+ hideHeaderIcons: boolean;
798
871
  /** 非受控模式下的完整数据(包含所有分组的子行) */
799
872
  private _fullData;
800
873
  /** 双缓冲:离屏 canvas(避免每帧创建,懒初始化 + 复用) */
@@ -946,6 +1019,7 @@ declare class DataGrid {
946
1019
  private isDirty;
947
1020
  private lastScrollX;
948
1021
  private lastScrollY;
1022
+ private _afterRenderListeners;
949
1023
  private _renderErrorCount;
950
1024
  private _renderPaused;
951
1025
  private static readonly MAX_CONSECUTIVE_RENDER_ERRORS;
@@ -966,12 +1040,17 @@ declare class DataGrid {
966
1040
  private headerTextColorMap;
967
1041
  private sortOrderMap;
968
1042
  private sortOrderCount;
1043
+ private moduleSortOrderMap;
1044
+ private moduleSortCountMap;
969
1045
  private _searchMatchColors;
970
1046
  hoveredHeaderColId: string | null;
971
1047
  onHeaderSortClick?: (info: {
972
1048
  colId: string;
973
1049
  colIndex: number;
974
1050
  colTitle: string;
1051
+ colKey: string;
1052
+ colType?: string;
1053
+ parentKey?: string;
975
1054
  clientX: number;
976
1055
  clientY: number;
977
1056
  }) => void;
@@ -979,8 +1058,17 @@ declare class DataGrid {
979
1058
  colId: string;
980
1059
  colIndex: number;
981
1060
  colTitle: string;
1061
+ colKey: string;
1062
+ colType?: string;
1063
+ parentKey?: string;
982
1064
  clientX: number;
983
1065
  clientY: number;
1066
+ headerBounds: {
1067
+ left: number;
1068
+ top: number;
1069
+ width: number;
1070
+ height: number;
1071
+ };
984
1072
  }) => void;
985
1073
  onNestedSettingsClick?: (info: {
986
1074
  colId: string;
@@ -1071,6 +1159,19 @@ declare class DataGrid {
1071
1159
  height: number;
1072
1160
  };
1073
1161
  }) => void;
1162
+ onHeaderFieldHintIconHover?: (info: {
1163
+ show: boolean;
1164
+ colKey: string;
1165
+ colIndex: number;
1166
+ colTitle: string;
1167
+ fieldHint: string;
1168
+ position: {
1169
+ x: number;
1170
+ y: number;
1171
+ width: number;
1172
+ height: number;
1173
+ };
1174
+ }) => void;
1074
1175
  onLinkIconClick?: (info: {
1075
1176
  rowData: Record<string, any>;
1076
1177
  colKey: string;
@@ -1136,6 +1237,10 @@ declare class DataGrid {
1136
1237
  * 获取容器可视区域宽、高,设置canvas容器样式尺寸、画布尺寸
1137
1238
  */
1138
1239
  setLayoutSize(options?: DataGridOptions): void;
1240
+ /**
1241
+ * 获取未被 autoFill 改写的表格原始宽度。
1242
+ */
1243
+ getTableOriginalWidth(): number;
1139
1244
  /**
1140
1245
  * 获取表格左、右冻结列宽,表格实际的宽、高
1141
1246
  */
@@ -1180,6 +1285,8 @@ declare class DataGrid {
1180
1285
  selectCell({ colIndex, rowIndex }: {
1181
1286
  colIndex: number;
1182
1287
  rowIndex: number;
1288
+ }, options?: {
1289
+ skipBoundaryAdjust?: boolean;
1183
1290
  }): void;
1184
1291
  resetCellPosition(): void;
1185
1292
  /**
@@ -1311,12 +1418,52 @@ declare class DataGrid {
1311
1418
  * Called when data changes, interaction state changes, etc.
1312
1419
  */
1313
1420
  markDirty(): void;
1421
+ /**
1422
+ * 注册一次性的"下一帧渲染完成后"回调。
1423
+ * 触发时机:initPaint 的 finally 块(draw 完成或抛异常后)。
1424
+ * 回调执行后队列会被清空;每次调用仅添加一个监听器,监听器执行一次后自动移除。
1425
+ * fail-safe:回调内部抛错只会被捕获并 console.error,不影响后续渲染循环。
1426
+ */
1427
+ onceAfterRender(cb: () => void): void;
1428
+ /**
1429
+ * 计算指定列头在屏幕坐标系下的矩形区域,用于外部将 popover / 弹窗锚点
1430
+ * 对齐到"该列表头单元格下方左对齐"。
1431
+ *
1432
+ * 返回值格式为 DOMRect-like 的 { left, top, width, height },其中:
1433
+ * - left / top:该列表头左上角相对于视口(viewport)的坐标;
1434
+ * - width / height:该列表头的宽高(对 nested-child 即为子表头本身的尺寸)。
1435
+ *
1436
+ * 兼容 3 种 fixed 场景(left / right / 非冻结)以及水平滚动 scrollX。
1437
+ * 对嵌套子列(colType === 'nested-child'),col.y 已是子表头行的 y,
1438
+ * 因此无需额外处理,直接用 col.y 即可得到子表头自身的矩形。
1439
+ */
1440
+ computeHeaderScreenBounds(col: any): {
1441
+ left: number;
1442
+ top: number;
1443
+ width: number;
1444
+ height: number;
1445
+ };
1314
1446
  /**
1315
1447
  * Resume the render loop after it was paused due to consecutive render errors.
1316
1448
  * Also resets the error counter. Call this after the root cause has been fixed
1317
1449
  * (e.g. after loadData with corrected data).
1318
1450
  */
1319
1451
  resumeRenderLoop(): void;
1452
+ /**
1453
+ * 清除 Body 层的所有内部缓存(不影响接口数据缓存)。
1454
+ *
1455
+ * 典型场景:displayTaskNum 变化时,需要彻底清除 canvas 表格实例的缓存,
1456
+ * 确保后续 loadData 时不会从旧的 body.data 迁移任何状态(如 _nestedExpanded),
1457
+ * 同时所有 Row/Cell 对象会被重新创建。
1458
+ *
1459
+ * 清除范围:
1460
+ * - body.data(设为空数组,阻止 Body.paint() 迁移旧状态)
1461
+ * - body.rowCache / rowAccessTime(Row 对象缓存池和 LRU 访问时间)
1462
+ * - body.visibleRowIndexes / rows(可见行索引和 Row 对象数组)
1463
+ * - body._nestedDirtyRows / _nestedRenderedRows(嵌套表格渲染追踪)
1464
+ * - body.rowHeights / rowOffsets(行高和偏移量数组)
1465
+ */
1466
+ clearBodyCache(): void;
1320
1467
  drawContainer(): void;
1321
1468
  draw(): void;
1322
1469
  /**
@@ -1626,7 +1773,8 @@ declare class DataGrid {
1626
1773
  /**
1627
1774
  * 将指定单元格滚动到可见区域内(通过 rowId 和 colIndex)
1628
1775
  * @param rowId - 行的唯一标识
1629
- * @param colIndex - 列索引
1776
+ * @param colIndex - 列索引;传入负数(如 -1)表示仅做垂直滚动、保持水平滚动位置
1777
+ * (适用于分组组头等不关联具体列的行定位场景)
1630
1778
  */
1631
1779
  scrollCellIntoViewById(rowId: string | number, colIndex: number): void;
1632
1780
  /**
@@ -1721,6 +1869,13 @@ declare class DataGrid {
1721
1869
  * @returns 高亮色字符串,未设置时返回空字符串
1722
1870
  */
1723
1871
  getColumnHighlightColor(columnKey: string): string;
1872
+ /**
1873
+ * 设置是否隐藏表头业务图标(TAPD / IOMC / fieldHint / link)。
1874
+ * 对齐 DOM 表格的 "显示表头图标" 开关:关闭时四种图标均不绘制,
1875
+ * 但排序/筛选/设置图标不受影响,同时图标 hover 热区(fieldHintIconBounds /
1876
+ * linkIconBounds)也会在下次 draw 时被置空,避免隐藏后仍触发 hover。
1877
+ */
1878
+ setHideHeaderIcons(hide: boolean): void;
1724
1879
  /**
1725
1880
  * 批量设置表头文字颜色(用于新加入字段紫色高亮等场景)
1726
1881
  * @param colors 表头文字颜色映射对象:{ columnKey: color },color 为空字符串表示清除
@@ -1742,7 +1897,18 @@ declare class DataGrid {
1742
1897
  type: 'asc' | 'desc';
1743
1898
  }>): void;
1744
1899
  /**
1745
- * 获取指定列的排序状态
1900
+ * 批量设置模块排序状态(各模块独立管理排序,与全局排序互不干扰)
1901
+ * @param moduleOrders 模块排序数组:[{ moduleId: string, orders: [{ meta, type }] }]
1902
+ */
1903
+ setModuleSortOrders(moduleOrders: Array<{
1904
+ moduleId: string;
1905
+ orders: Array<{
1906
+ meta: string;
1907
+ type: 'asc' | 'desc';
1908
+ }>;
1909
+ }>): void;
1910
+ /**
1911
+ * 获取全局排序状态
1746
1912
  * @param convertMeta 列的 convertMeta 标识
1747
1913
  * @returns 排序状态对象,未排序时返回 null
1748
1914
  */
@@ -1751,9 +1917,23 @@ declare class DataGrid {
1751
1917
  index: number;
1752
1918
  } | null;
1753
1919
  /**
1754
- * 获取当前排序列总数
1920
+ * 获取模块排序状态(嵌套子列使用)
1921
+ * @param moduleId 模块 ID(即父列的 key)
1922
+ * @param convertMeta 列的 convertMeta 标识
1923
+ * @returns 排序状态对象,未排序时返回 null
1924
+ */
1925
+ getModuleSortOrder(moduleId: string, convertMeta: string): {
1926
+ type: 'asc' | 'desc';
1927
+ index: number;
1928
+ } | null;
1929
+ /**
1930
+ * 获取全局排序列总数
1755
1931
  */
1756
1932
  getSortOrderCount(): number;
1933
+ /**
1934
+ * 获取指定模块的排序列总数
1935
+ */
1936
+ getModuleSortOrderCount(moduleId: string): number;
1757
1937
  /**
1758
1938
  * 设置搜索匹配颜色
1759
1939
  */
@@ -1832,6 +2012,23 @@ declare class DataGrid {
1832
2012
  * @returns Row data object (deep copy) or null if not found
1833
2013
  */
1834
2014
  testGetRowData(rowId: string | number): Record<string, any> | null;
2015
+ /**
2016
+ * 获取组头行搜索命中高亮状态(用于 E2E / 单元测试验证)。
2017
+ *
2018
+ * @param rowId - 组头行 id(分组模式下通常是 string,如 "group-project-0")
2019
+ * @returns { matched, currentHighlight } 或 null(行不存在 / 非组头行)
2020
+ */
2021
+ testGetGroupHeaderSearchMatchState(rowId: string | number): {
2022
+ matched: boolean;
2023
+ currentHighlight: boolean;
2024
+ } | null;
2025
+ /**
2026
+ * 获取组头行搜索命中的"首列左边框" x 坐标(用于 E2E / 单元测试验证多层分组的绘制位置)。
2027
+ *
2028
+ * @param rowId - 组头行 id
2029
+ * @returns x 坐标(canvas 相对坐标)或 null(行不存在 / 非组头行 / 未命中 GroupRow 实例)
2030
+ */
2031
+ testGetSearchHighlightFirstLeftBorderX(rowId: string | number): number | null;
1835
2032
  /**
1836
2033
  * Get current scroll position and scrollbar state.
1837
2034
  * @returns ScrollPosition object
@@ -2026,5 +2223,166 @@ declare class DataGrid {
2026
2223
  * 算法:遍历 _fullData,使用分组栈跟踪折叠状态
2027
2224
  */
2028
2225
  filterVisibleRows(fullData: RowData[]): RowData[];
2226
+ /**
2227
+ * Get interactive areas within a column header.
2228
+ * Returns sort/filter icon, resize handle, and settings icon bounds.
2229
+ */
2230
+ testGetHeaderInteractiveAreas(colIndex: number): {
2231
+ header: {
2232
+ canvasX: number;
2233
+ canvasY: number;
2234
+ width: number;
2235
+ height: number;
2236
+ };
2237
+ sortIcon: {
2238
+ canvasX: number;
2239
+ canvasY: number;
2240
+ width: number;
2241
+ height: number;
2242
+ } | null;
2243
+ filterIcon: {
2244
+ canvasX: number;
2245
+ canvasY: number;
2246
+ width: number;
2247
+ height: number;
2248
+ } | null;
2249
+ resizeHandle: {
2250
+ canvasX: number;
2251
+ canvasY: number;
2252
+ width: number;
2253
+ height: number;
2254
+ };
2255
+ settingsIcon: {
2256
+ canvasX: number;
2257
+ canvasY: number;
2258
+ width: number;
2259
+ height: number;
2260
+ } | null;
2261
+ meta: {
2262
+ colId: string;
2263
+ columnKey: string;
2264
+ colType: string;
2265
+ index: number;
2266
+ sortDisabled: boolean;
2267
+ canDrag: boolean;
2268
+ isNested: boolean;
2269
+ };
2270
+ } | null;
2271
+ /**
2272
+ * Get all interactive (clickable) areas within a specific cell.
2273
+ * Returns canvas-relative coordinates for edit icon, link icon, error icon, etc.
2274
+ */
2275
+ testGetCellInteractiveAreas(rowId: string | number, columnKey: string): {
2276
+ cell: {
2277
+ canvasX: number;
2278
+ canvasY: number;
2279
+ width: number;
2280
+ height: number;
2281
+ };
2282
+ editIcon: {
2283
+ canvasX: number;
2284
+ canvasY: number;
2285
+ width: number;
2286
+ height: number;
2287
+ } | null;
2288
+ linkIcon: {
2289
+ canvasX: number;
2290
+ canvasY: number;
2291
+ width: number;
2292
+ height: number;
2293
+ } | null;
2294
+ errorIcon: {
2295
+ canvasX: number;
2296
+ canvasY: number;
2297
+ width: number;
2298
+ height: number;
2299
+ } | null;
2300
+ reminderTriangle: {
2301
+ canvasX: number;
2302
+ canvasY: number;
2303
+ width: number;
2304
+ height: number;
2305
+ } | null;
2306
+ viewerAreas: Array<{
2307
+ type: string;
2308
+ bounds: {
2309
+ canvasX: number;
2310
+ canvasY: number;
2311
+ width: number;
2312
+ height: number;
2313
+ };
2314
+ value?: any;
2315
+ }>;
2316
+ meta: {
2317
+ viewerType: string;
2318
+ readonly: boolean;
2319
+ isLink: boolean;
2320
+ hasError: boolean;
2321
+ hasReminder: boolean;
2322
+ hasNestedGrid: boolean;
2323
+ };
2324
+ } | null;
2325
+ /**
2326
+ * Get interactive areas within a group row header.
2327
+ */
2328
+ testGetGroupRowAreas(rowId: string): {
2329
+ expandArrow: {
2330
+ canvasX: number;
2331
+ canvasY: number;
2332
+ width: number;
2333
+ height: number;
2334
+ };
2335
+ checkbox: {
2336
+ canvasX: number;
2337
+ canvasY: number;
2338
+ width: number;
2339
+ height: number;
2340
+ } | null;
2341
+ row: {
2342
+ canvasX: number;
2343
+ canvasY: number;
2344
+ width: number;
2345
+ height: number;
2346
+ };
2347
+ meta: {
2348
+ expanded: boolean;
2349
+ groupLevel: number;
2350
+ groupName: string;
2351
+ isLeafGroup: boolean;
2352
+ rowId: string;
2353
+ };
2354
+ } | null;
2355
+ /**
2356
+ * Get all visible group rows.
2357
+ */
2358
+ testGetVisibleGroupRows(): Array<{
2359
+ rowId: string;
2360
+ rowIndex: number;
2361
+ expanded: boolean;
2362
+ groupName: string;
2363
+ groupLevel: number;
2364
+ isLeafGroup: boolean;
2365
+ }>;
2366
+ /**
2367
+ * Get current selection, editing, and checked-row state.
2368
+ */
2369
+ testGetSelectionState(): {
2370
+ range: {
2371
+ startRow: number;
2372
+ startCol: number;
2373
+ endRow: number;
2374
+ endCol: number;
2375
+ } | null;
2376
+ activeCell: {
2377
+ rowIndex: number;
2378
+ colIndex: number;
2379
+ } | null;
2380
+ checkedRowIds: (string | number)[];
2381
+ editor: {
2382
+ show: boolean;
2383
+ rowIndex: number;
2384
+ colIndex: number;
2385
+ } | null;
2386
+ };
2029
2387
  }
2030
2388
  export default DataGrid;
@@ -17,7 +17,6 @@ interface EventTasks {
17
17
  declare class Events {
18
18
  grid: DataGrid;
19
19
  el: HTMLCanvasElement;
20
- isFirefox: boolean;
21
20
  eventTasks: EventTasks;
22
21
  constructor(grid: DataGrid, el: HTMLCanvasElement);
23
22
  init(): void;
@@ -35,6 +35,52 @@ declare class GroupRow extends Context {
35
35
  * level 2+: 18px(与 level 1 相同,避免叶子分组过度靠右)
36
36
  */
37
37
  private getLevelIndent;
38
+ /**
39
+ * 获取组头行的搜索命中状态。
40
+ *
41
+ * 状态来源:rowDataAdapter.preprocessRow 在 isGroup 行上注入的
42
+ * `_groupHeaderSearchMatched` 和 `_groupHeaderSearchCurrentHighlight` 字段。
43
+ *
44
+ * - Separator 行(isSeparateRow)永远返回 false/false,不承载搜索命中语义;
45
+ * - 非 isGroupHeader 行也返回 false/false(防御性兜底);
46
+ * - currentHighlight = true 时,draw() 会绘制 2px 橙色 inset 边框。
47
+ */
48
+ getGroupHeaderSearchMatchState(): {
49
+ matched: boolean;
50
+ currentHighlight: boolean;
51
+ };
52
+ /**
53
+ * 获取组头行搜索命中高亮的"首列左边框" x 坐标。
54
+ *
55
+ * 方案 1A(顶/底/左三边同步内缩到色条右缘):按 (maxGroupLevel, groupLevel)
56
+ * 计算序号列分层色条的宽度 `barWidth`,返回 `this.x + barWidth`,使左边框与
57
+ * `drawGroupHeader` 中色条右缘的灰色分隔竖线 x 位置完全对齐——色条区域不被
58
+ * 橙色边框包裹,保留分层层次感。
59
+ *
60
+ * barWidth 规则(与 drawGroupHeader 色条绘制逻辑一致):
61
+ * maxGroupLevel=0 (1D) → 无色条,barWidth = 0
62
+ * maxGroupLevel=1 (2D):groupLevel=0 → 0;groupLevel>=1 → l0w (6)
63
+ * maxGroupLevel=2 (3D):groupLevel=0 → 0;groupLevel>=1 → l0w (6);groupLevel>=2 → l0w+l1w (16)
64
+ *
65
+ * @param groupLevel - 当前组头行的层级(0 表示最外层)
66
+ * @returns 色条右缘的 x 坐标,作为顶/底/左三边的公共起点
67
+ */
68
+ getSearchHighlightFirstLeftBorderX(groupLevel: number): number;
69
+ /**
70
+ * 绘制组头行搜索命中的 2px 橙色 inset 边框(对齐 DOM 表格 data-search-matched-highlight 行为)。
71
+ *
72
+ * 边框组合(方案 1A:顶/底/左三边同步内缩到色条右缘):
73
+ * - 顶边 + 底边:从 `firstLeftX`(色条右缘)横跨到可视区域右边界,不覆盖序号列色条区
74
+ * - 首列左边:贴在 `firstLeftX`,与顶/底边起点对齐,视觉上与 `drawGroupHeader`
75
+ * 中色条右缘的灰色分隔竖线同列,使第二/第三层组头命中框与分组原有左边界对齐
76
+ * - 末列右边:仅当表格末列在可视区域内时绘制,位置保持不变(tableRightEdge)
77
+ *
78
+ * 色条区域(`this.x` 到 `firstLeftX` 之间)刻意不被橙色边框包裹,继续保留分层层次感。
79
+ *
80
+ * 仅当"当前高亮"(currentHighlight = true)时绘制,与 DOM 表格保持一致——
81
+ * "命中但非当前"状态不渲染边框,避免多条命中之间的视觉噪音。
82
+ */
83
+ private drawSearchHighlightBorder;
38
84
  /**
39
85
  * Draw group header row
40
86
  */
@@ -21,6 +21,8 @@ declare class ImageManager {
21
21
  private filterIconCanvas;
22
22
  private settingsIcon;
23
23
  private settingsIconCanvas;
24
+ private infoIcon;
25
+ private infoIconCanvas;
24
26
  private tapdIcon;
25
27
  private iomcIcon;
26
28
  private warningIcon;
@@ -104,6 +106,14 @@ declare class ImageManager {
104
106
  * @returns HTMLCanvasElement or HTMLImageElement or null if not loaded
105
107
  */
106
108
  getFilterIcon(): HTMLCanvasElement | HTMLImageElement | null;
109
+ /**
110
+ * Get a colored version of filter icon (on-demand recolor, no cache).
111
+ * Used for "filter active" state where icon must show a themed highlight color.
112
+ * @param color Target fill color
113
+ * @param size Display size (square)
114
+ * @returns HTMLCanvasElement with colored icon, or null if source icon not yet loaded
115
+ */
116
+ getColoredFilterIcon(color: string, size?: number): HTMLCanvasElement | null;
107
117
  /**
108
118
  * Load settings icon (for nested column parent headers)
109
119
  */
@@ -113,6 +123,17 @@ declare class ImageManager {
113
123
  * @returns HTMLCanvasElement or HTMLImageElement or null if not loaded
114
124
  */
115
125
  getSettingsIcon(): HTMLCanvasElement | HTMLImageElement | null;
126
+ /** fieldHint info icon color */
127
+ private static INFO_ICON_COLOR;
128
+ /**
129
+ * Load fieldHint info icon and recolor to #767E89 (14px for header business icon slot)
130
+ */
131
+ private loadInfoIcon;
132
+ /**
133
+ * Get fieldHint info icon (recolored 14px canvas version)
134
+ * @returns HTMLCanvasElement or HTMLImageElement or null if not loaded
135
+ */
136
+ getInfoIcon(): HTMLCanvasElement | HTMLImageElement | null;
116
137
  /**
117
138
  * Load TAPD sync icon (display only)
118
139
  */