@guiexpert/table 1.1.79 → 1.1.80

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.
@@ -5,160 +5,873 @@ import { FilterFunction } from "../../common/filter-function";
5
5
  import { SortItem } from "../../common/sort-item";
6
6
  import { AreaIdent } from "../area-ident.type";
7
7
  /**
8
- * This is the model interface for an area model. A table can have three of these models, one for the header,
9
- * one for the body , and one for the footer.
10
- * An AreaModelIf gives you information about the rows and cell contents.
11
- * The column information is given by the TableModelIf.
8
+ * @interface AreaModelIf
9
+ * @description
10
+ * The AreaModelIf interface represents a model for a specific area of a table (header, body, or footer).
11
+ * It provides methods for accessing and manipulating data within that area.
12
+ *
13
+ * In the GuiExpert Table library, a table is divided into three main areas:
14
+ * - Header: Contains column titles and optional filter/sort controls
15
+ * - Body: Contains the main data of the table
16
+ * - Footer: Contains summary information or additional controls
17
+ *
18
+ * Each of these areas can be further divided into three sections:
19
+ * - West: Fixed columns on the left side
20
+ * - Center: Scrollable columns in the middle
21
+ * - East: Fixed columns on the right side
22
+ *
23
+ * <pre>
24
+ * +----------------+-------------------+--------------+
25
+ * | header/west | header/center | header/east |
26
+ * +----------------+-------------------+--------------+
27
+ * | body/west | body/center | body/east |
28
+ * +----------------+-------------------+--------------+
29
+ * | footer/west | footer/center | footer/east |
30
+ * +----------------+-------------------+--------------+
31
+ * </pre>
32
+ *
33
+ * The AreaModelIf interface is a core component of the table's architecture. While simple tables might use
34
+ * basic data structures like arrays of arrays or arrays of objects, the GuiExpert Table library uses a more
35
+ * sophisticated model approach. An AreaModelIf implementation provides information about:
36
+ *
37
+ * - The number of rows in the area
38
+ * - The content of each cell
39
+ * - The styling of cells (CSS classes, custom styles)
40
+ * - Cell spanning (colspan, rowspan)
41
+ * - Row heights
42
+ * - Cell editability and selectability
43
+ * - Row selection state
44
+ * - Filtering and sorting capabilities
45
+ *
46
+ * This model-based approach provides maximum flexibility for creating complex, interactive tables.
47
+ *
48
+ * @example
49
+ * // Example of creating a simple table with header, body, and footer areas
50
+ * import { TableFactory, TableModelIf } from "@guiexpert/table";
51
+ *
52
+ * // Create data for each area
53
+ * const headerData = [["ID", "Name", "Age"]];
54
+ * const bodyData = [
55
+ * [1, "John", 30],
56
+ * [2, "Jane", 25],
57
+ * [3, "Bob", 40]
58
+ * ];
59
+ * const footerData = [["", "Average", 31.67]];
60
+ *
61
+ * // Create the table model with all three areas
62
+ * const tableModel: TableModelIf = TableFactory.createTableModel({
63
+ * headerData,
64
+ * bodyData,
65
+ * footerData
66
+ * });
67
+ *
68
+ * // Access the area models
69
+ * const headerModel = tableModel.getAreaModel("header");
70
+ * const bodyModel = tableModel.getAreaModel("body");
71
+ * const footerModel = tableModel.getAreaModel("footer");
72
+ *
73
+ * // Get information from the body model
74
+ * console.log(`Number of rows: ${bodyModel.getRowCount()}`);
75
+ * console.log(`Value at (1,1): ${bodyModel.getValueAt(1, 1)}`); // "Jane"
76
+ *
77
+ * @example
78
+ * // Example of creating a table with object data and column definitions
79
+ * import { TableFactory, TableModelIf, ColumnDefIf } from "@guiexpert/table";
80
+ *
81
+ * // Define the data as an array of objects
82
+ * const data = [
83
+ * { id: 1, name: "John", age: 30 },
84
+ * { id: 2, name: "Jane", age: 25 },
85
+ * { id: 3, name: "Bob", age: 40 }
86
+ * ];
87
+ *
88
+ * // Define column definitions
89
+ * const columnDefs: ColumnDefIf[] = [
90
+ * { property: "id", headerLabel: "ID", width: 80 },
91
+ * { property: "name", headerLabel: "Name", width: 150 },
92
+ * { property: "age", headerLabel: "Age", width: 80 }
93
+ * ];
94
+ *
95
+ * // Create the table model
96
+ * const tableModel: TableModelIf = TableFactory.createByObjectArray(
97
+ * data,
98
+ * [["ID", "Name", "Age"]], // header
99
+ * [], // footer (empty)
100
+ * 0, // fixedLeftColumnCount
101
+ * 0, // fixedRightColumnCount
102
+ * false, // rowCheckboxVisible
103
+ * undefined, // defaultRowHeights
104
+ * columnDefs
105
+ * );
106
+ *
107
+ * @example
108
+ * // Example of implementing a custom AreaModelIf
109
+ * import { AreaModelIf, AreaIdent, CellRendererIf } from "@guiexpert/table";
110
+ *
111
+ * class CustomAreaModel implements AreaModelIf {
112
+ * constructor(
113
+ * public areaIdent: AreaIdent,
114
+ * private data: any[][],
115
+ * private defaultRowHeight: number = 30
116
+ * ) {}
117
+ *
118
+ * getRowCount(): number {
119
+ * return this.data.length;
120
+ * }
121
+ *
122
+ * getValueAt(rowIndex: number, columnIndex: number): any {
123
+ * if (rowIndex < 0 || rowIndex >= this.data.length) return undefined;
124
+ * const row = this.data[rowIndex];
125
+ * if (columnIndex < 0 || columnIndex >= row.length) return undefined;
126
+ * return row[columnIndex];
127
+ * }
128
+ *
129
+ * getRowHeight(rowIndex: number): number {
130
+ * return this.defaultRowHeight;
131
+ * }
132
+ *
133
+ * // Implement other required methods...
134
+ * }
135
+ *
136
+ * @see {@link TableModelIf} - The parent interface that contains area models
137
+ * @see {@link AreaModel} - A base implementation of this interface
138
+ * @see {@link AbstractAreaModel} - An abstract implementation with common functionality
139
+ * @see {@link AreaModelObjectArray} - An implementation for object array data
12
140
  */
