@guiexpert/table 1.1.79 → 1.1.81

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.
@@ -8,43 +8,639 @@ import { SelectionModelIf } from './selection/selection-model.if';
8
8
  import { TableModelIf } from './data/tablemodel/table-model.if';
9
9
  import { AreaModelIf } from './data/tablemodel/areamodel/area-model.if';
10
10
  /**
11
- * The TableApi class provides a set of methods to interact with a table's functionality.
12
- * It enables actions such as updating cells, scrolling, managing visibility, handling selection,
13
- * copying to the clipboard, downloading data, and triggering specific actions programmatically.
11
+ * # TableApi
12
+ *
13
+ * The TableApi class provides a comprehensive interface for programmatically interacting with a table component.
14
+ * After creating a table component, each component gets its own TableApi instance that serves as the primary
15
+ * means for developers to control and interact with the rendered table.
16
+ *
17
+ * ## Overview
18
+ *
19
+ * TableApi acts as a facade over the internal table implementation, providing a clean, well-documented API
20
+ * that abstracts away the complexity of the underlying table mechanics. It delegates most operations to the
21
+ * TableScope instance, which contains the actual implementation details.
22
+ *
23
+ * ## Core Functionality
24
+ *
25
+ * The TableApi provides methods for:
26
+ *
27
+ * ### Data Management
28
+ * - Setting, adding, and removing rows
29
+ * - Updating individual cells or ranges of cells
30
+ * - Finding and filtering rows based on criteria
31
+ * - Sorting data with custom comparators
32
+ *
33
+ * ### Visual Control
34
+ * - Scrolling to specific positions (by pixel or row/column index)
35
+ * - Controlling visibility of header, footer, and columns
36
+ * - Adjusting column widths (manually or automatically)
37
+ * - Repainting the table (normal or hard repaint)
38
+ *
39
+ * ### Selection and Focus
40
+ * - Managing cell, row, or column selection
41
+ * - Clearing selections
42
+ * - Ensuring specific rows are visible in the viewport
43
+ *
44
+ * ### Export and Clipboard
45
+ * - Copying selected data to clipboard
46
+ * - Exporting table data to Excel
47
+ *
48
+ * ### Events and Actions
49
+ * - Triggering specific actions programmatically
50
+ * - Responding to external filter changes
51
+ *
52
+ * ### Debugging
53
+ * - Enabling/disabling logging for troubleshooting
54
+ *
55
+ * ## Usage Patterns
56
+ *
57
+ * The TableApi is designed to be used in several common patterns:
58
+ *
59
+ * ### 1. Direct Method Calls
60
+ *
61
+ * The most straightforward usage is to call methods directly on the TableApi instance:
62
+ *
63
+ * ```typescript
64
+ * // Get the API from your table component
65
+ * const api = tableComponent.api;
66
+ *
67
+ * // Call methods directly
68
+ * api.setRows(newData);
69
+ * api.scrollToIndex(0, 10);
70
+ * api.repaint();
71
+ * ```
72
+ *
73
+ * ### 2. Chaining Operations
74
+ *
75
+ * While the TableApi doesn't support method chaining directly (most methods return void),
76
+ * you can group related operations together:
77
+ *
78
+ * ```typescript
79
+ * // Perform a sequence of related operations
80
+ * function updateTableSection(api, newRows, startIndex) {
81
+ * api.addRowsAt(newRows, startIndex);
82
+ * api.ensureRowIsVisible(startIndex);
83
+ * api.repaint();
84
+ * }
85
+ * ```
86
+ *
87
+ * ### 3. Event-Driven Updates
88
+ *
89
+ * Use the TableApi to respond to external events:
90
+ *
91
+ * ```typescript
92
+ * // Update table in response to user input
93
+ * searchInput.addEventListener('input', (e) => {
94
+ * const searchText = e.target.value;
95
+ * tableOptions.externalFilterFunction = row => row.name.includes(searchText);
96
+ * tableApi.externalFilterChanged();
97
+ * });
98
+ * ```
99
+ *
100
+ * ### 4. Integration with Application State
101
+ *
102
+ * Synchronize table state with application state:
103
+ *
104
+ * ```typescript
105
+ * // In a state management effect or watcher
106
+ * function onAppStateChanged(newState) {
107
+ * if (newState.tableData !== currentTableData) {
108
+ * tableApi.setRows(newState.tableData);
109
+ * tableApi.repaint();
110
+ * currentTableData = newState.tableData;
111
+ * }
112
+ * }
113
+ * ```
114
+ *
115
+ * ## Performance Considerations
116
+ *
117
+ * The TableApi provides methods that are optimized for different performance scenarios:
118
+ *
119
+ * - For frequent small updates: Use `updateCells()` with `repaintAll=false`
120
+ * - For complete data replacement: Use `setRows()`
121
+ * - For structural changes: Follow with `repaintHard()`
122
+ * - For visual-only changes: Use `repaint()`
123
+ *
124
+ * ## Common Use Cases
125
+ *
126
+ * ### Real-time Data Updates
127
+ *
128
+ * ```typescript
129
+ * // Update specific cells with new values from a data stream
130
+ * dataStream.subscribe(update => {
131
+ * const cellUpdates = update.changes.map(change => ({
132
+ * area: 'body',
133
+ * rowIndex: change.rowIndex,
134
+ * columnIndex: change.columnIndex,
135
+ * value: change.newValue,
136
+ * cssClasses: { 'updated': true }
137
+ * }));
138
+ *
139
+ * tableApi.updateCells(cellUpdates);
140
+ * });
141
+ * ```
142
+ *
143
+ * ### Interactive Filtering
144
+ *
145
+ * ```typescript
146
+ * // Set up filter controls
147
+ * function applyFilters(filters) {
148
+ * tableOptions.externalFilterFunction = row => {
149
+ * return Object.entries(filters).every(([key, value]) => {
150
+ * if (!value) return true; // Skip empty filters
151
+ * return row[key].toString().includes(value);
152
+ * });
153
+ * };
154
+ *
155
+ * tableApi.externalFilterChanged();
156
+ * }
157
+ * ```
158
+ *
159
+ * ### Custom Sorting
160
+ *
161
+ * ```typescript
162
+ * // Apply multi-column sorting
163
+ * function sortByMultipleColumns(sortConfig) {
164
+ * tableApi.sort((a, b) => {
165
+ * for (const {column, direction} of sortConfig) {
166
+ * const aValue = a[column];
167
+ * const bValue = b[column];
168
+ * const comparison = compare(aValue, bValue);
169
+ *
170
+ * if (comparison !== 0) {
171
+ * return direction === 'asc' ? comparison : -comparison;
172
+ * }
173
+ * }
174
+ * return 0;
175
+ * });
176
+ * }
177
+ *
178
+ * function compare(a, b) {
179
+ * if (typeof a === 'string' && typeof b === 'string') {
180
+ * return a.localeCompare(b);
181
+ * }
182
+ * return a < b ? -1 : a > b ? 1 : 0;
183
+ * }
184
+ * ```
185
+ *
186
+ * ### Row Management
187
+ *
188
+ * ```typescript
189
+ * // Add, update, and remove rows based on user interactions
190
+ * function onAddRow(newRow) {
191
+ * tableApi.addRows([newRow]);
192
+ * tableApi.ensureRowIsVisible(tableApi.getDisplayedRowCount() - 1);
193
+ * }
194
+ *
195
+ * function onUpdateRow(updatedRow) {
196
+ * tableApi.updateRows([updatedRow], (a, b) => a.id === b.id);
197
+ * }
198
+ *
199
+ * function onDeleteRow(rowToDelete) {
200
+ * tableApi.removeRows([rowToDelete], (a, b) => a.id === b.id);
201
+ * }
202
+ * ```
203
+ *
204
+ * ### Export and Reporting
205
+ *
206
+ * ```typescript
207
+ * // Set up export buttons
208
+ * exportButton.addEventListener('click', () => {
209
+ * tableApi.downloadExcel('report.xlsx', 'Report Generator');
210
+ * });
211
+ *
212
+ * copyButton.addEventListener('click', () => {
213
+ * tableApi.copyToClipboard()
214
+ * .then(() => showNotification('Data copied to clipboard'))
215
+ * .catch(err => showError('Failed to copy data', err));
216
+ * });
217
+ * ```
218
+ *
219
+ * ### Responsive Behavior
220
+ *
221
+ * ```typescript
222
+ * // Handle window resize events
223
+ * window.addEventListener('resize', () => {
224
+ * tableApi.autoResizeColumns();
225
+ * tableApi.repaintHard();
226
+ * });
227
+ * ```
228
+ *
229
+ * ## Integration with Frameworks
230
+ *
231
+ * ### React
232
+ *
233
+ * ```jsx
234
+ * function DataTable({ data, onRowSelect }) {
235
+ * const tableRef = useRef(null);
236
+ *
237
+ * useEffect(() => {
238
+ * if (tableRef.current && tableRef.current.api) {
239
+ * tableRef.current.api.setRows(data);
240
+ * tableRef.current.api.repaint();
241
+ * }
242
+ * }, [data]);
243
+ *
244
+ * return <div ref={tableRef} className="table-container" />;
245
+ * }
246
+ * ```
247
+ *
248
+ * ### Vue
249
+ *
250
+ * ```vue
251
+ * <template>
252
+ * <div ref="tableContainer"></div>
253
+ * </template>
254
+ *
255
+ * <script>
256
+ * export default {
257
+ * props: ['tableData'],
258
+ * watch: {
259
+ * tableData(newData) {
260
+ * if (this.tableApi) {
261
+ * this.tableApi.setRows(newData);
262
+ * this.tableApi.repaint();
263
+ * }
264
+ * }
265
+ * },
266
+ * mounted() {
267
+ * // Initialize table and get API reference
268
+ * this.tableApi = initializeTable(this.$refs.tableContainer).api;
269
+ * }
270
+ * }
271
+ * </script>
272
+ * ```
273
+ *
274
+ * ### Angular
275
+ *
276
+ * ```typescript
277
+ * @Component({
278
+ * selector: 'app-data-table',
279
+ * template: '<div #tableContainer></div>'
280
+ * })
281
+ * export class DataTableComponent implements OnInit, OnChanges {
282
+ * @Input() data: any[];
283
+ * @ViewChild('tableContainer') tableContainer: ElementRef;
284
+ *
285
+ * private tableApi: TableApi;
286
+ *
287
+ * ngOnInit() {
288
+ * this.tableApi = initializeTable(this.tableContainer.nativeElement).api;
289
+ * }
290
+ *
291
+ * ngOnChanges(changes) {
292
+ * if (changes.data && this.tableApi) {
293
+ * this.tableApi.setRows(this.data);
294
+ * this.tableApi.repaint();
295
+ * }
296
+ * }
297
+ * }
298
+ * ```
299
+ *
300
+ * ## Error Handling
301
+ *
302
+ * The TableApi methods generally don't throw exceptions, but instead log warnings to the console
303
+ * when operations cannot be completed (e.g., when trying to use row operations on an incompatible
304
+ * area model type). It's good practice to check console warnings during development.
305
+ *
306
+ * For asynchronous operations like clipboard access, proper error handling should be used:
307
+ *
308
+ * ```typescript
309
+ * tableApi.copyToClipboard()
310
+ * .then(content => {
311
+ * console.log('Copied to clipboard:', content);
312
+ * })
313
+ * .catch(error => {
314
+ * console.error('Failed to copy to clipboard:', error);
315
+ * // Show user-friendly error message
316
+ * });
317
+ * ```
318
+ *
319
+ * ## Debugging
320
+ *
321
+ * For troubleshooting complex table behavior, the logging system can be enabled:
322
+ *
323
+ * ```typescript
324
+ * // Enable detailed logging
325
+ * tableApi.setLoggingActive(true);
326
+ *
327
+ * // Perform operations that need debugging
328
+ * tableApi.updateCells([...]);
329
+ * tableApi.scrollToIndex(5, 10);
330
+ *
331
+ * // Check if logging is active
332
+ * const isLogging = tableApi.isLoggingActive();
333
+ *
334
+ * // Disable logging when done
335
+ * tableApi.setLoggingActive(false);
336
+ * ```
337
+ *
338
+ * ## Advanced Usage
339
+ *
340
+ * For advanced scenarios, you can access the underlying TableScope:
341
+ *
342
+ * ```typescript
343
+ * const tableScope = tableApi.getTableScope();
344
+ * // Now you can access internal implementation details
345
+ * // Note: This is generally not recommended unless absolutely necessary
346
+ * ```
347
+ *
348
+ * @class TableApi
14
349
  */
