@guiexpert/solid-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.
Files changed (2) hide show
  1. package/index.js +1013 -41
  2. package/package.json +5 -3
package/index.js CHANGED
@@ -998,28 +998,128 @@ class st {
998
998
  }
999
999
  }
1000
1000
  class L extends tt {
1001
+ /**
1002
+ * Creates an instance of AreaModelObjectArray.
1003
+ *
1004
+ * @param {AreaIdent} areaIdent - Identifies which area of the table this model represents ('header', 'body', or 'footer')
1005
+ * @param {T[]} rows - The array of objects that represent the rows in this area
1006
+ * @param {number} defaultRowHeight - The default height for rows in this area (in pixels)
1007
+ * @param {ColumnDefIf[]} [columnDefs=[]] - Definitions for the columns in this area
1008
+ * @param {string} [selectedRowClass='ge-selected-row'] - CSS class to apply to selected rows
1009
+ * @param {string} [focusedRowClass='ge-focused-row'] - CSS class to apply to the focused row
1010
+ *
1011
+ * @example
1012
+ * const rows = [
1013
+ * { id: 1, name: 'John', age: 30 },
1014
+ * { id: 2, name: 'Jane', age: 25 }
1015
+ * ];
1016
+ *
1017
+ * const columnDefs = [
1018
+ * { property: 'id', headerLabel: 'ID', width: 50 },
1019
+ * { property: 'name', headerLabel: 'Name', width: 150 },
1020
+ * { property: 'age', headerLabel: 'Age', width: 100 }
1021
+ * ];
1022
+ *
1023
+ * const bodyAreaModel = new AreaModelObjectArray(
1024
+ * 'body',
1025
+ * rows,
1026
+ * 30,
1027
+ * columnDefs
1028
+ * );
1029
+ */
1001
1030
  constructor(e, t, s, o = [], i = "ge-selected-row", r = "ge-focused-row") {
1002
1031
  super(e, o, s), this.areaIdent = e, this.rows = t, this.defaultRowHeight = s, this.columnDefs = o, this.selectedRowClass = i, this.focusedRowClass = r, this.sorterService = new st(), this._focusedRowIndex = 0, this.filteredRows = [...t], this.properties = o.map((a) => a.property);
1003
1032
  }
1033
+ /**
1034
+ * Gets the index of the currently focused row.
1035
+ *
1036
+ * @returns {number} The index of the focused row
1037
+ *
1038
+ * @example
1039
+ * const focusedRowIndex = bodyAreaModel.getFocusedRowIndex();
1040
+ * console.log(`The focused row is at index ${focusedRowIndex}`);
1041
+ */
1004
1042
  getFocusedRowIndex() {
1005
1043
  return this._focusedRowIndex;
1006
1044
  }
1045
+ /**
1046
+ * Sets the index of the focused row.
1047
+ * This will apply the focused row styling to the specified row.
1048
+ *
1049
+ * @param {number} value - The index of the row to focus
1050
+ *
1051
+ * @example
1052
+ * // Focus the second row (index 1)
1053
+ * bodyAreaModel.setFocusedRowIndex(1);
1054
+ */
1007
1055
  setFocusedRowIndex(e) {
1008
1056
  this._focusedRowIndex = e;
1009
1057
  }
1058
+ /**
1059
+ * Replaces the current rows array with a new one.
1060
+ * This also resets the filtered rows to match the new rows array.
1061
+ *
1062
+ * @param {T[]} rows - The new array of row objects
1063
+ *
1064
+ * @example
1065
+ * // Replace the current rows with new data
1066
+ * const newRows = [
1067
+ * { id: 4, name: 'Alice', age: 35 },
1068
+ * { id: 5, name: 'Charlie', age: 45 }
1069
+ * ];
1070
+ * bodyAreaModel.setRows(newRows);
1071
+ */
1010
1072
  setRows(e) {
1011
1073
  this.rows = e, this.filteredRows = [...e];
1012
1074
  }
1075
+ /**
1076
+ * Filters both the original rows and filtered rows arrays using the provided predicate function.
1077
+ * Unlike `externalFilterChanged`, this method permanently modifies the original rows array.
1078
+ *
1079
+ * @param {(row: T) => boolean} predict - A function that returns true for rows to keep and false for rows to filter out
1080
+ *
1081
+ * @example
1082
+ * // Remove all rows where age is less than 30
1083
+ * bodyAreaModel.filterRowsByPredict(row => row.age >= 30);
1084
+ */
1013
1085
  filterRowsByPredict(e) {
1014
1086
  this.rows = this.rows.filter(e), this.filteredRows = this.filteredRows.filter(e);
1015
1087
  }
1016
1088
  /**
1017
- * return row count of filtered rows
1089
+ * Returns the number of rows in the filtered rows array.
1090
+ * This is used to determine how many rows should be rendered in the table.
1091
+ *
1092
+ * @returns {number} The number of rows in the filtered rows array
1093
+ *
1094
+ * @example
1095
+ * const rowCount = bodyAreaModel.getRowCount();
1096
+ * console.log(`The table has ${rowCount} rows`);
1018
1097
  */
1019
1098
  getRowCount() {
1020
1099
  var e;
1021
1100
  return ((e = this.filteredRows) == null ? void 0 : e.length) ?? 0;
1022
1101
  }
1102
+ /**
1103
+ * Gets the value at the specified row and column indices.
1104
+ * This method handles tree rows and nested properties.
1105
+ *
1106
+ * @param {number} rowIndex - The index of the row
1107
+ * @param {number} columnIndex - The index of the column
1108
+ * @returns {any} The value at the specified cell, or an empty string if not found
1109
+ *
1110
+ * @example
1111
+ * // Get the value in the first row, second column
1112
+ * const value = bodyAreaModel.getValueAt(0, 1);
1113
+ * console.log(`The value is: ${value}`);
1114
+ *
1115
+ * @example
1116
+ * // Iterate through all cells in a row
1117
+ * const rowIndex = 0;
1118
+ * for (let colIndex = 0; colIndex < columnDefs.length; colIndex++) {
1119
+ * const value = bodyAreaModel.getValueAt(rowIndex, colIndex);
1120
+ * console.log(`Cell (${rowIndex}, ${colIndex}): ${value}`);
1121
+ * }
1122
+ */
1023
1123
  getValueAt(e, t) {
1024
1124
  const s = this.properties[t];
1025
1125
  let o = this.filteredRows[e];
@@ -1028,46 +1128,176 @@ class L extends tt {
1028
1128
  /**
1029
1129
  * Retrieves the filtered and sorted rows from the dataset.
1030
1130
  * These rows are used for rendering the table.
1131
+ * Unlike `getAllRows()`, this method returns only the rows that match any applied filters.
1031
1132
  *
1032
- * @return {T[]} An array containing the filtered (and sorted) rows.
1133
+ * @returns {T[]} An array containing the filtered (and sorted) rows
1134
+ *
1135
+ * @example
1136
+ * // Get all filtered rows
1137
+ * const filteredRows = bodyAreaModel.getFilteredRows();
1138
+ *
1139
+ * // Count rows that match a certain condition
1140
+ * const adultsCount = filteredRows.filter(row => row.age >= 18).length;
1033
1141
  */
1034
1142
  getFilteredRows() {
1035
1143
  return this.filteredRows;
1036
1144
  }
1145
+ /**
1146
+ * Returns the original, unfiltered array of rows.
1147
+ * This can be useful when you need to access all data regardless of any applied filters.
1148
+ *
1149
+ * @returns {T[]} The original array of row objects
1150
+ *
1151
+ * @example
1152
+ * // Get all rows, including those filtered out
1153
+ * const allRows = bodyAreaModel.getAllRows();
1154
+ *
1155
+ * // Calculate average age across all rows
1156
+ * const totalAge = allRows.reduce((sum, row) => sum + row.age, 0);
1157
+ * const averageAge = totalAge / allRows.length;
1158
+ */
1037
1159
  getAllRows() {
1038
1160
  return this.rows;
1039
1161
  }
1040
1162
  /**
1041
1163
  * Returns the first row from the filtered rows that matches the given criteria based on the provided predicate function.
1164
+ * This method only searches within the filtered rows, not the original rows array.
1042
1165
  *
1043
1166
  * @param {Partial<T>} criteria - A partial object containing the search criteria
1044
1167
  * @param {(criteria: Partial<T>, row: T) => boolean} predicate - A function that takes the search criteria and a row,
1045
1168
  * and returns true if the row matches the criteria
1046
1169
  * @returns {T | undefined} The first matching row, or undefined if no match is found
1170
+ *
1171
+ * @example
1172
+ * // Find a user by name in the filtered rows
1173
+ * const criteria = { name: 'John' };
1174
+ * const user = bodyAreaModel.findRowFromFilteredRowsByAllCriteria(
1175
+ * criteria,
1176
+ * (criteria, row) => row.name === criteria.name
1177
+ * );
1178
+ *
1179
+ * @example
1180
+ * // Find a user by age range in the filtered rows
1181
+ * const criteria = { minAge: 25, maxAge: 35 };
1182
+ * const user = bodyAreaModel.findRowFromFilteredRowsByAllCriteria(
1183
+ * criteria,
1184
+ * (criteria, row) => row.age >= criteria.minAge && row.age <= criteria.maxAge
1185
+ * );
1047
1186
  */
1048
1187
  findRowFromFilteredRowsByAllCriteria(e, t) {
1049
1188
  return this.getFilteredRows().find((s) => t(e, s));
1050
1189
  }
1051
1190
  /**
1052
1191
  * Searches through all rows to find a row that matches the given criteria based on the predicate function.
1192
+ * This method searches within the original rows array, including rows that may have been filtered out.
1053
1193
  *
1054
1194
  * @param {Partial<T>} criteria - A partial object containing the search criteria
1055
1195
  * @param {(criteria: Partial<T>, row: T) => boolean} predicate - A function that takes the search criteria and a row,
1056
1196
  * and returns true if the row matches the criteria
1057
1197
  * @returns {T | undefined} The first matching row from all rows, or undefined if no match is found
1198
+ *
1199
+ * @example
1200
+ * // Find a user by ID in all rows
1201
+ * const criteria = { id: 42 };
1202
+ * const user = bodyAreaModel.findRowFromAllRowsByAllCriteria(
1203
+ * criteria,
1204
+ * (criteria, row) => row.id === criteria.id
1205
+ * );
1206
+ *
1207
+ * @example
1208
+ * // Find a user with a specific property value in all rows
1209
+ * const criteria = { department: 'Engineering', role: 'Manager' };
1210
+ * const user = bodyAreaModel.findRowFromAllRowsByAllCriteria(
1211
+ * criteria,
1212
+ * (criteria, row) => row.department === criteria.department && row.role === criteria.role
1213
+ * );
1058
1214
  */
1059
1215
  findRowFromAllRowsByAllCriteria(e, t) {
1060
1216
  return this.getAllRows().find((s) => t(e, s));
1061
1217
  }
1218
+ /**
1219
+ * Returns the height of the row at the specified index.
1220
+ * This implementation always returns the default row height.
1221
+ * Override this method in subclasses to support variable row heights.
1222
+ *
1223
+ * @param {number} _rowIndex - The index of the row (unused in this implementation)
1224
+ * @returns {number} The height of the row in pixels
1225
+ *
1226
+ * @example
1227
+ * const rowHeight = bodyAreaModel.getRowHeight(0);
1228
+ * console.log(`The first row has a height of ${rowHeight}px`);
1229
+ */
1062
1230
  getRowHeight(e) {
1063
1231
  return this.defaultRowHeight;
1064
1232
  }
1233
+ /**
1234
+ * Returns the row object at the specified index from the filtered rows array.
1235
+ * This method overrides the parent class implementation.
1236
+ *
1237
+ * @param {number} rowIndex - The index of the row to retrieve
1238
+ * @returns {any} The row object at the specified index, or undefined if the index is out of bounds
1239
+ *
1240
+ * @example
1241
+ * // Get the first row object
1242
+ * const row = bodyAreaModel.getRowByIndex(0);
1243
+ * console.log('First row:', row);
1244
+ *
1245
+ * @example
1246
+ * // Iterate through all rows
1247
+ * for (let i = 0; i < bodyAreaModel.getRowCount(); i++) {
1248
+ * const row = bodyAreaModel.getRowByIndex(i);
1249
+ * console.log(`Row ${i}:`, row);
1250
+ * }
1251
+ */
1065
1252
  getRowByIndex(e) {
1066
1253
  return this.filteredRows[e];
1067
1254
  }
1255
+ /**
1256
+ * Applies an external filter function to the rows array.
1257
+ * This method updates the filtered rows array without modifying the original rows array.
1258
+ *
1259
+ * @param {FilterFunction<any>} predictFn - A function that returns true for rows to keep and false for rows to filter out
1260
+ *
1261
+ * @example
1262
+ * // Filter rows where age is greater than 30
1263
+ * bodyAreaModel.externalFilterChanged(row => row.age > 30);
1264
+ *
1265
+ * @example
1266
+ * // Filter rows based on a search term
1267
+ * const searchTerm = 'john';
1268
+ * bodyAreaModel.externalFilterChanged(row =>
1269
+ * row.name.toLowerCase().includes(searchTerm.toLowerCase())
1270
+ * );
1271
+ *
1272
+ * @example
1273
+ * // Clear all filters
1274
+ * bodyAreaModel.externalFilterChanged(() => true);
1275
+ */
1068
1276
  externalFilterChanged(e) {
1069
1277
  this.filteredRows = this.rows ? this.rows.filter(e) : [];
1070
1278
  }
1279
+ /**
1280
+ * Sorts the filtered rows based on the provided sort items.
1281
+ * This method supports sorting by multiple columns with different sort directions.
1282
+ *
1283
+ * @param {SortItem[]} sortItems - An array of sort items, each containing a column index and sort state
1284
+ * @returns {boolean} Always returns true to indicate sorting was performed
1285
+ *
1286
+ * @example
1287
+ * // Sort by age in ascending order
1288
+ * bodyAreaModel.doSort([{ columnIndex: 2, sortState: 'asc' }]);
1289
+ *
1290
+ * @example
1291
+ * // Sort by name in descending order, then by age in ascending order
1292
+ * bodyAreaModel.doSort([
1293
+ * { columnIndex: 1, sortState: 'desc' },
1294
+ * { columnIndex: 2, sortState: 'asc' }
1295
+ * ]);
1296
+ *
1297
+ * @example
1298
+ * // Clear sorting
1299
+ * bodyAreaModel.doSort([{ columnIndex: 0, sortState: 'none' }]);
1300
+ */
1071
1301
  doSort(e) {
1072
1302
  for (const t of e) {
1073
1303
  const { columnIndex: s, sortState: o } = t, i = o === "asc" ? 1 : o === "desc" ? -1 : 0, r = this.properties[s];
@@ -1075,20 +1305,110 @@ class L extends tt {
1075
1305
  }
1076
1306
  return !0;
1077
1307
  }
1308
+ /**
1309
+ * Sorts the filtered rows using a custom comparator function.
1310
+ * This method provides more flexibility than `doSort()` for complex sorting logic.
1311
+ *
1312
+ * @param {(a: T, b: T) => number} compareFn - A function that compares two rows and returns a number:
1313
+ * - Negative if a should come before b
1314
+ * - Positive if a should come after b
1315
+ * - Zero if they are equivalent for sorting purposes
1316
+ *
1317
+ * @example
1318
+ * // Sort by name length
1319
+ * bodyAreaModel.sort((a, b) => a.name.length - b.name.length);
1320
+ *
1321
+ * @example
1322
+ * // Sort by a computed value
1323
+ * bodyAreaModel.sort((a, b) => {
1324
+ * const scoreA = a.wins * 3 + a.draws;
1325
+ * const scoreB = b.wins * 3 + b.draws;
1326
+ * return scoreB - scoreA; // Descending order
1327
+ * });
1328
+ */
1078
1329
  sort(e) {
1079
1330
  this.filteredRows = this.filteredRows.sort(e);
1080
1331
  }
1332
+ /**
1333
+ * Gets a value from an object using a property path.
1334
+ * This method supports accessing nested properties using dot notation (e.g., 'person.name').
1335
+ *
1336
+ * @param {T} t - The object to get the value from
1337
+ * @param {string} property - The property path to access (e.g., 'name' or 'person.contact.email')
1338
+ * @returns {any} The value at the specified property path, or undefined if not found
1339
+ *
1340
+ * @example
1341
+ * const user = { id: 1, name: 'John', contact: { email: 'john@example.com' } };
1342
+ *
1343
+ * // Access simple property
1344
+ * const name = bodyAreaModel.getValueByT(user, 'name');
1345
+ * console.log(name); // 'John'
1346
+ *
1347
+ * // Access nested property
1348
+ * const email = bodyAreaModel.getValueByT(user, 'contact.email');
1349
+ * console.log(email); // 'john@example.com'
1350
+ */
1081
1351
  getValueByT(e, t) {
1082
1352
  if (e && t)
1083
1353
  return t.includes(".") ? this.getPropertyValue(e, t.split(".")) : e[t];
1084
1354
  }
1355
+ /**
1356
+ * Changes the order of columns by moving a column from one position to another.
1357
+ * This method updates both the properties array and calls the parent class implementation.
1358
+ *
1359
+ * @param {number} sourceColumnIndex - The index of the column to move
1360
+ * @param {number} targetColumnIndex - The index where the column should be moved to
1361
+ *
1362
+ * @example
1363
+ * // Move the second column (index 1) to the fourth position (index 3)
1364
+ * bodyAreaModel.changeColumnOrder(1, 3);
1365
+ *
1366
+ * @example
1367
+ * // Move the last column to the first position
1368
+ * const lastIndex = bodyAreaModel.columnDefs.length - 1;
1369
+ * bodyAreaModel.changeColumnOrder(lastIndex, 0);
1370
+ */
1085
1371
  changeColumnOrder(e, t) {
1086
1372
  this.arrayMove(this.properties, e, t), super.changeColumnOrder(e, t);
1087
1373
  }
1374
+ /**
1375
+ * Gets the custom CSS classes that should be applied to a cell.
1376
+ * This method extends the parent class implementation to add selection and focus classes.
1377
+ *
1378
+ * @param {number} rowIndex - The index of the row
1379
+ * @param {number} _columnIndex - The index of the column (unused in this implementation)
1380
+ * @returns {string[]} An array of CSS class names to apply to the cell
1381
+ *
1382
+ * @example
1383
+ * // Get the CSS classes for a cell
1384
+ * const classes = bodyAreaModel.getCustomClassesAt(1, 2);
1385
+ * console.log('CSS classes:', classes);
1386
+ *
1387
+ * @example
1388
+ * // Apply the classes to a cell element
1389
+ * const cellElement = document.createElement('div');
1390
+ * const classes = bodyAreaModel.getCustomClassesAt(rowIndex, columnIndex);
1391
+ * cellElement.classList.add(...classes);
1392
+ */
1088
1393
  getCustomClassesAt(e, t) {
1089
1394
  const s = super.getCustomClassesAt(e, t);
1090
1395
  return this.getRowByIndex(e).selected && s.push(this.selectedRowClass), this._focusedRowIndex === e && s.push(this.focusedRowClass), s;
1091
1396
  }
1397
+ /**
1398
+ * Creates a comparator function for sorting rows based on a property and sort direction.
1399
+ * This method supports custom sort comparators defined in column definitions.
1400
+ *
1401
+ * @param {string} property - The property to sort by
1402
+ * @param {number} f - The sort direction factor: 1 for ascending, -1 for descending, 0 for no sorting
1403
+ * @returns {(a: T, b: T) => number} A comparator function that compares two rows
1404
+ *
1405
+ * @example
1406
+ * // Create a comparator for sorting by name in ascending order
1407
+ * const comparator = bodyAreaModel.genericFlatTableSortComparator('name', 1);
1408
+ *
1409
+ * // Sort the rows using the comparator
1410
+ * const sortedRows = [...bodyAreaModel.getFilteredRows()].sort(comparator);
1411
+ */
1092
1412
  genericFlatTableSortComparator(e, t) {
1093
1413
  const s = this.columnDefs.find((o) => o.property === e);
1094
1414
  return (o, i) => {
@@ -1096,6 +1416,16 @@ class L extends tt {
1096
1416
  return s != null && s.sortComparator ? t * s.sortComparator(r, a, o, i, t) : this.sorterService.genericSortComparator(r, a, t);
1097
1417
  };
1098
1418
  }
1419
+ /**
1420
+ * Recursively gets a value from an object using an array of property names.
1421
+ * This is a helper method used by `getValueByT` to access nested properties.
1422
+ *
1423
+ * @param {any} o - The object to get the value from
1424
+ * @param {string[]} props - An array of property names representing the path to the value
1425
+ * @returns {any} The value at the specified property path, or undefined if not found
1426
+ *
1427
+ * @private
1428
+ */
1099
1429
  getPropertyValue(e, t) {
1100
1430
  const s = t.shift(), o = e[s];
1101
1431
  return o && t.length ? this.getPropertyValue(o, t) : o;
@@ -1106,41 +1436,302 @@ class ot {
1106
1436
  this.tableScope = e;
1107
1437
  }
1108
1438
  /**
1109
- * Updates the cells in the table based on the provided events.
1439
+ * Updates the cells in the table with the provided cell update events.
1110
1440
  *
1111
- * @param {TableCellUpdateEventIf[]} events - The array of events representing the updates to perform on the cells.
1112
- * @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.
1441
+ * This method allows you to update specific cells in the table without requiring a full table repaint,
1442
+ * which can significantly improve performance when updating large tables frequently.
1113
1443
  *
1114
- * @return {void} - This method doesn't return anything.
1444
+ * @param {TableCellUpdateEventIf[]} events - An array of cell update events, each defining a single cell update operation.
1445
+ * Each event must specify:
1446
+ * - area: The table area to update ('header', 'body', or 'footer')
1447
+ * - rowIndex: The row index of the cell to update
1448
+ * - columnIndex: The column index of the cell to update
1449
+ * - value: The new value to set for the cell
1450
+ * - cssClasses: Optional object mapping CSS class names to boolean values
1451
+ * (true to add the class, false to remove it)
1452
+ *
1453
+ * @param {boolean} [repaintAll=false] - Whether to repaint the entire table after updating cells.
1454
+ * - If true: All cells will be repainted after updating (slower but ensures visual consistency)
1455
+ * - If false: Only the modified cells will be repainted (faster, recommended for frequent updates)
1456
+ *
1457
+ * @returns {void}
1458
+ *
1459
+ * @example
1460
+ * // Update a single cell with a new value and CSS classes
1461
+ * tableApi.updateCells([{
1462
+ * area: 'body',
1463
+ * rowIndex: 3,
1464
+ * columnIndex: 2,
1465
+ * value: 42,
1466
+ * cssClasses: {
1467
+ * 'highlight': true, // Add 'highlight' class
1468
+ * 'error': false // Remove 'error' class if present
1469
+ * }
1470
+ * }]);
1471
+ *
1472
+ * @example
1473
+ * // Update multiple cells at once
1474
+ * tableApi.updateCells([
1475
+ * {
1476
+ * area: 'body',
1477
+ * rowIndex: 1,
1478
+ * columnIndex: 1,
1479
+ * value: 'New Value 1',
1480
+ * cssClasses: { 'updated': true }
1481
+ * },
1482
+ * {
1483
+ * area: 'body',
1484
+ * rowIndex: 2,
1485
+ * columnIndex: 3,
1486
+ * value: 'New Value 2',
1487
+ * cssClasses: { 'updated': true }
1488
+ * }
1489
+ * ]);
1490
+ *
1491
+ * @example
1492
+ * // Update cells and repaint the entire table
1493
+ * tableApi.updateCells([
1494
+ * { area: 'body', rowIndex: 0, columnIndex: 0, value: 'Hello', cssClasses: { 'bg-green-0': true } },
1495
+ * { area: 'body', rowIndex: 1, columnIndex: 1, value: 'World', cssClasses: { 'bg-red-0': true } }
1496
+ * ], true);
1497
+ *
1498
+ * @example
1499
+ * // High-performance animation example (update without full repaint)
1500
+ * function animateCell() {
1501
+ * const value = Math.sin(Date.now() / 1000) * 50;
1502
+ * const cssClasses = {
1503
+ * 'positive': value > 0,
1504
+ * 'negative': value < 0
1505
+ * };
1506
+ *
1507
+ * tableApi.updateCells([{
1508
+ * area: 'body',
1509
+ * rowIndex: 0,
1510
+ * columnIndex: 0,
1511
+ * value: Math.round(value),
1512
+ * cssClasses
1513
+ * }]);
1514
+ *
1515
+ * requestAnimationFrame(animateCell);
1516
+ * }
1517
+ * animateCell();
1115
1518
  */
1116
1519
  updateCells(e, t = !1) {
1117
1520
  this.tableScope.updateCells(e, t);
1118
1521
  }
1119
1522
  /**
1120
- * Notifies that the external filter has changed.
1523
+ * Notifies the table that an external filter has been changed and needs to be applied.
1121
1524
  *
1122
- * @return {void}
1525
+ * This method is used when an external filter condition (defined by `tableOptions.externalFilterFunction`)
1526
+ * has changed and the table needs to refresh its display to reflect the new filtering criteria.
1527
+ *
1528
+ * When called, this method:
1529
+ * 1. Applies the external filter function to all rows
1530
+ * 2. Clears the current selection (by default)
1531
+ * 3. Scrolls to the top of the table
1532
+ * 4. Recalculates table dimensions
1533
+ * 5. Repaints the table to display only the filtered rows
1534
+ *
1535
+ * @example
1536
+ * ```typescript
1537
+ * // Define an external filter function in your table options
1538
+ * const tableOptions = {
1539
+ * externalFilterFunction: (row: MyRowType) => {
1540
+ * // Return true to include the row, false to filter it out
1541
+ * return row.status === 'active';
1542
+ * }
1543
+ * };
1544
+ *
1545
+ * // Initialize your table with these options
1546
+ * const tableApi = new TableApi(tableScope);
1547
+ *
1548
+ * // Later, when filter criteria change (e.g., in a search input handler)
1549
+ * function onFilterTextChanged() {
1550
+ * // Update the filter function if needed
1551
+ * tableOptions.externalFilterFunction = (row: MyRowType) => {
1552
+ * return row.name.includes(searchText);
1553
+ * };
1554
+ *
1555
+ * // Apply the updated filter
1556
+ * tableApi.externalFilterChanged();
1557
+ * }
1558
+ * ```
1559
+ *
1560
+ * @returns {void}
1561
+ * @see TableScope.externalFilterChanged
1123
1562
  */
1124
1563
  externalFilterChanged() {
1125
1564
  this.tableScope.externalFilterChanged();
1126
1565
  }
1127
1566
  /**
1128
- * Scrolls the table body to the specified pixel coordinates.
1567
+ * Scrolls the table content to the specified pixel coordinates.
1129
1568
  *
1130
- * @param {number} px - The horizontal pixel coordinate to scroll to. Defaults to 0.
1131
- * @param {number} py - The vertical pixel coordinate to scroll to. Defaults to 0.
1132
- * @return {void}
1569
+ * This method allows programmatic scrolling of the table viewport to exact pixel positions.
1570
+ * It delegates the scrolling operation to the underlying TableScope instance.
1571
+ *
1572
+ * @param {number} px - The horizontal pixel coordinate to scroll to. Defaults to 0 (leftmost position).
1573
+ * @param {number} py - The vertical pixel coordinate to scroll to. Defaults to 0 (topmost position).
1574
+ * @returns {void}
1575
+ *
1576
+ * @example
1577
+ * // Scroll to the top-left corner of the table
1578
+ * tableApi.scrollToPixel(0, 0);
1579
+ *
1580
+ * @example
1581
+ * // Scroll 200 pixels horizontally and 150 pixels vertically
1582
+ * tableApi.scrollToPixel(200, 150);
1583
+ *
1584
+ * @example
1585
+ * // Scroll only vertically, keeping the current horizontal position
1586
+ * tableApi.scrollToPixel(undefined, 300);
1587
+ *
1588
+ * @example
1589
+ * // Example in a component that needs precise scrolling control
1590
+ * class TableScroller {
1591
+ * private tableApi: TableApi;
1592
+ *
1593
+ * constructor(tableApi: TableApi) {
1594
+ * this.tableApi = tableApi;
1595
+ * }
1596
+ *
1597
+ * scrollToPosition(x: number, y: number) {
1598
+ * // Scroll to exact pixel coordinates
1599
+ * this.tableApi.scrollToPixel(x, y);
1600
+ * }
1601
+ *
1602
+ * scrollHalfway() {
1603
+ * const tableModel = this.tableApi.getTableModel();
1604
+ * const totalWidth = tableModel.getContentWidthInPixel();
1605
+ * const totalHeight = tableModel.getContentHeightInPixel();
1606
+ *
1607
+ * // Scroll to the middle of the table content
1608
+ * this.tableApi.scrollToPixel(totalWidth / 2, totalHeight / 2);
1609
+ * }
1610
+ * }
1611
+ *
1612
+ * @example
1613
+ * // Advanced usage with animated scrolling
1614
+ * class SmoothScroller {
1615
+ * private tableApi: TableApi;
1616
+ * private animationFrameId: number | null = null;
1617
+ *
1618
+ * constructor(tableApi: TableApi) {
1619
+ * this.tableApi = tableApi;
1620
+ * }
1621
+ *
1622
+ * smoothScrollTo(targetX: number, targetY: number, duration: number = 500) {
1623
+ * // Cancel any ongoing animation
1624
+ * if (this.animationFrameId !== null) {
1625
+ * cancelAnimationFrame(this.animationFrameId);
1626
+ * }
1627
+ *
1628
+ * const startTime = performance.now();
1629
+ * const startX = this.tableApi.getTableScope().getScrollLeft();
1630
+ * const startY = this.tableApi.getTableScope().getScrollTop();
1631
+ * const distanceX = targetX - startX;
1632
+ * const distanceY = targetY - startY;
1633
+ *
1634
+ * const step = (currentTime: number) => {
1635
+ * const elapsed = currentTime - startTime;
1636
+ * const progress = Math.min(elapsed / duration, 1);
1637
+ *
1638
+ * // Use easing function for smooth animation
1639
+ * const easeProgress = 1 - Math.pow(1 - progress, 3); // Cubic ease-out
1640
+ *
1641
+ * const currentX = startX + distanceX * easeProgress;
1642
+ * const currentY = startY + distanceY * easeProgress;
1643
+ *
1644
+ * this.tableApi.scrollToPixel(currentX, currentY);
1645
+ *
1646
+ * if (progress < 1) {
1647
+ * this.animationFrameId = requestAnimationFrame(step);
1648
+ * } else {
1649
+ * this.animationFrameId = null;
1650
+ * }
1651
+ * };
1652
+ *
1653
+ * this.animationFrameId = requestAnimationFrame(step);
1654
+ * }
1655
+ *
1656
+ * cancelAnimation() {
1657
+ * if (this.animationFrameId !== null) {
1658
+ * cancelAnimationFrame(this.animationFrameId);
1659
+ * this.animationFrameId = null;
1660
+ * }
1661
+ * }
1662
+ * }
1663
+ *
1664
+ * @see {@link scrollToIndex} - For scrolling based on row and column indices
1665
+ * @see {@link ensureRowIsVisible} - For scrolling to make a specific row visible
1133
1666
  */
1134
1667
  scrollToPixel(e = 0, t = 0) {
1135
1668
  this.tableScope.scrollToPixel(e, t);
1136
1669
  }
1137
1670
  /**
1138
- * Scrolls to the specified index in both horizontal and vertical directions.
1671
+ * Scrolls the table to display the specified row and column indices at the top-left corner of the viewport.
1139
1672
  *
1140
- * @param {number} indexX - The index of the column to scroll to in the horizontal direction. Default is 0.
1141
- * @param {number} indexY - The index of the row to scroll to in the vertical direction. Default is 0.
1673
+ * This method allows programmatic scrolling to a specific position in the table grid based on row and column indices.
1674
+ * It uses the underlying TableScope's scrolling mechanism to navigate to the target location.
1142
1675
  *
1143
- * @return undefined
1676
+ * @param {number} indexX - The horizontal index (column) to scroll to. Defaults to 0 (leftmost column).
1677
+ * @param {number} indexY - The vertical index (row) to scroll to. Defaults to 0 (topmost row).
1678
+ * @returns {void}
1679
+ *
1680
+ * @example
1681
+ * // Scroll to the 5th row, keeping the current horizontal scroll position
1682
+ * tableApi.scrollToIndex(0, 5);
1683
+ *
1684
+ * @example
1685
+ * // Scroll to column 3, row 10
1686
+ * tableApi.scrollToIndex(3, 10);
1687
+ *
1688
+ * @example
1689
+ * // Example in a component that needs to navigate to specific content
1690
+ * class TableNavigator {
1691
+ * private tableApi: TableApi;
1692
+ *
1693
+ * constructor(tableApi: TableApi) {
1694
+ * this.tableApi = tableApi;
1695
+ * }
1696
+ *
1697
+ * goToCell(columnIndex: number, rowIndex: number) {
1698
+ * // Navigate directly to the specified cell position
1699
+ * this.tableApi.scrollToIndex(columnIndex, rowIndex);
1700
+ *
1701
+ * // Optional: Select the cell after navigating to it
1702
+ * const selectionModel = this.tableApi.getSelectionModel();
1703
+ * if (selectionModel) {
1704
+ * selectionModel.selectCell(rowIndex, columnIndex);
1705
+ * }
1706
+ * }
1707
+ * }
1708
+ *
1709
+ * @example
1710
+ * // Advanced usage with search functionality
1711
+ * class TableSearcher {
1712
+ * findAndScrollToMatch(searchTerm: string) {
1713
+ * const tableModel = this.tableApi.getTableModel();
1714
+ * const bodyModel = tableModel.getAreaModel('body');
1715
+ *
1716
+ * // Search for the term in the table data
1717
+ * for (let row = 0; row < bodyModel.getRowCount(); row++) {
1718
+ * for (let col = 0; col < tableModel.getColumnCount(); col++) {
1719
+ * const cellContent = bodyModel.getValueAt(row, col)?.toString() || '';
1720
+ *
1721
+ * if (cellContent.includes(searchTerm)) {
1722
+ * // Found a match, scroll to it
1723
+ * this.tableApi.scrollToIndex(col, row);
1724
+ * return true;
1725
+ * }
1726
+ * }
1727
+ * }
1728
+ *
1729
+ * return false; // No match found
1730
+ * }
1731
+ * }
1732
+ *
1733
+ * @see {@link scrollToPixel} - For scrolling to specific pixel coordinates
1734
+ * @see {@link ensureRowIsVisible} - For scrolling to make a specific row visible
1144
1735
  */
1145
1736
  scrollToIndex(e = 0, t = 0) {
1146
1737
  this.tableScope.scrollToIndex(e, t);
@@ -1201,19 +1792,71 @@ class ot {
1201
1792
  /**
1202
1793
  * Repaints the table.
1203
1794
  *
1204
- * This method calls the repaint method of the tableScope object
1205
- * to update and redraw the table based on the latest data.
1795
+ * This method refreshes the visual representation of the table by delegating to the
1796
+ * tableScope's repaint functionality. Use this method whenever the table's visual state
1797
+ * needs to be updated after data changes, selection changes, or any modifications that
1798
+ * affect the rendered output.
1799
+ *
1800
+ * Repainting the table ensures that all visible cells, rows, and styling reflect the
1801
+ * current state of the underlying data model and configuration settings.
1802
+ *
1803
+ * @example
1804
+ * // Update data and repaint the table
1805
+ * const tableApi = new TableApi(tableScope);
1806
+ * tableApi.setRows(newData);
1807
+ * tableApi.repaint();
1808
+ *
1809
+ * @example
1810
+ * // Update selection and repaint to show the visual change
1811
+ * tableApi.getSelectionModel().selectCell(2, 3);
1812
+ * tableApi.repaint();
1813
+ *
1814
+ * @example
1815
+ * // After changing column visibility, repaint to reflect changes
1816
+ * tableApi.setColumnVisible(0, false);
1817
+ * tableApi.repaint();
1818
+ *
1819
+ * @returns {void}
1206
1820
  */
1207
1821
  repaint() {
1208
1822
  this.tableScope.repaint();
1209
1823
  }
1210
1824
  /**
1211
- * Repaints the table scope with hard repaint.
1212
- * Repaints the UI by resetting the size of the wrapper div,
1213
- * adjusting the containers and rows, and performing additional adjustments
1214
- * after scrolling.
1825
+ * Performs a complete repaint of the table by triggering a hard repaint on the underlying table scope.
1215
1826
  *
1216
- * @return {void}
1827
+ * A hard repaint is more thorough than a regular repaint and performs the following operations:
1828
+ * - Recalculates the height and padding of the table model
1829
+ * - Resets the size of the wrapper div elements
1830
+ * - Adjusts containers and rows positioning
1831
+ * - Makes additional adjustments after scrolling
1832
+ *
1833
+ * Use this method when regular repaint isn't sufficient, such as when:
1834
+ * - Table dimensions have significantly changed
1835
+ * - The structure of data has been modified (rows/columns added or removed)
1836
+ * - The table layout needs complete recalculation
1837
+ * - After major DOM changes affecting the table's container
1838
+ *
1839
+ * @example
1840
+ * // Example 1: Basic usage
1841
+ * tableApi.repaintHard();
1842
+ *
1843
+ * @example
1844
+ * // Example 2: Using after major data changes
1845
+ * tableApi.setRows(newDataSet);
1846
+ * tableApi.repaintHard();
1847
+ *
1848
+ * @example
1849
+ * // Example 3: Using after resizing a container
1850
+ * window.addEventListener('resize', () => {
1851
+ * tableApi.repaintHard();
1852
+ * });
1853
+ *
1854
+ * @example
1855
+ * // Example 4: Using after changing column visibility
1856
+ * tableApi.setColumnVisible(2, false);
1857
+ * tableApi.repaintHard();
1858
+ *
1859
+ * @returns {void} This method doesn't return a value
1217
1860
  */
1218
1861
  repaintHard() {
1219
1862
  this.tableScope.repaintHard();
@@ -1229,8 +1872,30 @@ class ot {
1229
1872
  this.tableScope.recalcColumnWidths(e);
1230
1873
  }
1231
1874
  /**
1232
- * Clears the current selection of the table.
1233
- * The table will be rendered automatically.
1875
+ * Clears the current selection in the table.
1876
+ *
1877
+ * This method removes any selected cells, rows, or columns in the table.
1878
+ * It provides a convenient way to programmatically clear all selections in the table
1879
+ * without having to access the underlying selection model directly.
1880
+ *
1881
+ * When called, this method delegates to the table scope's clearSelection method with
1882
+ * a parameter value of true, which ensures the table is automatically repainted after
1883
+ * the selection is cleared.
1884
+ *
1885
+ * @example
1886
+ * // Clear all selections in the table
1887
+ * tableApi.clearSelection();
1888
+ *
1889
+ * // Example usage in a component
1890
+ * class MyComponent {
1891
+ * @ViewChild('tableComponent') tableComponent: TableComponent;
1892
+ *
1893
+ * resetTableSelection(): void {
1894
+ * if (this.tableComponent?.api) {
1895
+ * this.tableComponent.api.clearSelection();
1896
+ * }
1897
+ * }
1898
+ * }
1234
1899
  *
1235
1900
  * @returns {void}
1236
1901
  */
@@ -1238,12 +1903,31 @@ class ot {
1238
1903
  this.tableScope.clearSelection(!0);
1239
1904
  }
1240
1905
  /**
1241
- * Sets the selection model for the table scope.
1906
+ * Sets the selection model for the table.
1242
1907
  *
1243
- * @param {SelectionModel} sm - The selection model to be set.
1244
- * @param {boolean} [repaint=true] - Indicates whether the table should be repainted after setting the selection model. Default value is true.
1908
+ * This method allows you to replace the current selection model with a new one,
1909
+ * which controls how cells, rows, or columns can be selected in the table.
1245
1910
  *
1246
- * @return {void}
1911
+ * @param {SelectionModel} sm - The new selection model to be set. This model defines
1912
+ * the selection behavior including selection type (none, cell, row, column),
1913
+ * selection mode (single, multi), and manages the selected ranges.
1914
+ * @param {boolean} [repaint=true] - Whether to repaint the table after changing the selection model.
1915
+ * Default is true, which immediately reflects the change visually.
1916
+ * Set to false if you want to avoid immediate repainting.
1917
+ *
1918
+ * @example
1919
+ * // Create a new selection model with row selection and multi-select mode
1920
+ * const selectionModel = new SelectionModel("row", "multi");
1921
+ *
1922
+ * // Set the new selection model and repaint the table
1923
+ * tableApi.setSelectionModel(selectionModel);
1924
+ *
1925
+ * // Set a selection model without repainting (if you plan to make more changes)
1926
+ * tableApi.setSelectionModel(selectionModel, false);
1927
+ * // ... make other changes ...
1928
+ * tableApi.repaint(); // Now repaint once
1929
+ *
1930
+ * @returns {void}
1247
1931
  */
1248
1932
  setSelectionModel(e, t = !0) {
1249
1933
  this.tableScope.setSelectionModel(e, t);
@@ -1259,9 +1943,36 @@ class ot {
1259
1943
  this.tableScope.onActionTriggered(e);
1260
1944
  }
1261
1945
  /**
1262
- * Retrieves the mapping of shortcuts to corresponding action in the current table scope.
1946
+ * Retrieves the shortcut action mapping from the table's shortcut service.
1947
+ *
1948
+ * This method provides access to the keyboard shortcut configuration that defines
1949
+ * which keys trigger specific actions in the table. The mapping contains key-value
1950
+ * pairs where:
1951
+ * - Keys are string representations of keyboard shortcuts (e.g., "ctrl+c", "shift+arrow_down")
1952
+ * - Values are ActionId values representing the corresponding table actions
1953
+ *
1954
+ * This mapping can be useful for:
1955
+ * - Displaying available shortcuts to users
1956
+ * - Creating custom shortcut documentation
1957
+ * - Dynamically checking which actions are available via keyboard
1958
+ * - Extending or integrating with the table's shortcut system
1959
+ *
1960
+ * @returns {ShortcutActionIdMapping} An object mapping shortcut key combinations to their corresponding action IDs.
1961
+ * For example: { "ctrl+c": "COPY_2_CLIPBOARD", "arrow_down": "NAVIGATE_DOWN" }
1962
+ *
1963
+ * @example
1964
+ * // Get all available shortcuts in the table
1965
+ * const shortcuts = tableApi.getShortcutActionMapping();
1263
1966
  *
1264
- * @return {ShortcutActionIdMapping} The mapping of shortcuts to corresponding action.
1967
+ * // Check if a specific shortcut exists
1968
+ * if (shortcuts["ctrl+c"]) {
1969
+ * console.log("Copy shortcut is available with action:", shortcuts["ctrl+c"]);
1970
+ * }
1971
+ *
1972
+ * // Display available shortcuts in the UI
1973
+ * Object.entries(shortcuts).forEach(([key, actionId]) => {
1974
+ * console.log(`${key}: ${actionId}`);
1975
+ * });
1265
1976
  */
1266
1977
  getShortcutActionMapping() {
1267
1978
  return this.tableScope.shortcutService.getShortcutActionMapping();
@@ -1269,7 +1980,35 @@ class ot {
1269
1980
  /**
1270
1981
  * Copies the selected data from the table to the clipboard.
1271
1982
  *
1272
- * @return {Promise<string>} - A promise that resolves with the copied data as a string.
1983
+ * This method leverages the copyService to extract and copy the currently selected data
1984
+ * from the table. It works with the current selection state and focus position to determine
1985
+ * what content should be copied.
1986
+ *
1987
+ * The copied data is formatted as tab-separated text that can be pasted into spreadsheet
1988
+ * applications like Excel or text editors while maintaining the tabular structure.
1989
+ *
1990
+ * @example
1991
+ * // Copy the currently selected data to clipboard
1992
+ * tableApi.copyToClipboard().then(content => {
1993
+ * console.log('Copied to clipboard:', content);
1994
+ * });
1995
+ *
1996
+ * // Using with a button click handler
1997
+ * function onCopyButtonClick() {
1998
+ * if (tableApi) {
1999
+ * tableApi.copyToClipboard()
2000
+ * .then(content => {
2001
+ * console.log('Successfully copied data to clipboard');
2002
+ * // Optionally do something with the copied content
2003
+ * })
2004
+ * .catch(error => {
2005
+ * console.error('Failed to copy to clipboard:', error);
2006
+ * });
2007
+ * }
2008
+ * }
2009
+ *
2010
+ * @returns {Promise<string>} A promise that resolves with the copied data as a string.
2011
+ * The string contains the tab-separated representation of the selected table data.
1273
2012
  */
1274
2013
  copyToClipboard() {
1275
2014
  return this.tableScope.copyService.copyToClipboard(
@@ -1279,11 +2018,33 @@ class ot {
1279
2018
  );
1280
2019
  }
1281
2020
  /**
1282
- * Generates and downloads an Excel file based on the table data.
2021
+ * Downloads the current table data as an Excel file.
2022
+ *
2023
+ * This method extracts all visible data from the table (including header, body, and footer areas),
2024
+ * converts it into a matrix format, and triggers a download of an Excel file containing this data.
1283
2025
  *
1284
- * @param {string} fileName - The name of the Excel file to be downloaded. Defaults to 'table.xlsx'.
1285
- * @param {string} author - The author of the Excel file. If not provided, it will remain empty.
1286
- * @return {void} No return value. Initiates a file download of the Excel document.
2026
+ * The method works by:
2027
+ * 1. Creating an empty matrix to hold all table data
2028
+ * 2. Iterating through each area of the table (header, body, footer)
2029
+ * 3. For each area, iterating through all rows and columns to extract cell values
2030
+ * 4. Passing the complete data matrix to the Excel service for file generation and download
2031
+ *
2032
+ * @param {string} fileName - The name of the Excel file to be downloaded (default: 'table.xlsx')
2033
+ * @param {string} author - Optional metadata for the Excel file to specify the author (default: '')
2034
+ *
2035
+ * @returns {void} The result of the excelService.downloadExcel method call
2036
+ *
2037
+ * @example
2038
+ * // Download table data with default filename
2039
+ * tableApi.downloadExcel();
2040
+ *
2041
+ * @example
2042
+ * // Download table data with custom filename and author
2043
+ * tableApi.downloadExcel('sales-report.xlsx', 'John Doe');
2044
+ *
2045
+ * @example
2046
+ * // Download table data with custom filename only
2047
+ * tableApi.downloadExcel('quarterly-data.xlsx');
1287
2048
  */
1288
2049
  downloadExcel(e = "table.xlsx", t = "") {
1289
2050
  const s = [], o = this.tableScope.tableModel.getColumnCount(), i = ["header", "body", "footer"];
@@ -1299,18 +2060,66 @@ class ot {
1299
2060
  return this.tableScope.excelService.downloadExcel(s, e, t);
1300
2061
  }
1301
2062
  /**
1302
- * Retrieves the current scope of the table.
2063
+ * Returns the TableScope instance associated with this TableApi.
2064
+ *
2065
+ * The TableScope provides access to the core functionality and internal state of the table component,
2066
+ * including rendering, event handling, selection, and other low-level operations.
2067
+ *
2068
+ * This method is useful for advanced customization scenarios where you need direct access
2069
+ * to the table's internal structure and behaviors.
2070
+ *
2071
+ * @returns {TableScope} The TableScope instance that controls this table component
1303
2072
  *
1304
- * @returns {TableScope} The current scope of the table.
2073
+ * @example
2074
+ * // Access the TableScope to perform a custom operation
2075
+ * const tableApi = new TableApi(myTableScope);
2076
+ * const tableScope = tableApi.getTableScope();
2077
+ *
2078
+ * // Example: Manually trigger a context menu at a specific location
2079
+ * const mouseEvent = new MouseEvent('contextmenu');
2080
+ * const geMouseEvent = tableScope.createGeMouseEvent(mouseEvent);
2081
+ * tableScope.contextmenu(geMouseEvent);
1305
2082
  */
1306
2083
  getTableScope() {
1307
2084
  return this.tableScope;
1308
2085
  }
1309
2086
  /**
1310
- * Retrieves the selection model of the table.
2087
+ * Returns the current selection model for the table.
2088
+ *
2089
+ * The selection model manages cell selection state, including single cells, ranges, rows, and columns.
2090
+ * This method provides access to the selection model instance, allowing operations like:
2091
+ * - Checking if cells are selected
2092
+ * - Getting selection ranges
2093
+ * - Modifying selections
2094
+ * - Adding/removing selection event listeners
2095
+ *
2096
+ * @returns {SelectionModelIf | undefined} The current selection model if available, otherwise undefined.
2097
+ *
2098
+ * @example
2099
+ * // Get the selection model
2100
+ * const selectionModel = tableApi.getSelectionModel();
2101
+ *
2102
+ * // Check if a specific cell is selected
2103
+ * if (selectionModel?.isSelected(3, 2)) {
2104
+ * console.log('Cell at row 3, column 2 is selected');
2105
+ * }
2106
+ *
2107
+ * // Get all selected ranges
2108
+ * const ranges = selectionModel?.getRanges();
2109
+ * console.log('Selected ranges:', ranges);
2110
+ *
2111
+ * // Clear all selections
2112
+ * selectionModel?.clear();
1311
2113
  *
1312
- * @return {SelectionModelIf | undefined} The selection model of the table,
1313
- * or undefined if no selection model is available.
2114
+ * // Toggle selection of a cell
2115
+ * selectionModel?.togglePoint(5, 1);
2116
+ *
2117
+ * // Add a selection change listener
2118
+ * selectionModel?.addEventSelectionChangedListener({
2119
+ * selectionChanged: () => {
2120
+ * console.log('Selection has changed');
2121
+ * }
2122
+ * });
1314
2123
  */
1315
2124
  getSelectionModel() {
1316
2125
  return this.tableScope.selectionModel();
@@ -1791,18 +2600,181 @@ class ot {
1791
2600
  getFirstVisibleRowIndex() {
1792
2601
  return this.tableScope.getFirstVisibleRowIndex();
1793
2602
  }
2603
+ /**
2604
+ * Retrieves the index of the first fully visible row in the table's viewport.
2605
+ *
2606
+ * A row is considered "fully visible" when it's completely within the visible area of the table.
2607
+ * This differs from the regular "visible" row, which might be partially visible at the edges of the viewport.
2608
+ *
2609
+ * This method is useful for:
2610
+ * - Determining which rows are completely in view for operations that require full visibility
2611
+ * - Implementing pagination or virtualization logic that needs to know complete row visibility
2612
+ * - Supporting keyboard navigation that should skip partially visible rows
2613
+ *
2614
+ * @returns {number} The index of the first fully visible row, or -1 if no rows are fully visible
2615
+ *
2616
+ * @example
2617
+ * // Get the first fully visible row index
2618
+ * const firstFullVisibleRow = tableApi.getFirstFullVisibleRowIndex();
2619
+ *
2620
+ * // Check if a specific row is fully visible
2621
+ * const isRowFullyVisible = (rowIndex) => {
2622
+ * const firstFullVisible = tableApi.getFirstFullVisibleRowIndex();
2623
+ * const lastFullVisible = tableApi.getLastFullVisibleRowIndex();
2624
+ * return rowIndex >= firstFullVisible && rowIndex <= lastFullVisible;
2625
+ * };
2626
+ */
1794
2627
  getFirstFullVisibleRowIndex() {
1795
2628
  return this.tableScope.getFirstFullVisibleRowIndex();
1796
2629
  }
2630
+ /**
2631
+ * Returns the index of the last row that is visible in the table's viewport.
2632
+ *
2633
+ * This method retrieves the last visible row index from the table scope, which keeps
2634
+ * track of which rows are currently visible as the user scrolls through the table.
2635
+ *
2636
+ * This can be useful for:
2637
+ * - Implementing virtualized scrolling optimizations
2638
+ * - Determining if specific rows are currently in view
2639
+ * - Implementing features that need to know the visible range of rows
2640
+ *
2641
+ * @returns {number} The index of the last visible row in the table viewport
2642
+ *
2643
+ * @example
2644
+ * // Check if a specific row is currently visible in the viewport
2645
+ * const lastVisibleIndex = tableApi.getLastVisibleRowIndex();
2646
+ * const firstVisibleIndex = tableApi.getFirstVisibleRowIndex();
2647
+ * const isRowVisible = rowIndex >= firstVisibleIndex && rowIndex <= lastVisibleIndex;
2648
+ *
2649
+ * @example
2650
+ * // Get the range of visible rows
2651
+ * const visibleRowsRange = {
2652
+ * first: tableApi.getFirstVisibleRowIndex(),
2653
+ * last: tableApi.getLastVisibleRowIndex()
2654
+ * };
2655
+ * console.log(`Visible rows: ${visibleRowsRange.first} to ${visibleRowsRange.last}`);
2656
+ */
1797
2657
  getLastVisibleRowIndex() {
1798
2658
  return this.tableScope.getLastVisibleRowIndex();
1799
2659
  }
2660
+ /**
2661
+ * Returns the index of the last fully visible row in the table's viewport.
2662
+ *
2663
+ * This method retrieves the last row that is completely visible within the current
2664
+ * viewport of the table. A row is considered "fully visible" when its entire height
2665
+ * is visible without any portion being cut off by the viewport boundaries.
2666
+ *
2667
+ * The distinction between "visible" and "fully visible" is important when scrolling:
2668
+ * - A row can be partially visible (some portion is in view)
2669
+ * - A row can be fully visible (the entire row is in view)
2670
+ *
2671
+ * @returns {number} The index of the last fully visible row in the table.
2672
+ * If no row is fully visible or the table is empty, the method might return -1.
2673
+ *
2674
+ * @example
2675
+ * ```typescript
2676
+ * // Get the index of the last fully visible row
2677
+ * const lastVisibleRowIndex = tableApi.getLastFullVisibleRowIndex();
2678
+ *
2679
+ * // Use this information to determine if a specific row is fully visible
2680
+ * const isRowFullyVisible = rowIndex <= lastVisibleRowIndex && rowIndex >= tableApi.getFirstFullVisibleRowIndex();
2681
+ *
2682
+ * // Can be used with scrolling operations to ensure certain rows are visible
2683
+ * if (rowIndex > lastVisibleRowIndex) {
2684
+ * tableApi.ensureRowIsVisible(rowIndex);
2685
+ * }
2686
+ * ```
2687
+ */
1800
2688
  getLastFullVisibleRowIndex() {
1801
2689
  return this.tableScope.getLastFullVisibleRowIndex();
1802
2690
  }
2691
+ /**
2692
+ * Checks whether logging is currently active for the table component.
2693
+ *
2694
+ * This method returns the current state of logging for the table. When logging is active,
2695
+ * the table outputs detailed information about its operations to the console, including:
2696
+ *
2697
+ * - Rendering processes and lifecycle events
2698
+ * - Data modifications and updates
2699
+ * - Event handling and user interactions
2700
+ * - Performance metrics and state changes
2701
+ *
2702
+ * Logging can be toggled using the `setLoggingActive(boolean)` method.
2703
+ *
2704
+ * @returns {boolean} True if logging is currently enabled, false otherwise.
2705
+ *
2706
+ * @example
2707
+ * // Check if logging is enabled
2708
+ * if (tableApi.isLoggingActive()) {
2709
+ * console.log("Table logging is currently active");
2710
+ * }
2711
+ *
2712
+ * // Conditionally enable logging only if it's not already active
2713
+ * if (!tableApi.isLoggingActive()) {
2714
+ * tableApi.setLoggingActive(true);
2715
+ *
2716
+ * // Perform operations that need debugging
2717
+ * tableApi.updateCells([
2718
+ * {
2719
+ * area: "body",
2720
+ * rowIndex: 2,
2721
+ * columnIndex: 3,
2722
+ * value: "New Value",
2723
+ * cssClasses: { "highlight": true }
2724
+ * }
2725
+ * ]);
2726
+ *
2727
+ * // Run some additional operations...
2728
+ *
2729
+ * // Disable logging when finished
2730
+ * tableApi.setLoggingActive(false);
2731
+ * }
2732
+ */
1803
2733
  setLoggingActive(e) {
1804
2734
  this.tableScope.loggingActive = e;
1805
2735
  }
2736
+ /**
2737
+ * Checks whether logging is currently active for the table component.
2738
+ *
2739
+ * This method returns the current state of logging for the table. When logging is active,
2740
+ * the table outputs detailed information about its operations to the console, including:
2741
+ *
2742
+ * - Rendering processes and lifecycle events
2743
+ * - Data modifications and updates
2744
+ * - Event handling and user interactions
2745
+ * - Performance metrics and state changes
2746
+ *
2747
+ * Logging can be toggled using the `setLoggingActive(boolean)` method.
2748
+ *
2749
+ * @returns {boolean} True if logging is currently enabled, false otherwise.
2750
+ *
2751
+ * @example
2752
+ * // Check if logging is enabled
2753
+ * if (tableApi.isLoggingActive()) {
2754
+ * console.log("Table logging is currently active");
2755
+ * }
2756
+ *
2757
+ * // Conditionally enable logging only if it's not already active
2758
+ * if (!tableApi.isLoggingActive()) {
2759
+ * tableApi.setLoggingActive(true);
2760
+ *
2761
+ * // Perform operations that need debugging
2762
+ * tableApi.updateCells([
2763
+ * {
2764
+ * area: "body",
2765
+ * rowIndex: 2,
2766
+ * columnIndex: 3,
2767
+ * value: "New Value",
2768
+ * cssClasses: { "highlight": true }
2769
+ * }
2770
+ * ]);
2771
+ *
2772
+ * // Run some additional operations...
2773
+ *
2774
+ * // Disable logging when finished
2775
+ * tableApi.setLoggingActive(false);
2776
+ * }
2777
+ */
1806
2778
  isLoggingActive() {
1807
2779
  return this.tableScope.loggingActive;
1808
2780
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guiexpert/solid-table",
3
- "version": "1.1.79",
3
+ "version": "1.1.81",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -8,7 +8,9 @@
8
8
  "entryFile": "src/index.ts"
9
9
  },
10
10
  "publishConfig": {
11
- "directory": "dist"
11
+ "directory": "dist",
12
+ "registry": "https://registry.npmjs.org/",
13
+ "access": "public"
12
14
  },
13
15
  "exports": {
14
16
  ".": {
@@ -18,7 +20,7 @@
18
20
  },
19
21
  "dependencies": {
20
22
  "tslib": "^2.3.0",
21
- "@guiexpert/table": "^1.1.79"
23
+ "@guiexpert/table": "^1.1.81"
22
24
  },
23
25
  "devDependencies": {
24
26
  "solid-jest": "^0.2.0",