13
141
  export interface AreaModelIf {
14
142
  /**
15
143
  * The identifier for one of the areas: header, body, footer.
144
+ * This property determines which area of the table this model represents.
145
+ *
146
+ * @type {AreaIdent}
147
+ *
148
+ * @example
149
+ * // Creating an area model for the header
150
+ * const headerModel = new AreaModel("header");
151
+ *
152
+ * @example
153
+ * // Checking which area a model represents
154
+ * if (areaModel.areaIdent === "body") {
155
+ * // This is a body area model
156
+ * }
16
157
  */
17
158
  areaIdent: AreaIdent;
18
159
  /**
19
- * A model and controller for a row checkbox selection
160
+ * A model and controller for row checkbox selection.
161
+ * This property allows the area to support row selection via checkboxes.
162
+ *
163
+ * @type {CheckboxModelIf<any> | undefined}
164
+ *
165
+ * @example
166
+ * // Creating a checkbox model for row selection
167
+ * import { CheckboxModel } from "@guiexpert/table";
168
+ *
169
+ * const bodyModel = new AreaModel("body");
170
+ * bodyModel.rowSelectionModel = new CheckboxModel();
171
+ *
172
+ * // Later, check if a row is selected
173
+ * const isSelected = bodyModel.isRowChecked(5);
20
174
  */
21
175
  rowSelectionModel: CheckboxModelIf<any> | undefined;
22
176
  /**
23
- * Method for moving a column from position sourceColumnIndex to targetColumnIndex.
177
+ * Changes the order of columns by moving a column from one position to another.
178
+ * This method is called when the user drags a column to a new position.
179
+ *
180
+ * @param {number} sourceColumnIndex - The index of the column to move
181
+ * @param {number} targetColumnIndex - The index where the column should be moved to
182
+ * @returns {void}
183
+ *
184
+ * @example
185
+ * // Move the second column (index 1) to the fourth position (index 3)
186
+ * areaModel.changeColumnOrder(1, 3);
187
+ *
188
+ * @example
189
+ * // Implementation example
190
+ * changeColumnOrder(sourceColumnIndex: number, targetColumnIndex: number): void {
191
+ * // Move the column in the internal data structure
192
+ * this.arrayMove(this.columns, sourceColumnIndex, targetColumnIndex);
193
+ *
194
+ * // Update any dependent data structures
195
+ * this.arrayMove(this.cellRenderers, sourceColumnIndex, targetColumnIndex);
196
+ * }
24
197
  */
25
198
  changeColumnOrder(sourceColumnIndex: number, targetColumnIndex: number): void;
26
199
  /**
27
- * Method for changing a cell value.
200
+ * Sets the value of a cell at the specified row and column indices.
201
+ * This method is called when a cell is edited by the user or programmatically.
202
+ *
203
+ * @param {number} rowIndex - The index of the row containing the cell
204
+ * @param {number} columnIndex - The index of the column containing the cell
205
+ * @param {any} value - The new value to set
206
+ * @returns {boolean} - True if the value was successfully set, false otherwise
207
+ *
208
+ * @example
209
+ * // Set the value of a cell
210
+ * areaModel.setValue(1, 2, "New Value");
211
+ *
212
+ * @example
213
+ * // Implementation example for an object-based model
214
+ * setValue(rowIndex: number, columnIndex: number, value: any): boolean {
215
+ * const row = this.getRowByIndex(rowIndex);
216
+ * if (!row) return false;
217
+ *
218
+ * const property = this.columnDefs[columnIndex].property;
219
+ * row[property] = value;
220
+ * return true;
221
+ * }
28
222
  */
29
223
  setValue(rowIndex: number, columnIndex: number, value: any): boolean;
30
224
  /**
31
- * Internally used by TableModel.
225
+ * Initializes the area model.
226
+ * This method is called internally by the TableModel during initialization.
227
+ * It can be used to perform any necessary setup, such as calculating row positions.
228
+ *
229
+ * @returns {void}
230
+ *
231
+ * @example
232
+ * // Implementation example
233
+ * init(): void {
234
+ * // Calculate y-positions for all rows
235
+ * this.calculateYPositions();
236
+ *
237
+ * // Initialize any other internal state
238
+ * this.initialized = true;
239
+ * }
32
240
  */
33
241
  init(): void;
34
242
  /**
35
- * Returns the number of rows of the area
243
+ * Returns the number of rows in this area.
244
+ * This is a fundamental method that determines the vertical size of the area.
245
+ *
246
+ * @returns {number} The number of rows in the area
247
+ *
248
+ * @example
249
+ * // Get the number of rows in the body area
250
+ * const rowCount = bodyAreaModel.getRowCount();
251
+ * console.log(`The body has ${rowCount} rows`);
252
+ *
253
+ * @example
254
+ * // Implementation example for an array-based model
255
+ * getRowCount(): number {
256
+ * return this.data.length;
257
+ * }
36
258
  */
37
259
  getRowCount(): number;
38
260
  /**
39
- * Returns the value of the cell at position rowIndex/columnIndex.
261
+ * Returns the value of the cell at the specified row and column indices.
262
+ * This is one of the most important methods in the area model, as it provides
263
+ * the actual data to be displayed in each cell.
264
+ *
265
+ * @param {number} rowIndex - The index of the row
266
+ * @param {number} columnIndex - The index of the column
267
+ * @returns {any} The value at the specified cell
268
+ *
269
+ * @example
270
+ * // Get the value of a cell
271
+ * const value = bodyAreaModel.getValueAt(1, 2);
272
+ * console.log(`Cell (1,2) contains: ${value}`);
273
+ *
274
+ * @example
275
+ * // Implementation example for a 2D array model
276
+ * getValueAt(rowIndex: number, columnIndex: number): any {
277
+ * if (rowIndex < 0 || rowIndex >= this.data.length) return undefined;
278
+ * const row = this.data[rowIndex];
279
+ * if (columnIndex < 0 || columnIndex >= row.length) return undefined;
280
+ * return row[columnIndex];
281
+ * }
282
+ *
283
+ * @example
284
+ * // Implementation example for an object array model
285
+ * getValueAt(rowIndex: number, columnIndex: number): any {
286
+ * const row = this.getRowByIndex(rowIndex);
287
+ * if (!row) return undefined;
288
+ *
289
+ * const property = this.columnDefs[columnIndex].property;
290
+ * return row[property];
291
+ * }
40
292
  */
41
293
  getValueAt(rowIndex: number, columnIndex: number): any;
42
294
  /**
43
- * Returns a string value of the cell at position rowIndex/columnIndex.
44
- * This function will be called by 'export' or 'copy to clipboard'.
295
+ * Returns a string representation of the cell value at the specified row and column indices.
296
+ * This method is used when exporting the table data or copying to clipboard.
297
+ *
298
+ * @param {number} rowIndex - The index of the row
299
+ * @param {number} columnIndex - The index of the column
300
+ * @returns {string} The text value of the specified cell
301
+ *
302
+ * @example
303
+ * // Get the text value of a cell for export
304
+ * const textValue = bodyAreaModel.getTextValueAt(1, 2);
305
+ *
306
+ * @example
307
+ * // Implementation example
308
+ * getTextValueAt(rowIndex: number, columnIndex: number): string {
309
+ * const value = this.getValueAt(rowIndex, columnIndex);
310
+ *
311
+ * // Handle different data types appropriately
312
+ * if (value === null || value === undefined) return '';
313
+ * if (value instanceof Date) return value.toISOString();
314
+ * return String(value);
315
+ * }
45
316
  */
46
317
  getTextValueAt(rowIndex: number, columnIndex: number): string;
47
318
  /**
48
- * Returns the value of a colspan of the cell at position rowIndex/columnIndex.
49
- * A value below 2 is ignored.
319
+ * Returns the column span value for the cell at the specified row and column indices.
320
+ * A colspan value of N means the cell spans N columns horizontally.
321
+ * Values less than 2 are ignored (no spanning).
322
+ *
323
+ * @param {number} rowIndex - The index of the row
324
+ * @param {number} columnIndex - The index of the column
325
+ * @returns {number} The colspan value (number of columns the cell spans)
326
+ *
327
+ * @example
328
+ * // Check if a cell spans multiple columns
329
+ * const colspan = headerAreaModel.getColspanAt(0, 0);
330
+ * if (colspan > 1) {
331
+ * console.log(`This header cell spans ${colspan} columns`);
332
+ * }
333
+ *
334
+ * @example
335
+ * // Implementation example for a model with column spanning
336
+ * getColspanAt(rowIndex: number, columnIndex: number): number {
337
+ * // Special case: first row, first column spans 3 columns
338
+ * if (rowIndex === 0 && columnIndex === 0) return 3;
339
+ *
340
+ * // No spanning for other cells
341
+ * return 1;
342
+ * }
50
343
  */
51
344
  getColspanAt(rowIndex: number, columnIndex: number): number;
52
345
  /**
53
- * This return value is internally used to optimize the render performance.
54
- * Set this value to the lowest possible value. If the model has no colspan,
55
- * a value of 0 would be good. The dafault is 32. If your model has a colspan
56
- * cell greater 32, don't forget to increase this value.
346
+ * Returns the maximum colspan value that can occur in this area model.
347
+ * This value is used to optimize rendering performance.
348
+ *
349
+ * @returns {number} The maximum possible colspan value in this area
350
+ *
351
+ * @example
352
+ * // Get the maximum colspan for optimization
353
+ * const maxColspan = headerAreaModel.getMaxColspan();
354
+ *
355
+ * @example
356
+ * // Implementation example
357
+ * getMaxColspan(): number {
358
+ * // If the model has no colspans, return 0 for optimization
359
+ * return 0;
360
+ *
361
+ * // If the model has colspans, return the maximum possible value
362
+ * // return 3; // If some cells span up to 3 columns
363
+ * }
57
364
  */
58
365
  getMaxColspan(): number;
59
366
  /**
60
- * Returns the value of a rowspan of the cell at position rowIndex/columnIndex.
61
- * A value below 2 is ignored.
367
+ * Returns the row span value for the cell at the specified row and column indices.
368
+ * A rowspan value of N means the cell spans N rows vertically.
369
+ * Values less than 2 are ignored (no spanning).
370
+ *
371
+ * @param {number} rowIndex - The index of the row
372
+ * @param {number} columnIndex - The index of the column
373
+ * @returns {number} The rowspan value (number of rows the cell spans)
374
+ *
375
+ * @example
376
+ * // Check if a cell spans multiple rows
377
+ * const rowspan = bodyAreaModel.getRowspanAt(0, 0);
378
+ * if (rowspan > 1) {
379
+ * console.log(`This cell spans ${rowspan} rows`);
380
+ * }
381
+ *
382
+ * @example
383
+ * // Implementation example for a model with row spanning
384
+ * getRowspanAt(rowIndex: number, columnIndex: number): number {
385
+ * // Special case: first column spans 2 rows at the beginning
386
+ * if (columnIndex === 0 && rowIndex % 2 === 0) return 2;
387
+ *
388
+ * // No spanning for other cells
389
+ * return 1;
390
+ * }
62
391
  */
63
392
  getRowspanAt(rowIndex: number, columnIndex: number): number;
64
393
  /**
65
- * This return value is internally used to optimize the render performance.
66
- * Set this value to the lowest possible value. If the model has no rowspan,
67
- * a value of 0 would be good. The default is 32. If your model has a rowspan
68
- * cell greater 32, don't forget to increase this value.
394
+ * Returns the maximum rowspan value that can occur in this area model.
395
+ * This value is used to optimize rendering performance.
396
+ *
397
+ * @returns {number} The maximum possible rowspan value in this area
398
+ *
399
+ * @example
400
+ * // Get the maximum rowspan for optimization
401
+ * const maxRowspan = bodyAreaModel.getMaxRowspan();
402
+ *
403
+ * @example
404
+ * // Implementation example
405
+ * getMaxRowspan(): number {
406
+ * // If the model has no rowspans, return 0 for optimization
407
+ * return 0;
408
+ *
409
+ * // If the model has rowspans, return the maximum possible value
410
+ * // return 2; // If some cells span up to 2 rows
411
+ * }
69
412
  */
70
413
  getMaxRowspan(): number;
71
414
  /**
72
- * This method can be used to return a list of css classes for the given cell
73
- * @param rowIndex row index of the cell
74
- * @param columnIndex column index of the cell
415
+ * Returns an array of CSS class names to apply to the cell at the specified row and column indices.
416
+ * This method allows for custom styling of individual cells.
417
+ *
418
+ * @param {number} rowIndex - The index of the row
419
+ * @param {number} columnIndex - The index of the column
420
+ * @returns {string[]} An array of CSS class names
421
+ *
422
+ * @example
423
+ * // Apply custom classes to cells
424
+ * const classes = bodyAreaModel.getCustomClassesAt(1, 2);
425
+ * console.log(`Cell classes: ${classes.join(', ')}`);
426
+ *
427
+ * @example
428
+ * // Implementation example with conditional styling
429
+ * getCustomClassesAt(rowIndex: number, columnIndex: number): string[] {
430
+ * const classes: string[] = [];
431
+ *
432
+ * // Add classes based on row index
433
+ * if (rowIndex % 2 === 0) {
434
+ * classes.push('even-row');
435
+ * } else {
436
+ * classes.push('odd-row');
437
+ * }
438
+ *
439
+ * // Add classes based on cell value
440
+ * const value = this.getValueAt(rowIndex, columnIndex);
441
+ * if (typeof value === 'number' && value < 0) {
442
+ * classes.push('negative-value');
443
+ * }
444
+ *
445
+ * // Add classes for selected rows
446
+ * if (this.isRowChecked(rowIndex)) {
447
+ * classes.push('selected-row');
448
+ * }
449
+ *
450
+ * return classes;
451
+ * }
75
452
  */
76
453
  getCustomClassesAt(rowIndex: number, columnIndex: number): string[];
77
454
  /**
78
- * This method can be used to return an object with css style information for the given cell
79
- * @param rowIndex row index of the cell
80
- * @param columnIndex column index of the cell
455
+ * Returns an object containing CSS style properties to apply to the cell at the specified row and column indices.
456
+ * This method allows for inline styling of individual cells.
457
+ *
458
+ * @param {number} rowIndex - The index of the row
459
+ * @param {number} columnIndex - The index of the column
460
+ * @returns {{ [key: string]: string } | undefined} An object with CSS style properties, or undefined if no custom styles
461
+ *
462
+ * @example
463
+ * // Apply custom styles to cells
464
+ * const styles = bodyAreaModel.getCustomStyleAt(1, 2);
465
+ * console.log('Cell styles:', styles);
466
+ *
467
+ * @example
468
+ * // Implementation example with conditional styling
469
+ * getCustomStyleAt(rowIndex: number, columnIndex: number): { [key: string]: string } | undefined {
470
+ * // Apply background color based on value
471
+ * const value = this.getValueAt(rowIndex, columnIndex);
472
+ *
473
+ * if (typeof value === 'number') {
474
+ * // Color gradient based on value
475
+ * if (value < 0) {
476
+ * return { 'background-color': `rgba(255, 0, 0, ${Math.min(Math.abs(value) / 100, 0.5)})` };
477
+ * } else if (value > 0) {
478
+ * return { 'background-color': `rgba(0, 255, 0, ${Math.min(value / 100, 0.5)})` };
479
+ * }
480
+ * }
481
+ *
482
+ * return undefined; // No custom styles
483
+ * }
81
484
  */
82
485
  getCustomStyleAt(rowIndex: number, columnIndex: number): {
83
486
  [key: string]: string;
84
487
  } | undefined;
85
488
  /**
86
- * Returns the cell value of the given cell. This value will be rendered
87
- * directly in the cell or rendered by a cell renderer: see {@link getCellRenderer}.
88
- * @param rowIndex
89
- * @param columnIndex
90
- */
91
- getValueAt(rowIndex: number, columnIndex: number): any;
92
- /**
93
- * Returns the value of a tooltip of the given cell (rowIndex/columnIndex).
94
- * @param rowIndex
95
- * @param columnIndex
489
+ * Returns the tooltip text for the cell at the specified row and column indices.
490
+ * This tooltip will be displayed when the user hovers over the cell.
491
+ *
492
+ * @param {number} rowIndex - The index of the row
493
+ * @param {number} columnIndex - The index of the column
494
+ * @returns {any} The tooltip content (usually a string)
495
+ *
496
+ * @example
497
+ * // Get the tooltip for a cell
498
+ * const tooltip = bodyAreaModel.getTooltipAt(1, 2);
499
+ *
500
+ * @example
501
+ * // Implementation example
502
+ * getTooltipAt(rowIndex: number, columnIndex: number): any {
503
+ * // Use the cell value as the tooltip
504
+ * return this.getValueAt(rowIndex, columnIndex);
505
+ *
506
+ * // Or provide a more detailed tooltip
507
+ * // const value = this.getValueAt(rowIndex, columnIndex);
508
+ * // return `Value: ${value}\nRow: ${rowIndex}\nColumn: ${columnIndex}`;
509
+ * }
96
510
  */
97
511
  getTooltipAt(rowIndex: number, columnIndex: number): any;
98
512
  /**
99
- * Returns a cell renderer class for the given cell (rowIndex/columnIndex).
100
- * If the return value is undefined, no renderer is used and the model value will be rendered directly in the cell.
101
- * @param rowIndex
102
- * @param columnIndex
513
+ * Returns a cell renderer for the cell at the specified row and column indices.
514
+ * A cell renderer is responsible for rendering the cell content in a custom way.
515
+ * If undefined is returned, the cell value will be rendered directly.
516
+ *
517
+ * @param {number} rowIndex - The index of the row
518
+ * @param {number} columnIndex - The index of the column
519
+ * @returns {CellRendererIf | undefined} A cell renderer instance, or undefined for default rendering
520
+ *
521
+ * @example
522
+ * // Get a custom renderer for a cell
523
+ * const renderer = bodyAreaModel.getCellRenderer(1, 2);
524
+ *
525
+ * @example
526
+ * // Implementation example using column definitions
527
+ * getCellRenderer(rowIndex: number, columnIndex: number): CellRendererIf | undefined {
528
+ * // Get renderer from column definition
529
+ * const columnDef = this.columnDefs[columnIndex];
530
+ * return columnDef?.rendererMap?.[this.areaIdent];
531
+ * }
103
532
  */
104
533
  getCellRenderer(rowIndex: number, columnIndex: number): CellRendererIf | undefined;
105
534
  /**
106
- * Returns the row height in pixel of the given row (rowIndex).
107
- * @param rowIndex
535
+ * Returns the height of the row at the specified index, in pixels.
536
+ * This method allows for variable row heights in the table.
537
+ *
538
+ * @param {number} rowIndex - The index of the row
539
+ * @returns {number} The height of the row in pixels
540
+ *
541
+ * @example
542
+ * // Get the height of a row
543
+ * const height = bodyAreaModel.getRowHeight(1);
544
+ * console.log(`Row 1 height: ${height}px`);
545
+ *
546
+ * @example
547
+ * // Implementation example with fixed row height
548
+ * getRowHeight(rowIndex: number): number {
549
+ * return this.defaultRowHeight; // e.g., 30px
550
+ * }
551
+ *
552
+ * @example
553
+ * // Implementation example with variable row heights
554
+ * getRowHeight(rowIndex: number): number {
555
+ * // First row is taller
556
+ * if (rowIndex === 0) return 50;
557
+ *
558
+ * // Rows with more content are taller
559
+ * const row = this.getRowByIndex(rowIndex);
560
+ * if (row && row.hasLongContent) return 60;
561
+ *
562
+ * // Default height for other rows
563
+ * return 30;
564
+ * }
108
565
  */
109
566
  getRowHeight(rowIndex: number): number;
110
567
  /**
111
- * Returns the row of the model, which correspond to the rowIndex.
112
- * @param rowIndex
568
+ * Returns the row object at the specified index.
569
+ * This method provides access to the underlying data structure.
570
+ *
571
+ * @param {number} rowIndex - The index of the row
572
+ * @returns {any} The row object
573
+ *
574
+ * @example
575
+ * // Get a row object
576
+ * const row = bodyAreaModel.getRowByIndex(1);
577
+ * console.log('Row data:', row);
578
+ *
579
+ * @example
580
+ * // Implementation example for an array-based model
581
+ * getRowByIndex(rowIndex: number): any {
582
+ * if (rowIndex < 0 || rowIndex >= this.data.length) return undefined;
583
+ * return this.data[rowIndex];
584
+ * }
113
585
  */
114
586
  getRowByIndex(rowIndex: number): any;
115
587
  /**
116
- * Return the y-position in pixel of the top of the row on the scrollpane.
117
- * For big tables it can be a big value (greate than the height of the viewport).
118
- * @param rowIndex
588
+ * Returns the Y-coordinate (in pixels) of the top of the row at the specified index.
589
+ * This method is used for scrolling and positioning rows in the viewport.
590
+ *
591
+ * @param {number} rowIndex - The index of the row
592
+ * @returns {number} The Y-coordinate of the top of the row, in pixels
593
+ *
594
+ * @example
595
+ * // Get the Y-position of a row
596
+ * const yPos = bodyAreaModel.getYPosByRowIndex(10);
597
+ * console.log(`Row 10 starts at Y-position: ${yPos}px`);
598
+ *
599
+ * @example
600
+ * // Implementation example with fixed row heights
601
+ * getYPosByRowIndex(rowIndex: number): number {
602
+ * return rowIndex * this.defaultRowHeight;
603
+ * }
604
+ *
605
+ * @example
606
+ * // Implementation example with variable row heights
607
+ * getYPosByRowIndex(rowIndex: number): number {
608
+ * // Use a pre-calculated array of Y-positions
609
+ * return this.yPositions[rowIndex];
610
+ *
611
+ * // Or calculate on-the-fly
612
+ * // let yPos = 0;
613
+ * // for (let i = 0; i < rowIndex; i++) {
614
+ * // yPos += this.getRowHeight(i);
615
+ * // }
616
+ * // return yPos;
617
+ * }
119
618
  */
120
619
  getYPosByRowIndex(rowIndex: number): number;
121
620
  /**
122
- * If this method returns true, the cell can be edited by the user.
123
- * @param rowIndex
124
- * @param columnIndex
621
+ * Determines whether the cell at the specified row and column indices is editable.
622
+ * If true, the user can edit the cell content.
623
+ *
624
+ * @param {number} rowIndex - The index of the row
625
+ * @param {number} columnIndex - The index of the column
626
+ * @returns {boolean} True if the cell is editable, false otherwise
627
+ *
628
+ * @example
629
+ * // Check if a cell is editable
630
+ * const editable = bodyAreaModel.isEditable(1, 2);
631
+ * if (editable) {
632
+ * console.log('This cell can be edited by the user');
633
+ * }
634
+ *
635
+ * @example
636
+ * // Implementation example using column definitions
637
+ * isEditable(rowIndex: number, columnIndex: number): boolean {
638
+ * // Get editability from column definition
639
+ * const columnDef = this.columnDefs[columnIndex];
640
+ * return columnDef?.editable?.() ?? false;
641
+ * }
642
+ *
643
+ * @example
644
+ * // Implementation example with conditional editability
645
+ * isEditable(rowIndex: number, columnIndex: number): boolean {
646
+ * // Header cells are not editable
647
+ * if (this.areaIdent === 'header') return false;
648
+ *
649
+ * // First column is not editable (e.g., ID column)
650
+ * if (columnIndex === 0) return false;
651
+ *
652
+ * // Other cells in the body are editable
653
+ * return this.areaIdent === 'body';
654
+ * }
125
655
  */
126
656
  isEditable(rowIndex: number, columnIndex: number): boolean;
127
657
  /**
128
- * If true, the cell is selectable.
129
- * @param rowIndex
130
- * @param columnIndex
658
+ * Determines whether the cell at the specified row and column indices is selectable.
659
+ * If true, the user can select the cell.
660
+ *
661
+ * @param {number} rowIndex - The index of the row
662
+ * @param {number} columnIndex - The index of the column
663
+ * @returns {boolean} True if the cell is selectable, false otherwise
664
+ *
665
+ * @example
666
+ * // Check if a cell is selectable
667
+ * const selectable = bodyAreaModel.isSelectable(1, 2);
668
+ * if (selectable) {
669
+ * console.log('This cell can be selected by the user');
670
+ * }
671
+ *
672
+ * @example
673
+ * // Implementation example
674
+ * isSelectable(rowIndex: number, columnIndex: number): boolean {
675
+ * // All cells are selectable by default
676
+ * return true;
677
+ *
678
+ * // Or implement custom logic
679
+ * // return this.areaIdent === 'body'; // Only body cells are selectable
680
+ * }
131
681
  */
132
682
  isSelectable(rowIndex: number, columnIndex: number): boolean;
133
683
  /**
134
- * If true, the row is checkable and a checkbox is rendered at the beginning of the row.
135
- * @param rowIndex
684
+ * Determines whether the row at the specified index is checkable.
685
+ * If true, a checkbox will be rendered at the beginning of the row.
686
+ *
687
+ * @param {number} rowIndex - The index of the row
688
+ * @returns {boolean} True if the row is checkable, false otherwise
689
+ *
690
+ * @example
691
+ * // Check if a row is checkable
692
+ * const checkable = bodyAreaModel.isRowCheckable(1);
693
+ * if (checkable) {
694
+ * console.log('This row can be checked by the user');
695
+ * }
696
+ *
697
+ * @example
698
+ * // Implementation example
699
+ * isRowCheckable(rowIndex: number): boolean {
700
+ * // All rows are checkable by default
701
+ * return true;
702
+ *
703
+ * // Or implement custom logic
704
+ * // const row = this.getRowByIndex(rowIndex);
705
+ * // return row && !row.locked; // Only unlocked rows are checkable
706
+ * }
136
707
  */
137
708
  isRowCheckable(rowIndex: number): boolean;
138
709
  /**
139
- * Returns the checked state of an row.
140
- * @param rowIndex
710
+ * Returns the checked state of the row at the specified index.
711
+ *
712
+ * @param {number} rowIndex - The index of the row
713
+ * @returns {CheckedType | undefined} The checked state of the row (true, false, or 'indeterminate'),
714
+ * or undefined if the row is not checkable
715
+ *
716
+ * @example
717
+ * // Check if a row is checked
718
+ * const checkedState = bodyAreaModel.isRowChecked(1);
719
+ * if (checkedState === true) {
720
+ * console.log('This row is checked');
721
+ * } else if (checkedState === 'indeterminate') {
722
+ * console.log('This row is partially checked');
723
+ * }
724
+ *
725
+ * @example
726
+ * // Implementation example using a row selection model
727
+ * isRowChecked(rowIndex: number): CheckedType | undefined {
728
+ * if (!this.rowSelectionModel) return undefined;
729
+ *
730
+ * const row = this.getRowByIndex(rowIndex);
731
+ * return this.rowSelectionModel.isRowChecked(row);
732
+ * }
141
733
  */
142
734
  isRowChecked(rowIndex: number): CheckedType | undefined;
143
735
  /**
144
- * Set the checked state of the row (rowIndex) to #checked.
145
- * @param rowIndex
146
- * @param checked
736
+ * Sets the checked state of the row at the specified index.
737
+ *
738
+ * @param {number} rowIndex - The index of the row
739
+ * @param {boolean} checked - The new checked state
740
+ * @returns {void}
741
+ *
742
+ * @example
743
+ * // Check a row
744
+ * bodyAreaModel.setRowChecked(1, true);
745
+ *
746
+ * // Uncheck a row
747
+ * bodyAreaModel.setRowChecked(2, false);
748
+ *
749
+ * @example
750
+ * // Implementation example using a row selection model
751
+ * setRowChecked(rowIndex: number, checked: boolean): void {
752
+ * if (!this.rowSelectionModel) return;
753
+ *
754
+ * const row = this.getRowByIndex(rowIndex);
755
+ * if (row) {
756
+ * this.rowSelectionModel.checkRow(row, checked);
757
+ * }
758
+ * }
147
759
  */
148
760
  setRowChecked(rowIndex: number, checked: boolean): void;
149
761
  /**
150
- * If true, the table is filterable. Rows can be filtered with help of {@link #externalFilterChanged()}
762
+ * Determines whether this area supports filtering.
763
+ * If true, the area can be filtered using the externalFilterChanged method.
764
+ *
765
+ * @returns {boolean} True if the area is filterable, false otherwise
766
+ *
767
+ * @example
768
+ * // Check if an area is filterable
769
+ * const filterable = bodyAreaModel.isFilterable();
770
+ * if (filterable) {
771
+ * console.log('This area supports filtering');
772
+ * }
773
+ *
774
+ * @example
775
+ * // Implementation example
776
+ * isFilterable(): boolean {
777
+ * // Only the body area is filterable
778
+ * return this.areaIdent === 'body';
779
+ * }
151
780
  */
152
781
  isFilterable(): boolean;
153
782
  /**
154
- * Will be called internally, when a filtering is trigger.
155
- * @param predictFn Defines, what row are invisible or visible after filtering.
783
+ * Applies a filter function to the rows in this area.
784
+ * This method is called when a filter is applied to the table.
785
+ *
786
+ * @param {FilterFunction<T>} predictFn - A function that takes a row and returns true if the row should be visible
787
+ * @returns {void}
788
+ *
789
+ * @example
790
+ * // Filter rows where age > 30
791
+ * bodyAreaModel.externalFilterChanged(row => row.age > 30);
792
+ *
793
+ * // Clear all filters
794
+ * bodyAreaModel.externalFilterChanged(() => true);
795
+ *
796
+ * @example
797
+ * // Implementation example
798
+ * externalFilterChanged<T>(predictFn: FilterFunction<T>): void {
799
+ * // Apply the filter to the rows
800
+ * this.filteredRows = this.rows.filter(predictFn);
801
+ * }
156
802
  */
157
803
  externalFilterChanged<T>(predictFn: FilterFunction<T>): void;
158
804
  /**
159
- * If the 'restore sort' option is set (see), this method will be triggered automatically by the table,
160
- * @param sortItems
805
+ * Sorts the rows in this area based on the provided sort items.
806
+ * This method is called when the user clicks on a sortable column header.
807
+ *
808
+ * @param {SortItem[]} sortItems - An array of sort items, each containing a column index and sort direction
809
+ * @returns {boolean} True if sorting was performed, false otherwise
810
+ *
811
+ * @example
812
+ * // Sort by the second column in ascending order
813
+ * bodyAreaModel.doSort([{ columnIndex: 1, sortState: 'asc' }]);
814
+ *
815
+ * // Sort by the first column in descending order, then by the second column in ascending order
816
+ * bodyAreaModel.doSort([
817
+ * { columnIndex: 0, sortState: 'desc' },
818
+ * { columnIndex: 1, sortState: 'asc' }
819
+ * ]);
820
+ *
821
+ * @example
822
+ * // Implementation example
823
+ * doSort(sortItems: SortItem[]): boolean {
824
+ * if (!sortItems.length) return false;
825
+ *
826
+ * // Apply sorting to the rows
827
+ * for (const sortItem of sortItems) {
828
+ * const { columnIndex, sortState } = sortItem;
829
+ * const property = this.columnDefs[columnIndex].property;
830
+ * const direction = sortState === 'asc' ? 1 : -1;
831
+ *
832
+ * this.rows.sort((a, b) => {
833
+ * const valueA = a[property];
834
+ * const valueB = b[property];
835
+ *
836
+ * if (valueA < valueB) return -1 * direction;
837
+ * if (valueA > valueB) return 1 * direction;
838
+ * return 0;
839
+ * });
840
+ * }
841
+ *
842
+ * return true;
843
+ * }
161
844
  */
162
845
  doSort(sortItems: SortItem[]): boolean;
846
+ /**
847
+ * Sorts the rows in this area using a custom comparator function.
848
+ * This method provides more flexibility than doSort for complex sorting logic.
849
+ *
850
+ * @param {(a: any, b: any) => number} [compareFn] - A function that compares two rows and returns a number:
851
+ * - Negative if a should come before b
852
+ * - Positive if a should come after b
853
+ * - Zero if they are equivalent for sorting purposes
854
+ * @returns {void}
855
+ *
856
+ * @example
857
+ * // Sort rows by name length
858
+ * bodyAreaModel.sort((a, b) => a.name.length - b.name.length);
859
+ *
860
+ * // Sort rows by a computed value
861
+ * bodyAreaModel.sort((a, b) => {
862
+ * const scoreA = a.wins * 3 + a.draws;
863
+ * const scoreB = b.wins * 3 + b.draws;
864
+ * return scoreB - scoreA; // Descending order
865
+ * });
866
+ *
867
+ * @example
868
+ * // Implementation example
869
+ * sort(compareFn?: (a: any, b: any) => number): void {
870
+ * if (!compareFn) return;
871
+ *
872
+ * // Apply the custom sort function
873
+ * this.rows.sort(compareFn);
874
+ * }
875
+ */
163
876
  sort(compareFn?: (a: any, b: any) => number): void;
164
877
  }