15
350
  export declare class TableApi {
16
351
  readonly tableScope: TableScope;
17
352
  constructor(tableScope: TableScope);
18
353
  /**
19
- * Updates the cells in the table based on the provided events.
354
+ * Updates the cells in the table with the provided cell update events.
20
355
  *
21
- * @param {TableCellUpdateEventIf[]} events - The array of events representing the updates to perform on the cells.
22
- * @param {boolean} [repaintAll=false] - Optional parameter indicating whether to repaint all cells or not. Default value is false. If true, the full table will be rendered. If false, the table cell will be rendered immediately.
356
+ * This method allows you to update specific cells in the table without requiring a full table repaint,
357
+ * which can significantly improve performance when updating large tables frequently.
23
358
  *
24
- * @return {void} - This method doesn't return anything.
359
+ * @param {TableCellUpdateEventIf[]} events - An array of cell update events, each defining a single cell update operation.
360
+ * Each event must specify:
361
+ * - area: The table area to update ('header', 'body', or 'footer')
362
+ * - rowIndex: The row index of the cell to update
363
+ * - columnIndex: The column index of the cell to update
364
+ * - value: The new value to set for the cell
365
+ * - cssClasses: Optional object mapping CSS class names to boolean values
366
+ * (true to add the class, false to remove it)
367
+ *
368
+ * @param {boolean} [repaintAll=false] - Whether to repaint the entire table after updating cells.
369
+ * - If true: All cells will be repainted after updating (slower but ensures visual consistency)
370
+ * - If false: Only the modified cells will be repainted (faster, recommended for frequent updates)
371
+ *
372
+ * @returns {void}
373
+ *
374
+ * @example
375
+ * // Update a single cell with a new value and CSS classes
376
+ * tableApi.updateCells([{
377
+ * area: 'body',
378
+ * rowIndex: 3,
379
+ * columnIndex: 2,
380
+ * value: 42,
381
+ * cssClasses: {
382
+ * 'highlight': true, // Add 'highlight' class
383
+ * 'error': false // Remove 'error' class if present
384
+ * }
385
+ * }]);
386
+ *
387
+ * @example
388
+ * // Update multiple cells at once
389
+ * tableApi.updateCells([
390
+ * {
391
+ * area: 'body',
392
+ * rowIndex: 1,
393
+ * columnIndex: 1,
394
+ * value: 'New Value 1',
395
+ * cssClasses: { 'updated': true }
396
+ * },
397
+ * {
398
+ * area: 'body',
399
+ * rowIndex: 2,
400
+ * columnIndex: 3,
401
+ * value: 'New Value 2',
402
+ * cssClasses: { 'updated': true }
403
+ * }
404
+ * ]);
405
+ *
406
+ * @example
407
+ * // Update cells and repaint the entire table
408
+ * tableApi.updateCells([
409
+ * { area: 'body', rowIndex: 0, columnIndex: 0, value: 'Hello', cssClasses: { 'bg-green-0': true } },
410
+ * { area: 'body', rowIndex: 1, columnIndex: 1, value: 'World', cssClasses: { 'bg-red-0': true } }
411
+ * ], true);
412
+ *
413
+ * @example
414
+ * // High-performance animation example (update without full repaint)
415
+ * function animateCell() {
416
+ * const value = Math.sin(Date.now() / 1000) * 50;
417
+ * const cssClasses = {
418
+ * 'positive': value > 0,
419
+ * 'negative': value < 0
420
+ * };
421
+ *
422
+ * tableApi.updateCells([{
423
+ * area: 'body',
424
+ * rowIndex: 0,
425
+ * columnIndex: 0,
426
+ * value: Math.round(value),
427
+ * cssClasses
428
+ * }]);
429
+ *
430
+ * requestAnimationFrame(animateCell);
431
+ * }
432
+ * animateCell();
25
433
  */
26
434
  updateCells(events: TableCellUpdateEventIf[], repaintAll?: boolean): void;
27
435
  /**
28
- * Notifies that the external filter has changed.
436
+ * Notifies the table that an external filter has been changed and needs to be applied.
29
437
  *
30
- * @return {void}
438
+ * This method is used when an external filter condition (defined by `tableOptions.externalFilterFunction`)
439
+ * has changed and the table needs to refresh its display to reflect the new filtering criteria.
440
+ *
441
+ * When called, this method:
442
+ * 1. Applies the external filter function to all rows
443
+ * 2. Clears the current selection (by default)
444
+ * 3. Scrolls to the top of the table
445
+ * 4. Recalculates table dimensions
446
+ * 5. Repaints the table to display only the filtered rows
447
+ *
448
+ * @example
449
+ * ```typescript
450
+ * // Define an external filter function in your table options
451
+ * const tableOptions = {
452
+ * externalFilterFunction: (row: MyRowType) => {
453
+ * // Return true to include the row, false to filter it out
454
+ * return row.status === 'active';
455
+ * }
456
+ * };
457
+ *
458
+ * // Initialize your table with these options
459
+ * const tableApi = new TableApi(tableScope);
460
+ *
461
+ * // Later, when filter criteria change (e.g., in a search input handler)
462
+ * function onFilterTextChanged() {
463
+ * // Update the filter function if needed
464
+ * tableOptions.externalFilterFunction = (row: MyRowType) => {
465
+ * return row.name.includes(searchText);
466
+ * };
467
+ *
468
+ * // Apply the updated filter
469
+ * tableApi.externalFilterChanged();
470
+ * }
471
+ * ```
472
+ *
473
+ * @returns {void}
474
+ * @see TableScope.externalFilterChanged
31
475
  */
32
476
  externalFilterChanged(): void;
33
477
  /**
34
- * Scrolls the table body to the specified pixel coordinates.
478
+ * Scrolls the table content to the specified pixel coordinates.
35
479
  *
36
- * @param {number} px - The horizontal pixel coordinate to scroll to. Defaults to 0.
37
- * @param {number} py - The vertical pixel coordinate to scroll to. Defaults to 0.
38
- * @return {void}
480
+ * This method allows programmatic scrolling of the table viewport to exact pixel positions.
481
+ * It delegates the scrolling operation to the underlying TableScope instance.
482
+ *
483
+ * @param {number} px - The horizontal pixel coordinate to scroll to. Defaults to 0 (leftmost position).
484
+ * @param {number} py - The vertical pixel coordinate to scroll to. Defaults to 0 (topmost position).
485
+ * @returns {void}
486
+ *
487
+ * @example
488
+ * // Scroll to the top-left corner of the table
489
+ * tableApi.scrollToPixel(0, 0);
490
+ *
491
+ * @example
492
+ * // Scroll 200 pixels horizontally and 150 pixels vertically
493
+ * tableApi.scrollToPixel(200, 150);
494
+ *
495
+ * @example
496
+ * // Scroll only vertically, keeping the current horizontal position
497
+ * tableApi.scrollToPixel(undefined, 300);
498
+ *
499
+ * @example
500
+ * // Example in a component that needs precise scrolling control
501
+ * class TableScroller {
502
+ * private tableApi: TableApi;
503
+ *
504
+ * constructor(tableApi: TableApi) {
505
+ * this.tableApi = tableApi;
506
+ * }
507
+ *
508
+ * scrollToPosition(x: number, y: number) {
509
+ * // Scroll to exact pixel coordinates
510
+ * this.tableApi.scrollToPixel(x, y);
511
+ * }
512
+ *
513
+ * scrollHalfway() {
514
+ * const tableModel = this.tableApi.getTableModel();
515
+ * const totalWidth = tableModel.getContentWidthInPixel();
516
+ * const totalHeight = tableModel.getContentHeightInPixel();
517
+ *
518
+ * // Scroll to the middle of the table content
519
+ * this.tableApi.scrollToPixel(totalWidth / 2, totalHeight / 2);
520
+ * }
521
+ * }
522
+ *
523
+ * @example
524
+ * // Advanced usage with animated scrolling
525
+ * class SmoothScroller {
526
+ * private tableApi: TableApi;
527
+ * private animationFrameId: number | null = null;
528
+ *
529
+ * constructor(tableApi: TableApi) {
530
+ * this.tableApi = tableApi;
531
+ * }
532
+ *
533
+ * smoothScrollTo(targetX: number, targetY: number, duration: number = 500) {
534
+ * // Cancel any ongoing animation
535
+ * if (this.animationFrameId !== null) {
536
+ * cancelAnimationFrame(this.animationFrameId);
537
+ * }
538
+ *
539
+ * const startTime = performance.now();
540
+ * const startX = this.tableApi.getTableScope().getScrollLeft();
541
+ * const startY = this.tableApi.getTableScope().getScrollTop();
542
+ * const distanceX = targetX - startX;
543
+ * const distanceY = targetY - startY;
544
+ *
545
+ * const step = (currentTime: number) => {
546
+ * const elapsed = currentTime - startTime;
547
+ * const progress = Math.min(elapsed / duration, 1);
548
+ *
549
+ * // Use easing function for smooth animation
550
+ * const easeProgress = 1 - Math.pow(1 - progress, 3); // Cubic ease-out
551
+ *
552
+ * const currentX = startX + distanceX * easeProgress;
553
+ * const currentY = startY + distanceY * easeProgress;
554
+ *
555
+ * this.tableApi.scrollToPixel(currentX, currentY);
556
+ *
557
+ * if (progress < 1) {
558
+ * this.animationFrameId = requestAnimationFrame(step);
559
+ * } else {
560
+ * this.animationFrameId = null;
561
+ * }
562
+ * };
563
+ *
564
+ * this.animationFrameId = requestAnimationFrame(step);
565
+ * }
566
+ *
567
+ * cancelAnimation() {
568
+ * if (this.animationFrameId !== null) {
569
+ * cancelAnimationFrame(this.animationFrameId);
570
+ * this.animationFrameId = null;
571
+ * }
572
+ * }
573
+ * }
574
+ *
575
+ * @see {@link scrollToIndex} - For scrolling based on row and column indices
576
+ * @see {@link ensureRowIsVisible} - For scrolling to make a specific row visible
39
577
  */
40
578
  scrollToPixel(px?: number, py?: number): void;
41
579
  /**
42
- * Scrolls to the specified index in both horizontal and vertical directions.
580
+ * Scrolls the table to display the specified row and column indices at the top-left corner of the viewport.
43
581
  *
44
- * @param {number} indexX - The index of the column to scroll to in the horizontal direction. Default is 0.
45
- * @param {number} indexY - The index of the row to scroll to in the vertical direction. Default is 0.
582
+ * This method allows programmatic scrolling to a specific position in the table grid based on row and column indices.
583
+ * It uses the underlying TableScope's scrolling mechanism to navigate to the target location.
46
584
  *
47
- * @return undefined
585
+ * @param {number} indexX - The horizontal index (column) to scroll to. Defaults to 0 (leftmost column).
586
+ * @param {number} indexY - The vertical index (row) to scroll to. Defaults to 0 (topmost row).
587
+ * @returns {void}
588
+ *
589
+ * @example
590
+ * // Scroll to the 5th row, keeping the current horizontal scroll position
591
+ * tableApi.scrollToIndex(0, 5);
592
+ *
593
+ * @example
594
+ * // Scroll to column 3, row 10
595
+ * tableApi.scrollToIndex(3, 10);
596
+ *
597
+ * @example
598
+ * // Example in a component that needs to navigate to specific content
599
+ * class TableNavigator {
600
+ * private tableApi: TableApi;
601
+ *
602
+ * constructor(tableApi: TableApi) {
603
+ * this.tableApi = tableApi;
604
+ * }
605
+ *
606
+ * goToCell(columnIndex: number, rowIndex: number) {
607
+ * // Navigate directly to the specified cell position
608
+ * this.tableApi.scrollToIndex(columnIndex, rowIndex);
609
+ *
610
+ * // Optional: Select the cell after navigating to it
611
+ * const selectionModel = this.tableApi.getSelectionModel();
612
+ * if (selectionModel) {
613
+ * selectionModel.selectCell(rowIndex, columnIndex);
614
+ * }
615
+ * }
616
+ * }
617
+ *
618
+ * @example
619
+ * // Advanced usage with search functionality
620
+ * class TableSearcher {
621
+ * findAndScrollToMatch(searchTerm: string) {
622
+ * const tableModel = this.tableApi.getTableModel();
623
+ * const bodyModel = tableModel.getAreaModel('body');
624
+ *
625
+ * // Search for the term in the table data
626
+ * for (let row = 0; row < bodyModel.getRowCount(); row++) {
627
+ * for (let col = 0; col < tableModel.getColumnCount(); col++) {
628
+ * const cellContent = bodyModel.getValueAt(row, col)?.toString() || '';
629
+ *
630
+ * if (cellContent.includes(searchTerm)) {
631
+ * // Found a match, scroll to it
632
+ * this.tableApi.scrollToIndex(col, row);
633
+ * return true;
634
+ * }
635
+ * }
636
+ * }
637
+ *
638
+ * return false; // No match found
639
+ * }
640
+ * }
641
+ *
642
+ * @see {@link scrollToPixel} - For scrolling to specific pixel coordinates
643
+ * @see {@link ensureRowIsVisible} - For scrolling to make a specific row visible
48
644
  */
49
645
  scrollToIndex(indexX?: number, indexY?: number): void;
50
646
  /**
@@ -94,17 +690,69 @@ export declare class TableApi {
94
690
  /**
95
691
  * Repaints the table.
96
692
  *
97
- * This method calls the repaint method of the tableScope object
98
- * to update and redraw the table based on the latest data.
693
+ * This method refreshes the visual representation of the table by delegating to the
694
+ * tableScope's repaint functionality. Use this method whenever the table's visual state
695
+ * needs to be updated after data changes, selection changes, or any modifications that
696
+ * affect the rendered output.
697
+ *
698
+ * Repainting the table ensures that all visible cells, rows, and styling reflect the
699
+ * current state of the underlying data model and configuration settings.
700
+ *
701
+ * @example
702
+ * // Update data and repaint the table
703
+ * const tableApi = new TableApi(tableScope);
704
+ * tableApi.setRows(newData);
705
+ * tableApi.repaint();
706
+ *
707
+ * @example
708
+ * // Update selection and repaint to show the visual change
709
+ * tableApi.getSelectionModel().selectCell(2, 3);
710
+ * tableApi.repaint();
711
+ *
712
+ * @example
713
+ * // After changing column visibility, repaint to reflect changes
714
+ * tableApi.setColumnVisible(0, false);
715
+ * tableApi.repaint();
716
+ *
717
+ * @returns {void}
99
718
  */
100
719
  repaint(): void;
101
720
  /**
102
- * Repaints the table scope with hard repaint.
103
- * Repaints the UI by resetting the size of the wrapper div,
104
- * adjusting the containers and rows, and performing additional adjustments
105
- * after scrolling.
721
+ * Performs a complete repaint of the table by triggering a hard repaint on the underlying table scope.
106
722
  *
107
- * @return {void}
723
+ * A hard repaint is more thorough than a regular repaint and performs the following operations:
724
+ * - Recalculates the height and padding of the table model
725
+ * - Resets the size of the wrapper div elements
726
+ * - Adjusts containers and rows positioning
727
+ * - Makes additional adjustments after scrolling
728
+ *
729
+ * Use this method when regular repaint isn't sufficient, such as when:
730
+ * - Table dimensions have significantly changed
731
+ * - The structure of data has been modified (rows/columns added or removed)
732
+ * - The table layout needs complete recalculation
733
+ * - After major DOM changes affecting the table's container
734
+ *
735
+ * @example
736
+ * // Example 1: Basic usage
737
+ * tableApi.repaintHard();
738
+ *
739
+ * @example
740
+ * // Example 2: Using after major data changes
741
+ * tableApi.setRows(newDataSet);
742
+ * tableApi.repaintHard();
743
+ *
744
+ * @example
745
+ * // Example 3: Using after resizing a container
746
+ * window.addEventListener('resize', () => {
747
+ * tableApi.repaintHard();
748
+ * });
749
+ *
750
+ * @example
751
+ * // Example 4: Using after changing column visibility
752
+ * tableApi.setColumnVisible(2, false);
753
+ * tableApi.repaintHard();
754
+ *
755
+ * @returns {void} This method doesn't return a value
108
756
  */
109
757
  repaintHard(): void;
110
758
  /**
@@ -116,19 +764,60 @@ export declare class TableApi {
116
764
  */
117
765
  recalcColumnWidths(clientWidth?: number): void;
118
766
  /**
119
- * Clears the current selection of the table.
120
- * The table will be rendered automatically.
767
+ * Clears the current selection in the table.
768
+ *
769
+ * This method removes any selected cells, rows, or columns in the table.
770
+ * It provides a convenient way to programmatically clear all selections in the table
771
+ * without having to access the underlying selection model directly.
772
+ *
773
+ * When called, this method delegates to the table scope's clearSelection method with
774
+ * a parameter value of true, which ensures the table is automatically repainted after
775
+ * the selection is cleared.
776
+ *
777
+ * @example
778
+ * // Clear all selections in the table
779
+ * tableApi.clearSelection();
780
+ *
781
+ * // Example usage in a component
782
+ * class MyComponent {
783
+ * @ViewChild('tableComponent') tableComponent: TableComponent;
784
+ *
785
+ * resetTableSelection(): void {
786
+ * if (this.tableComponent?.api) {
787
+ * this.tableComponent.api.clearSelection();
788
+ * }
789
+ * }
790
+ * }
121
791
  *
122
792
  * @returns {void}
123
793
  */
124
794
  clearSelection(): void;
125
795
  /**
126
- * Sets the selection model for the table scope.
796
+ * Sets the selection model for the table.
127
797
  *
128
- * @param {SelectionModel} sm - The selection model to be set.
129
- * @param {boolean} [repaint=true] - Indicates whether the table should be repainted after setting the selection model. Default value is true.
798
+ * This method allows you to replace the current selection model with a new one,
799
+ * which controls how cells, rows, or columns can be selected in the table.
130
800
  *
131
- * @return {void}
801
+ * @param {SelectionModel} sm - The new selection model to be set. This model defines
802
+ * the selection behavior including selection type (none, cell, row, column),
803
+ * selection mode (single, multi), and manages the selected ranges.
804
+ * @param {boolean} [repaint=true] - Whether to repaint the table after changing the selection model.
805
+ * Default is true, which immediately reflects the change visually.
806
+ * Set to false if you want to avoid immediate repainting.
807
+ *
808
+ * @example
809
+ * // Create a new selection model with row selection and multi-select mode
810
+ * const selectionModel = new SelectionModel("row", "multi");
811
+ *
812
+ * // Set the new selection model and repaint the table
813
+ * tableApi.setSelectionModel(selectionModel);
814
+ *
815
+ * // Set a selection model without repainting (if you plan to make more changes)
816
+ * tableApi.setSelectionModel(selectionModel, false);
817
+ * // ... make other changes ...
818
+ * tableApi.repaint(); // Now repaint once
819
+ *
820
+ * @returns {void}
132
821
  */
133
822
  setSelectionModel(sm: SelectionModel, repaint?: boolean): void;
134
823
  /**
@@ -140,36 +829,161 @@ export declare class TableApi {
140
829
  */
141
830
  triggerAction(actionId: ActionId): void;
142
831
  /**
143
- * Retrieves the mapping of shortcuts to corresponding action in the current table scope.
832
+ * Retrieves the shortcut action mapping from the table's shortcut service.
833
+ *
834
+ * This method provides access to the keyboard shortcut configuration that defines
835
+ * which keys trigger specific actions in the table. The mapping contains key-value
836
+ * pairs where:
837
+ * - Keys are string representations of keyboard shortcuts (e.g., "ctrl+c", "shift+arrow_down")
838
+ * - Values are ActionId values representing the corresponding table actions
839
+ *
840
+ * This mapping can be useful for:
841
+ * - Displaying available shortcuts to users
842
+ * - Creating custom shortcut documentation
843
+ * - Dynamically checking which actions are available via keyboard
844
+ * - Extending or integrating with the table's shortcut system
845
+ *
846
+ * @returns {ShortcutActionIdMapping} An object mapping shortcut key combinations to their corresponding action IDs.
847
+ * For example: { "ctrl+c": "COPY_2_CLIPBOARD", "arrow_down": "NAVIGATE_DOWN" }
848
+ *
849
+ * @example
850
+ * // Get all available shortcuts in the table
851
+ * const shortcuts = tableApi.getShortcutActionMapping();
144
852
  *
145
- * @return {ShortcutActionIdMapping} The mapping of shortcuts to corresponding action.
853
+ * // Check if a specific shortcut exists
854
+ * if (shortcuts["ctrl+c"]) {
855
+ * console.log("Copy shortcut is available with action:", shortcuts["ctrl+c"]);
856
+ * }
857
+ *
858
+ * // Display available shortcuts in the UI
859
+ * Object.entries(shortcuts).forEach(([key, actionId]) => {
860
+ * console.log(`${key}: ${actionId}`);
861
+ * });
146
862
  */
147
863
  getShortcutActionMapping(): ShortcutActionIdMapping;
148
864
  /**
149
865
  * Copies the selected data from the table to the clipboard.
150
866
  *
151
- * @return {Promise<string>} - A promise that resolves with the copied data as a string.
867
+ * This method leverages the copyService to extract and copy the currently selected data
868
+ * from the table. It works with the current selection state and focus position to determine
869
+ * what content should be copied.
870
+ *
871
+ * The copied data is formatted as tab-separated text that can be pasted into spreadsheet
872
+ * applications like Excel or text editors while maintaining the tabular structure.
873
+ *
874
+ * @example
875
+ * // Copy the currently selected data to clipboard
876
+ * tableApi.copyToClipboard().then(content => {
877
+ * console.log('Copied to clipboard:', content);
878
+ * });
879
+ *
880
+ * // Using with a button click handler
881
+ * function onCopyButtonClick() {
882
+ * if (tableApi) {
883
+ * tableApi.copyToClipboard()
884
+ * .then(content => {
885
+ * console.log('Successfully copied data to clipboard');
886
+ * // Optionally do something with the copied content
887
+ * })
888
+ * .catch(error => {
889
+ * console.error('Failed to copy to clipboard:', error);
890
+ * });
891
+ * }
892
+ * }
893
+ *
894
+ * @returns {Promise<string>} A promise that resolves with the copied data as a string.
895
+ * The string contains the tab-separated representation of the selected table data.
152
896
  */
153
897
  copyToClipboard(): Promise<string>;
154
898
  /**
155
- * Generates and downloads an Excel file based on the table data.
899
+ * Downloads the current table data as an Excel file.
900
+ *
901
+ * This method extracts all visible data from the table (including header, body, and footer areas),
902
+ * converts it into a matrix format, and triggers a download of an Excel file containing this data.
903
+ *
904
+ * The method works by:
905
+ * 1. Creating an empty matrix to hold all table data
906
+ * 2. Iterating through each area of the table (header, body, footer)
907
+ * 3. For each area, iterating through all rows and columns to extract cell values
908
+ * 4. Passing the complete data matrix to the Excel service for file generation and download
909
+ *
910
+ * @param {string} fileName - The name of the Excel file to be downloaded (default: 'table.xlsx')
911
+ * @param {string} author - Optional metadata for the Excel file to specify the author (default: '')
156
912
  *
157
- * @param {string} fileName - The name of the Excel file to be downloaded. Defaults to 'table.xlsx'.
158
- * @param {string} author - The author of the Excel file. If not provided, it will remain empty.
159
- * @return {void} No return value. Initiates a file download of the Excel document.
913
+ * @returns {void} The result of the excelService.downloadExcel method call
914
+ *
915
+ * @example
916
+ * // Download table data with default filename
917
+ * tableApi.downloadExcel();
918
+ *
919
+ * @example
920
+ * // Download table data with custom filename and author
921
+ * tableApi.downloadExcel('sales-report.xlsx', 'John Doe');
922
+ *
923
+ * @example
924
+ * // Download table data with custom filename only
925
+ * tableApi.downloadExcel('quarterly-data.xlsx');
160
926
  */
161
927
  downloadExcel(fileName?: string, author?: string): void;
162
928
  /**
163
- * Retrieves the current scope of the table.
929
+ * Returns the TableScope instance associated with this TableApi.
930
+ *
931
+ * The TableScope provides access to the core functionality and internal state of the table component,
932
+ * including rendering, event handling, selection, and other low-level operations.
164
933
  *
165
- * @returns {TableScope} The current scope of the table.
934
+ * This method is useful for advanced customization scenarios where you need direct access
935
+ * to the table's internal structure and behaviors.
936
+ *
937
+ * @returns {TableScope} The TableScope instance that controls this table component
938
+ *
939
+ * @example
940
+ * // Access the TableScope to perform a custom operation
941
+ * const tableApi = new TableApi(myTableScope);
942
+ * const tableScope = tableApi.getTableScope();
943
+ *
944
+ * // Example: Manually trigger a context menu at a specific location
945
+ * const mouseEvent = new MouseEvent('contextmenu');
946
+ * const geMouseEvent = tableScope.createGeMouseEvent(mouseEvent);
947
+ * tableScope.contextmenu(geMouseEvent);
166
948
  */
167
949
  getTableScope(): TableScope;
168
950
  /**
169
- * Retrieves the selection model of the table.
951
+ * Returns the current selection model for the table.
952
+ *
953
+ * The selection model manages cell selection state, including single cells, ranges, rows, and columns.
954
+ * This method provides access to the selection model instance, allowing operations like:
955
+ * - Checking if cells are selected
956
+ * - Getting selection ranges
957
+ * - Modifying selections
958
+ * - Adding/removing selection event listeners
959
+ *
960
+ * @returns {SelectionModelIf | undefined} The current selection model if available, otherwise undefined.
961
+ *
962
+ * @example
963
+ * // Get the selection model
964
+ * const selectionModel = tableApi.getSelectionModel();
170
965
  *
171
- * @return {SelectionModelIf | undefined} The selection model of the table,
172
- * or undefined if no selection model is available.
966
+ * // Check if a specific cell is selected
967
+ * if (selectionModel?.isSelected(3, 2)) {
968
+ * console.log('Cell at row 3, column 2 is selected');
969
+ * }
970
+ *
971
+ * // Get all selected ranges
972
+ * const ranges = selectionModel?.getRanges();
973
+ * console.log('Selected ranges:', ranges);
974
+ *
975
+ * // Clear all selections
976
+ * selectionModel?.clear();
977
+ *
978
+ * // Toggle selection of a cell
979
+ * selectionModel?.togglePoint(5, 1);
980
+ *
981
+ * // Add a selection change listener
982
+ * selectionModel?.addEventSelectionChangedListener({
983
+ * selectionChanged: () => {
984
+ * console.log('Selection has changed');
985
+ * }
986
+ * });
173
987
  */
174
988
  getSelectionModel(): SelectionModelIf | undefined;
175
989
  /**
@@ -578,9 +1392,172 @@ export declare class TableApi {
578
1392
  * ```
579
1393
  */
580
1394
  getFirstVisibleRowIndex(): number;
1395
+ /**
1396
+ * Retrieves the index of the first fully visible row in the table's viewport.
1397
+ *
1398
+ * A row is considered "fully visible" when it's completely within the visible area of the table.
1399
+ * This differs from the regular "visible" row, which might be partially visible at the edges of the viewport.
1400
+ *
1401
+ * This method is useful for:
1402
+ * - Determining which rows are completely in view for operations that require full visibility
1403
+ * - Implementing pagination or virtualization logic that needs to know complete row visibility
1404
+ * - Supporting keyboard navigation that should skip partially visible rows
1405
+ *
1406
+ * @returns {number} The index of the first fully visible row, or -1 if no rows are fully visible
1407
+ *
1408
+ * @example
1409
+ * // Get the first fully visible row index
1410
+ * const firstFullVisibleRow = tableApi.getFirstFullVisibleRowIndex();
1411
+ *
1412
+ * // Check if a specific row is fully visible
1413
+ * const isRowFullyVisible = (rowIndex) => {
1414
+ * const firstFullVisible = tableApi.getFirstFullVisibleRowIndex();
1415
+ * const lastFullVisible = tableApi.getLastFullVisibleRowIndex();
1416
+ * return rowIndex >= firstFullVisible && rowIndex <= lastFullVisible;
1417
+ * };
1418
+ */
581
1419
  getFirstFullVisibleRowIndex(): number;
1420
+ /**
1421
+ * Returns the index of the last row that is visible in the table's viewport.
1422
+ *
1423
+ * This method retrieves the last visible row index from the table scope, which keeps
1424
+ * track of which rows are currently visible as the user scrolls through the table.
1425
+ *
1426
+ * This can be useful for:
1427
+ * - Implementing virtualized scrolling optimizations
1428
+ * - Determining if specific rows are currently in view
1429
+ * - Implementing features that need to know the visible range of rows
1430
+ *
1431
+ * @returns {number} The index of the last visible row in the table viewport
1432
+ *
1433
+ * @example
1434
+ * // Check if a specific row is currently visible in the viewport
1435
+ * const lastVisibleIndex = tableApi.getLastVisibleRowIndex();
1436
+ * const firstVisibleIndex = tableApi.getFirstVisibleRowIndex();
1437
+ * const isRowVisible = rowIndex >= firstVisibleIndex && rowIndex <= lastVisibleIndex;
1438
+ *
1439
+ * @example
1440
+ * // Get the range of visible rows
1441
+ * const visibleRowsRange = {
1442
+ * first: tableApi.getFirstVisibleRowIndex(),
1443
+ * last: tableApi.getLastVisibleRowIndex()
1444
+ * };
1445
+ * console.log(`Visible rows: ${visibleRowsRange.first} to ${visibleRowsRange.last}`);
1446
+ */
582
1447
  getLastVisibleRowIndex(): number;
1448
+ /**
1449
+ * Returns the index of the last fully visible row in the table's viewport.
1450
+ *
1451
+ * This method retrieves the last row that is completely visible within the current
1452
+ * viewport of the table. A row is considered "fully visible" when its entire height
1453
+ * is visible without any portion being cut off by the viewport boundaries.
1454
+ *
1455
+ * The distinction between "visible" and "fully visible" is important when scrolling:
1456
+ * - A row can be partially visible (some portion is in view)
1457
+ * - A row can be fully visible (the entire row is in view)
1458
+ *
1459
+ * @returns {number} The index of the last fully visible row in the table.
1460
+ * If no row is fully visible or the table is empty, the method might return -1.
1461
+ *
1462
+ * @example
1463
+ * ```typescript
1464
+ * // Get the index of the last fully visible row
1465
+ * const lastVisibleRowIndex = tableApi.getLastFullVisibleRowIndex();
1466
+ *
1467
+ * // Use this information to determine if a specific row is fully visible
1468
+ * const isRowFullyVisible = rowIndex <= lastVisibleRowIndex && rowIndex >= tableApi.getFirstFullVisibleRowIndex();
1469
+ *
1470
+ * // Can be used with scrolling operations to ensure certain rows are visible
1471
+ * if (rowIndex > lastVisibleRowIndex) {
1472
+ * tableApi.ensureRowIsVisible(rowIndex);
1473
+ * }
1474
+ * ```
1475
+ */
583
1476
  getLastFullVisibleRowIndex(): number;
1477
+ /**
1478
+ * Checks whether logging is currently active for the table component.
1479
+ *
1480
+ * This method returns the current state of logging for the table. When logging is active,
1481
+ * the table outputs detailed information about its operations to the console, including:
1482
+ *
1483
+ * - Rendering processes and lifecycle events
1484
+ * - Data modifications and updates
1485
+ * - Event handling and user interactions
1486
+ * - Performance metrics and state changes
1487
+ *
1488
+ * Logging can be toggled using the `setLoggingActive(boolean)` method.
1489
+ *
1490
+ * @returns {boolean} True if logging is currently enabled, false otherwise.
1491
+ *
1492
+ * @example
1493
+ * // Check if logging is enabled
1494
+ * if (tableApi.isLoggingActive()) {
1495
+ * console.log("Table logging is currently active");
1496
+ * }
1497
+ *
1498
+ * // Conditionally enable logging only if it's not already active
1499
+ * if (!tableApi.isLoggingActive()) {
1500
+ * tableApi.setLoggingActive(true);
1501
+ *
1502
+ * // Perform operations that need debugging
1503
+ * tableApi.updateCells([
1504
+ * {
1505
+ * area: "body",
1506
+ * rowIndex: 2,
1507
+ * columnIndex: 3,
1508
+ * value: "New Value",
1509
+ * cssClasses: { "highlight": true }
1510
+ * }
1511
+ * ]);
1512
+ *
1513
+ * // Run some additional operations...
1514
+ *
1515
+ * // Disable logging when finished
1516
+ * tableApi.setLoggingActive(false);
1517
+ * }
1518
+ */
584
1519
  setLoggingActive(active: boolean): void;
1520
+ /**
1521
+ * Checks whether logging is currently active for the table component.
1522
+ *
1523
+ * This method returns the current state of logging for the table. When logging is active,
1524
+ * the table outputs detailed information about its operations to the console, including:
1525
+ *
1526
+ * - Rendering processes and lifecycle events
1527
+ * - Data modifications and updates
1528
+ * - Event handling and user interactions
1529
+ * - Performance metrics and state changes
1530
+ *
1531
+ * Logging can be toggled using the `setLoggingActive(boolean)` method.
1532
+ *
1533
+ * @returns {boolean} True if logging is currently enabled, false otherwise.
1534
+ *
1535
+ * @example
1536
+ * // Check if logging is enabled
1537
+ * if (tableApi.isLoggingActive()) {
1538
+ * console.log("Table logging is currently active");
1539
+ * }
1540
+ *
1541
+ * // Conditionally enable logging only if it's not already active
1542
+ * if (!tableApi.isLoggingActive()) {
1543
+ * tableApi.setLoggingActive(true);
1544
+ *
1545
+ * // Perform operations that need debugging
1546
+ * tableApi.updateCells([
1547
+ * {
1548
+ * area: "body",
1549
+ * rowIndex: 2,
1550
+ * columnIndex: 3,
1551
+ * value: "New Value",
1552
+ * cssClasses: { "highlight": true }
1553
+ * }
1554
+ * ]);
1555
+ *
1556
+ * // Run some additional operations...
1557
+ *
1558
+ * // Disable logging when finished
1559
+ * tableApi.setLoggingActive(false);
1560
+ * }
1561
+ */
585
1562
  isLoggingActive(): boolean;
586
1563
  }