@mikestools/usetable 0.0.4 → 0.0.6

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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { ComputedRef } from 'vue';
2
+ import { ElementInstance } from '@mikestools/useelement';
3
+ import { MaybeRef } from 'vue';
2
4
  import { Ref } from 'vue';
3
5
 
4
6
  /**
5
7
  * Base record interface - all records must have an id.
6
- * This is the foundation for the shared reactive data schema.
7
8
  */
8
9
  export declare interface BaseRecord {
9
10
  /** Unique identifier - required on all records */
@@ -11,71 +12,92 @@ export declare interface BaseRecord {
11
12
  }
12
13
 
13
14
  /**
14
- * Cell change record for tracking modifications.
15
+ * Cell change record for dirty tracking.
15
16
  */
16
17
  export declare interface CellChange {
18
+ /** Row index */
17
19
  readonly row: number;
20
+ /** Column index */
18
21
  readonly column: number;
19
- readonly oldValue: CellValue;
20
- readonly newValue: CellValue;
22
+ /** Previous value */
23
+ readonly oldValue: unknown;
24
+ /** New value */
25
+ readonly newValue: unknown;
21
26
  }
22
27
 
28
+ /**
29
+ * Callback for cell change events
30
+ */
23
31
  export declare type CellChangeCallback = (row: number, column: number, oldValue: CellValue, newValue: CellValue) => void;
24
32
 
25
33
  /**
26
- * Cell position for navigation and selection.
34
+ * Cell position for focus/navigation.
27
35
  */
28
36
  export declare interface CellPosition {
37
+ /** Row index */
29
38
  readonly row: number;
39
+ /** Column index */
30
40
  readonly column: number;
31
41
  }
32
42
 
33
43
  /**
34
- * Cell value can be a string, number, or DOM element.
44
+ * Cell value types - can be primitive or DOM node
35
45
  */
36
- export declare type CellValue = string | number | boolean | null | undefined | HTMLElement | Node;
46
+ export declare type CellValue = string | number | boolean | null | undefined | Node;
37
47
 
38
48
  /**
39
- * Create a table instance for manipulating an HTML table element.
49
+ * Create a table instance wrapping HTMLTableElement.
40
50
  *
41
- * Uses native table DOM APIs exclusively - no querySelector/querySelectorAll.
42
- * DOM-first architecture where the HTML table is the source of truth.
51
+ * Built on top of createElement, adds table-specific APIs using native methods:
52
+ * - element.caption, tHead, tFoot, tBodies (native properties)
53
+ * - element.insertRow(), deleteRow() (native methods)
54
+ * - element.rows (native HTMLCollection)
55
+ * - row.cells, row.insertCell(), row.deleteCell()
43
56
  *
44
57
  * @param element - The HTML table element
45
- * @param initialData - Optional initial body data
58
+ * @param initialData - Initial body data
46
59
  * @param options - Configuration options
47
- * @returns TableInstance for table manipulation
60
+ * @returns TableInstance with full table manipulation API
48
61
  *
49
62
  * @example
50
63
  * ```ts
51
64
  * const table = document.createElement('table')
52
- * const instance = createTable(table, [['Alice', 30], ['Bob', 25]], {
65
+ * const instance = createTable(table, [
66
+ * ['Alice', 30],
67
+ * ['Bob', 25]
68
+ * ], {
53
69
  * headers: ['Name', 'Age'],
54
70
  * caption: 'Users'
55
71
  * })
56
72
  *
73
+ * // Native table methods
74
+ * const row = instance.insertTableRow() // Uses native insertRow
75
+ *
76
+ * // High-level convenience
57
77
  * instance.addRow(['Carol', 35])
58
78
  * instance.setCell(0, 1, 31)
59
- * console.log(instance. getData())
60
79
  * ```
61
80
  */
62
81
  export declare function createTable(element: HTMLTableElement, initialData?: TableData, options?: CreateTableOptions): TableInstance;
63
82
 
64
83
  /**
65
- * Options for creating a table.
84
+ * Options for createTable
66
85
  */
67
86
  export declare interface CreateTableOptions {
68
87
  /** Initial headers */
69
88
  readonly headers?: readonly string[];
70
- /** Initial footer data */
71
- readonly footer?: RowData;
72
- /** Caption text */
89
+ /** Table caption */
73
90
  readonly caption?: string;
74
- /** ID generator for records */
91
+ /** Initial footer row */
92
+ readonly footer?: RowData;
93
+ /** ID generator for rows */
75
94
  readonly idGenerator?: IdGenerator;
76
95
  }
77
96
 
78
- export declare type DataChangeCallback = (data: CellValue[][]) => void;
97
+ /**
98
+ * Callback for data change events
99
+ */
100
+ export declare type DataChangeCallback = (data: readonly (readonly CellValue[])[]) => void;
79
101
 
80
102
  /**
81
103
  * Ensure a record has an ID, generating one if missing.
@@ -90,7 +112,7 @@ export declare function ensureId<T extends Record<string, unknown>>(record: T, g
90
112
  export declare function findById<T extends BaseRecord>(records: readonly T[], id: string): T | undefined;
91
113
 
92
114
  /**
93
- * Focus state.
115
+ * Focus state for cells.
94
116
  */
95
117
  export declare interface FocusState {
96
118
  /** Currently focused cell position */
@@ -102,6 +124,9 @@ export declare interface FocusState {
102
124
  */
103
125
  export declare function generateId(): string;
104
126
 
127
+ /**
128
+ * Callback for header change events
129
+ */
105
130
  export declare type HeaderChangeCallback = (headers: readonly string[]) => void;
106
131
 
107
132
  /**
@@ -126,21 +151,27 @@ export declare function indexById<T extends BaseRecord>(records: readonly T[], i
126
151
  export declare function isValidId(value: unknown): value is string;
127
152
 
128
153
  /**
129
- * Event callback types.
154
+ * Callback for row add events
130
155
  */
131
- export declare type RowAddCallback = (rowData: CellValue[], rowIndex: number, rowId: string | undefined) => void;
156
+ export declare type RowAddCallback = (data: readonly CellValue[], index: number, id: string | null) => void;
132
157
 
133
158
  /**
134
- * Row data is an array of cell values.
159
+ * Row data is an array of cell values
135
160
  */
136
161
  export declare type RowData = readonly CellValue[];
137
162
 
138
- export declare type RowRemoveCallback = (rowData: CellValue[], rowIndex: number, rowId: string | undefined) => void;
163
+ /**
164
+ * Callback for row remove events
165
+ */
166
+ export declare type RowRemoveCallback = (data: readonly CellValue[], index: number, id: string | null) => void;
139
167
 
140
- export declare type RowUpdateCallback = (rowIndex: number, oldData: CellValue[], newData: CellValue[], rowId: string | undefined) => void;
168
+ /**
169
+ * Callback for row update events
170
+ */
171
+ export declare type RowUpdateCallback = (index: number, oldData: readonly CellValue[], newData: readonly CellValue[], id: string | null) => void;
141
172
 
142
173
  /**
143
- * Selection state.
174
+ * Selection state for rows.
144
175
  */
145
176
  export declare interface SelectionState {
146
177
  /** Selected row indices */
@@ -157,202 +188,149 @@ export declare function stripGeneratedId<T extends {
157
188
  }>(record: T): Omit<T, 'id'> | T;
158
189
 
159
190
  /**
160
- * Table data is a 2D array of cell values.
191
+ * Table data is a 2D array
161
192
  */
162
193
  export declare type TableData = readonly RowData[];
163
194
 
164
195
  /**
165
- * Return type for createTable.
196
+ * Table instance - extends ElementInstance with table-specific APIs
166
197
  */
167
- export declare interface TableInstance {
168
- /** The table element */
169
- readonly element: HTMLTableElement;
170
- /** Get caption element */
171
- getCaption(): HTMLTableCaptionElement | null;
172
- /** Get thead element */
173
- getTHead(): HTMLTableSectionElement | null;
174
- /** Get tfoot element */
175
- getTFoot(): HTMLTableSectionElement | null;
176
- /** Get all tbody elements */
177
- getTBodies(): HTMLCollectionOf<HTMLTableSectionElement>;
178
- /** Get primary tbody (first one, created if needed) */
179
- getPrimaryTBody(): HTMLTableSectionElement;
180
- /** Get all rows in tbody sections */
181
- getBodyRows(): readonly HTMLTableRowElement[];
182
- /** Get row by index (body rows only) */
183
- getRow(index: number): HTMLTableRowElement | undefined;
184
- /** Get row by ID */
185
- getRowById(id: string): HTMLTableRowElement | undefined;
186
- /** Get cell at position */
187
- getCell(row: number, column: number): HTMLTableCellElement | undefined;
188
- /** Get cell by row ID and column index */
189
- getCellByRowId(rowId: string, column: number): HTMLTableCellElement | undefined;
190
- /** Get current headers */
191
- getHeaders(): string[];
192
- /** Get header at index */
193
- getHeader(index: number): string | undefined;
194
- /** Get body data as 2D array */
195
- getData(): CellValue[][];
196
- /** Get row data by index */
197
- getRowData(index: number): CellValue[] | undefined;
198
- /** Get row data by ID */
199
- getRowDataById(id: string): CellValue[] | undefined;
200
- /** Get cell value */
201
- getCellValue(row: number, column: number): CellValue;
202
- /** Get column data */
203
- getColumnData(index: number): CellValue[];
204
- /** Get footer data */
205
- getFooterData(): CellValue[] | undefined;
206
- /** Get row count (body rows only) */
207
- getRowCount(): number;
208
- /** Get column count (based on headers or first row) */
209
- getColumnCount(): number;
210
- /** Get row ID by index */
211
- getRowId(index: number): string | undefined;
212
- /** Get row index by ID */
213
- getRowIndex(id: string): number;
214
- /** Get all row IDs */
215
- getAllRowIds(): string[];
216
- /** Create or get caption */
198
+ export declare interface TableInstance extends ElementInstance<HTMLTableElement> {
199
+ /** Get/set caption element */
200
+ getTableCaption(): HTMLTableCaptionElement | null;
201
+ setTableCaption(caption: HTMLTableCaptionElement | null): void;
202
+ /** Create and return caption (or return existing) */
217
203
  createCaption(): HTMLTableCaptionElement;
218
- /** Delete caption */
204
+ /** Delete caption if exists */
219
205
  deleteCaption(): void;
220
- /** Create or get thead */
206
+ /** Get/set thead element */
207
+ getTHead(): HTMLTableSectionElement | null;
208
+ setTHead(thead: HTMLTableSectionElement | null): void;
209
+ /** Create and return thead (or return existing) */
221
210
  createTHead(): HTMLTableSectionElement;
222
- /** Delete thead */
211
+ /** Delete thead if exists */
223
212
  deleteTHead(): void;
224
- /** Create or get tfoot */
213
+ /** Get/set tfoot element */
214
+ getTFoot(): HTMLTableSectionElement | null;
215
+ setTFoot(tfoot: HTMLTableSectionElement | null): void;
216
+ /** Create and return tfoot (or return existing) */
225
217
  createTFoot(): HTMLTableSectionElement;
226
- /** Delete tfoot */
218
+ /** Delete tfoot if exists */
227
219
  deleteTFoot(): void;
228
- /** Create a new tbody */
220
+ /** Get tBodies collection */
221
+ getTBodies(): HTMLCollectionOf<HTMLTableSectionElement>;
222
+ /** Create and insert new tbody */
229
223
  createTBody(): HTMLTableSectionElement;
230
- /** Set all headers */
224
+ /** Get rows collection (all rows in table) */
225
+ getTableRows(): HTMLCollectionOf<HTMLTableRowElement>;
226
+ /** Insert row at index (-1 = end) */
227
+ insertTableRow(index?: number): HTMLTableRowElement;
228
+ /** Delete row at index */
229
+ deleteTableRow(index: number): void;
230
+ /** Get header texts from thead */
231
+ getHeaders(): readonly string[];
232
+ /** Set headers (creates/updates thead) */
231
233
  setHeaders(headers: readonly string[]): void;
232
- /** Set single header */
233
- setHeader(index: number, text: string): void;
234
- /** Add header column */
234
+ /** Add single header at index */
235
235
  addHeader(text: string, index?: number): void;
236
- /** Remove header column */
236
+ /** Remove header at index */
237
237
  removeHeader(index: number): void;
238
- /** Add a row with data */
239
- addRow(data: RowData, index?: number, id?: string): HTMLTableRowElement;
240
- /** Remove row by index */
241
- removeRow(index: number): CellValue[] | undefined;
242
- /** Remove row by ID */
243
- removeRowById(id: string): CellValue[] | undefined;
244
- /** Update entire row */
238
+ /** Clear all headers */
239
+ clearHeaders(): void;
240
+ /** Get count of body rows */
241
+ getRowCount(): number;
242
+ /** Get all body rows */
243
+ getBodyRows(): readonly HTMLTableRowElement[];
244
+ /** Get row at index */
245
+ getRow(index: number): HTMLTableRowElement | null;
246
+ /** Add row with data */
247
+ addRow(data: RowData, index?: number): HTMLTableRowElement;
248
+ /** Remove row at index, return data */
249
+ removeRow(index: number): RowData | null;
250
+ /** Update row data */
245
251
  updateRow(index: number, data: RowData): void;
246
- /** Update row by ID */
247
- updateRowById(id: string, data: RowData): void;
248
- /** Move row from one index to another */
249
- moveRow(fromIndex: number, toIndex: number): void;
250
- /** Swap two rows */
251
- swapRows(indexA: number, indexB: number): void;
252
252
  /** Clear all body rows */
253
253
  clearRows(): void;
254
- /** Add a column */
255
- addColumn(header: string, defaultValue?: CellValue, index?: number): void;
256
- /** Remove a column */
254
+ /** Get row by data-id */
255
+ getRowById(id: string): HTMLTableRowElement | null;
256
+ /** Get ID of row at index */
257
+ getRowId(index: number): string | null;
258
+ /** Add row with specific ID */
259
+ addRowWithId(data: RowData, id: string, index?: number): HTMLTableRowElement;
260
+ /** Remove row by ID */
261
+ removeRowById(id: string): RowData | null;
262
+ /** Get cell at row, col */
263
+ getCell(row: number, col: number): HTMLTableCellElement | null;
264
+ /** Get cell value */
265
+ getCellValue(row: number, col: number): CellValue;
266
+ /** Set cell value */
267
+ setCell(row: number, col: number, value: CellValue): void;
268
+ /** Get column count */
269
+ getColumnCount(): number;
270
+ /** Add column (header + cells) */
271
+ addColumn(header?: string, index?: number): void;
272
+ /** Remove column */
257
273
  removeColumn(index: number): void;
258
- /** Move column */
259
- moveColumn(fromIndex: number, toIndex: number): void;
260
- /** Swap two columns */
261
- swapColumns(indexA: number, indexB: number): void;
274
+ /** Get column data */
275
+ getColumnData(index: number): readonly CellValue[];
262
276
  /** Set column data */
263
277
  setColumnData(index: number, data: readonly CellValue[]): void;
264
- /** Set cell value */
265
- setCell(row: number, column: number, value: CellValue): void;
266
- /** Set cell by row ID */
267
- setCellByRowId(rowId: string, column: number, value: CellValue): void;
268
- /** Set cell range */
269
- setCellRange(startRow: number, startColumn: number, data: TableData): void;
278
+ /** Get all body data */
279
+ getTableData(): TableData;
280
+ /** Set all body data */
281
+ setTableData(data: TableData): void;
282
+ /** Get footer row data */
283
+ getFooter(): RowData | null;
270
284
  /** Set footer row */
271
285
  setFooter(data: RowData): void;
272
- /** Set footer cell */
273
- setFooterCell(index: number, value: CellValue): void;
274
- /** Get footer cell */
275
- getFooterCell(index: number): CellValue;
276
286
  /** Clear footer */
277
287
  clearFooter(): void;
278
- /** Set caption text */
279
- setCaption(text: string): void;
280
288
  /** Get caption text */
281
- getCaptionText(): string | undefined;
282
- /** Set all data (replaces body rows) */
283
- setData(data: TableData): void;
284
- /** Reset table (clear all content) */
285
- reset(): void;
286
- /** Sync internal state with DOM (if external changes made) */
287
- sync(): void;
288
- /** Set records with column mapping */
289
- setRecords<T extends BaseRecord>(records: readonly T[], fields: readonly (keyof T | ((record: T) => CellValue))[]): void;
290
- /** Get record by ID */
291
- getRecordData(id: string): CellValue[] | undefined;
292
- /** Add a record */
293
- addRecord<T extends BaseRecord>(record: T | Omit<T, 'id'>, fields: readonly (keyof T | ((record: T) => CellValue))[], index?: number): string;
294
- /** Update a record by ID */
295
- updateRecordRow(id: string, data: RowData): boolean;
296
- /** Remove a record by ID */
297
- removeRecord(id: string): boolean;
298
- /** Check if record exists */
299
- hasRecord(id: string): boolean;
300
- /** Set the ID generator function */
301
- setIdGenerator(generator: IdGenerator): void;
302
- /** Generate a new ID */
303
- generateId(): string;
304
- /** Subscribe to row add events */
305
- onRowAdd(callback: RowAddCallback): () => void;
306
- /** Subscribe to row remove events */
307
- onRowRemove(callback: RowRemoveCallback): () => void;
308
- /** Subscribe to row update events */
309
- onRowUpdate(callback: RowUpdateCallback): () => void;
310
- /** Subscribe to cell change events */
311
- onCellChange(callback: CellChangeCallback): () => void;
312
- /** Subscribe to header change events */
313
- onHeaderChange(callback: HeaderChangeCallback): () => void;
314
- /** Subscribe to data change events */
315
- onDataChange(callback: DataChangeCallback): () => void;
316
- /** Destroy and clean up */
317
- destroy(): void;
289
+ getCaptionText(): string | null;
290
+ /** Set caption text */
291
+ setCaptionText(text: string): void;
292
+ /** Move row from one index to another */
293
+ moveRow(fromIndex: number, toIndex: number): void;
294
+ /** Swap two rows */
295
+ swapRows(index1: number, index2: number): void;
296
+ /** Subscribe to row add */
297
+ onRowAdd(callback: (index: number, id: string | null) => void): () => void;
298
+ /** Subscribe to row remove */
299
+ onRowRemove(callback: (index: number, id: string | null) => void): () => void;
300
+ /** Subscribe to data change */
301
+ onDataChange(callback: () => void): () => void;
318
302
  }
319
303
 
320
304
  /**
321
305
  * Vue 3 composable for HTML table manipulation.
322
306
  *
323
- * Wraps createTable with Vue reactivity and state management.
324
- * Uses native table DOM APIs - no querySelector/querySelectorAll.
307
+ * Wraps createTable with reactive state and Vue-specific integration.
308
+ * Follows the DOM-first architecture where the HTML table element is the source of truth.
325
309
  *
326
310
  * @param elementRef - Ref to the HTML table element
327
- * @param initialData - Optional initial body data
311
+ * @param initialData - Initial body data
328
312
  * @param options - Configuration options
329
- * @returns UseTableReturn for reactive table manipulation
313
+ * @returns UseTableReturn with reactive state and methods
330
314
  *
331
315
  * @example
332
316
  * ```vue
333
- * <script setup lang="ts">
317
+ * <script setup>
334
318
  * import { ref, onMounted } from 'vue'
335
319
  * import { useTable } from '@mikestools/usetable'
336
320
  *
337
- * const tableRef = ref<HTMLTableElement>()
321
+ * const tableRef = ref<HTMLTableElement | null>(null)
338
322
  *
339
- * onMounted(() => {
340
- * if (! tableRef.value) return
341
- *
342
- * const table = useTable(ref(tableRef.value), [
343
- * ['Alice', 30],
344
- * ['Bob', 25]
345
- * ], {
346
- * headers: ['Name', 'Age']
347
- * })
348
- *
349
- * // Reactive access
350
- * console. log(table.data. value)
351
- * console.log(table.rowCount. value)
352
- *
353
- * // Mutations
354
- * table.addRow(['Carol', 35])
355
- * table.setCell(0, 1, 31)
323
+ * const {
324
+ * data,
325
+ * headers,
326
+ * rowCount,
327
+ * addRow,
328
+ * setCell
329
+ * } = useTable(tableRef, [
330
+ * ['Alice', 30],
331
+ * ['Bob', 25]
332
+ * ], {
333
+ * headers: ['Name', 'Age']
356
334
  * })
357
335
  * </script>
358
336
  *
@@ -361,7 +339,7 @@ export declare interface TableInstance {
361
339
  * </template>
362
340
  * ```
363
341
  */
364
- export declare function useTable(elementRef: Ref<HTMLTableElement>, initialData?: TableData, options?: UseTableOptions): UseTableReturn;
342
+ export declare function useTable(elementRef: MaybeRef<HTMLTableElement | null>, initialData?: TableData, options?: UseTableOptions): UseTableReturn;
365
343
 
366
344
  /**
367
345
  * Options for useTable composable.
@@ -372,10 +350,12 @@ export declare type UseTableOptions = CreateTableOptions;
372
350
  * Return type for useTable composable.
373
351
  */
374
352
  export declare interface UseTableReturn {
375
- /** Underlying table instance */
376
- readonly instance: TableInstance;
377
- /** The table element */
378
- readonly element: Readonly<Ref<HTMLTableElement>>;
353
+ /** Underlying table instance (for advanced usage) */
354
+ readonly instance: Readonly<Ref<TableInstance | null>>;
355
+ /** Whether the table is initialized */
356
+ readonly isInitialized: ComputedRef<boolean>;
357
+ /** The table element reference */
358
+ readonly element: Readonly<Ref<HTMLTableElement | null>>;
379
359
  /** Reactive headers */
380
360
  readonly headers: ComputedRef<readonly string[]>;
381
361
  /** Reactive body data */
@@ -387,9 +367,9 @@ export declare interface UseTableReturn {
387
367
  /** Reactive row IDs */
388
368
  readonly rowIds: ComputedRef<readonly string[]>;
389
369
  /** Reactive footer data */
390
- readonly footerData: ComputedRef<readonly CellValue[] | undefined>;
370
+ readonly footerData: ComputedRef<readonly CellValue[] | null>;
391
371
  /** Reactive caption text */
392
- readonly captionText: ComputedRef<string | undefined>;
372
+ readonly captionText: ComputedRef<string | null>;
393
373
  /** Version counter for reactivity (incremented on changes) */
394
374
  readonly version: Readonly<Ref<number>>;
395
375
  /** Selection state */
@@ -397,91 +377,77 @@ export declare interface UseTableReturn {
397
377
  /** Focus state */
398
378
  readonly focus: FocusState;
399
379
  /** Create or get caption */
400
- createCaption(): HTMLTableCaptionElement;
380
+ createCaption(): HTMLTableCaptionElement | null;
401
381
  /** Delete caption */
402
382
  deleteCaption(): void;
403
383
  /** Create or get thead */
404
- createTHead(): HTMLTableSectionElement;
384
+ createTHead(): HTMLTableSectionElement | null;
405
385
  /** Delete thead */
406
386
  deleteTHead(): void;
407
387
  /** Create or get tfoot */
408
- createTFoot(): HTMLTableSectionElement;
388
+ createTFoot(): HTMLTableSectionElement | null;
409
389
  /** Delete tfoot */
410
390
  deleteTFoot(): void;
411
391
  /** Create a new tbody */
412
- createTBody(): HTMLTableSectionElement;
392
+ createTBody(): HTMLTableSectionElement | null;
413
393
  /** Set all headers */
414
394
  setHeaders(headers: readonly string[]): void;
415
- /** Set single header */
416
- setHeader(index: number, text: string): void;
417
395
  /** Add header column */
418
396
  addHeader(text: string, index?: number): void;
419
397
  /** Remove header column */
420
398
  removeHeader(index: number): void;
399
+ /** Clear all headers */
400
+ clearHeaders(): void;
421
401
  /** Add a row with data */
422
- addRow(data: RowData, index?: number, id?: string): HTMLTableRowElement;
402
+ addRow(data: RowData, index?: number): HTMLTableRowElement | null;
403
+ /** Add a row with specific ID */
404
+ addRowWithId(data: RowData, id: string, index?: number): HTMLTableRowElement | null;
423
405
  /** Remove row by index */
424
- removeRow(index: number): CellValue[] | undefined;
406
+ removeRow(index: number): RowData | null;
425
407
  /** Remove row by ID */
426
- removeRowById(id: string): CellValue[] | undefined;
408
+ removeRowById(id: string): RowData | null;
427
409
  /** Update entire row */
428
410
  updateRow(index: number, data: RowData): void;
429
- /** Update row by ID */
430
- updateRowById(id: string, data: RowData): void;
411
+ /** Clear all body rows */
412
+ clearRows(): void;
413
+ /** Get row by index */
414
+ getRow(index: number): HTMLTableRowElement | null;
415
+ /** Get row by ID */
416
+ getRowById(id: string): HTMLTableRowElement | null;
417
+ /** Get row ID by index */
418
+ getRowId(index: number): string | null;
431
419
  /** Move row from one index to another */
432
420
  moveRow(fromIndex: number, toIndex: number): void;
433
421
  /** Swap two rows */
434
- swapRows(indexA: number, indexB: number): void;
435
- /** Clear all body rows */
436
- clearRows(): void;
422
+ swapRows(index1: number, index2: number): void;
437
423
  /** Add a column */
438
- addColumn(header: string, defaultValue?: CellValue, index?: number): void;
424
+ addColumn(header?: string, index?: number): void;
439
425
  /** Remove a column */
440
426
  removeColumn(index: number): void;
441
- /** Move column */
442
- moveColumn(fromIndex: number, toIndex: number): void;
443
- /** Swap two columns */
444
- swapColumns(indexA: number, indexB: number): void;
427
+ /** Get column data */
428
+ getColumnData(index: number): readonly CellValue[];
445
429
  /** Set column data */
446
430
  setColumnData(index: number, data: readonly CellValue[]): void;
431
+ /** Get cell element */
432
+ getCell(row: number, column: number): HTMLTableCellElement | null;
447
433
  /** Get cell value */
448
- getCell(row: number, column: number): CellValue;
434
+ getCellValue(row: number, column: number): CellValue;
449
435
  /** Set cell value */
450
436
  setCell(row: number, column: number, value: CellValue): void;
451
- /** Set cell by row ID */
452
- setCellByRowId(rowId: string, column: number, value: CellValue): void;
453
- /** Set cell range */
454
- setCellRange(startRow: number, startColumn: number, data: TableData): void;
455
- /** Get cell element */
456
- getCellElement(row: number, column: number): HTMLTableCellElement | undefined;
457
- /** Get row data by index */
458
- getRowData(index: number): CellValue[] | undefined;
459
- /** Get row data by ID */
460
- getRowDataById(id: string): CellValue[] | undefined;
461
- /** Get row element */
462
- getRowElement(index: number): HTMLTableRowElement | undefined;
463
- /** Get row by ID */
464
- getRowById(id: string): HTMLTableRowElement | undefined;
465
- /** Get row ID by index */
466
- getRowId(index: number): string | undefined;
467
- /** Get row index by ID */
468
- getRowIndex(id: string): number;
469
- /** Get column data */
470
- getColumnData(index: number): CellValue[];
437
+ /** Get footer data */
438
+ getFooter(): RowData | null;
471
439
  /** Set footer row */
472
440
  setFooter(data: RowData): void;
473
- /** Set footer cell */
474
- setFooterCell(index: number, value: CellValue): void;
475
- /** Get footer cell */
476
- getFooterCell(index: number): CellValue;
477
441
  /** Clear footer */
478
442
  clearFooter(): void;
443
+ /** Get caption text */
444
+ getCaption(): string | null;
479
445
  /** Set caption text */
480
446
  setCaption(text: string): void;
447
+ /** Get all table data */
448
+ getData(): TableData;
481
449
  /** Set all data (replaces body rows) */
482
450
  setData(data: TableData): void;
483
- /** Reset table (clear all content) */
484
- reset(): void;
485
451
  /** Sync internal state with DOM */
486
452
  sync(): void;
487
453
  /** Select a row by index */
@@ -494,14 +460,16 @@ export declare interface UseTableReturn {
494
460
  selectAllRows(): void;
495
461
  /** Deselect all rows */
496
462
  deselectAllRows(): void;
497
- /** Select row range */
498
- selectRowRange(startIndex: number, endIndex: number): void;
499
463
  /** Check if row is selected */
500
464
  isRowSelected(index: number): boolean;
501
465
  /** Get selected row indices */
502
466
  getSelectedRowIndices(): readonly number[];
503
467
  /** Get selected row data */
504
468
  getSelectedRowData(): readonly (readonly CellValue[])[];
469
+ /** Select a range of rows (from anchor to target) */
470
+ selectRowRange(fromIndex: number, toIndex: number): void;
471
+ /** Select row with modifier key awareness (Ctrl/Cmd, Shift) */
472
+ selectRowWithModifiers(index: number, ctrlKey: boolean, shiftKey: boolean): void;
505
473
  /** Select a cell */
506
474
  selectCell(row: number, column: number): void;
507
475
  /** Deselect a cell */
@@ -528,51 +496,19 @@ export declare interface UseTableReturn {
528
496
  moveFocusLeft(): boolean;
529
497
  /** Move focus right */
530
498
  moveFocusRight(): boolean;
531
- /** Move focus to first cell */
532
- moveFocusToFirst(): void;
533
- /** Move focus to last cell */
534
- moveFocusToLast(): void;
535
499
  /** Enable keyboard navigation (returns cleanup function) */
536
500
  enableKeyboardNavigation(): () => void;
537
- /** Set records with column mapping */
538
- setRecords<T extends BaseRecord>(records: readonly T[], fields: readonly (keyof T | ((record: T) => CellValue))[]): void;
539
- /** Get record data by ID */
540
- getRecordData(id: string): CellValue[] | undefined;
541
- /** Add a record */
542
- addRecord<T extends BaseRecord>(record: T | Omit<T, 'id'>, fields: readonly (keyof T | ((record: T) => CellValue))[], index?: number): string;
543
- /** Update a record row by ID */
544
- updateRecordRow(id: string, data: RowData): boolean;
545
- /** Remove a record by ID */
546
- removeRecord(id: string): boolean;
547
- /** Check if record exists */
548
- hasRecord(id: string): boolean;
549
- /** Get selected record IDs */
550
- getSelectedRecordIds(): readonly string[];
551
- /** Select records by IDs */
552
- selectRecords(ids: readonly string[]): void;
553
- /** Deselect records by IDs */
554
- deselectRecords(ids: readonly string[]): void;
555
- /** Set the ID generator function */
556
- setIdGenerator(generator: IdGenerator): void;
557
- /** Generate a new ID */
558
- generateId(): string;
559
501
  /** Subscribe to row add events */
560
- onRowAdd(callback: RowAddCallback): () => void;
502
+ onRowAdd(callback: (index: number, id: string | null) => void): () => void;
561
503
  /** Subscribe to row remove events */
562
- onRowRemove(callback: RowRemoveCallback): () => void;
563
- /** Subscribe to row update events */
564
- onRowUpdate(callback: RowUpdateCallback): () => void;
565
- /** Subscribe to cell change events */
566
- onCellChange(callback: CellChangeCallback): () => void;
567
- /** Subscribe to header change events */
568
- onHeaderChange(callback: HeaderChangeCallback): () => void;
504
+ onRowRemove(callback: (index: number, id: string | null) => void): () => void;
569
505
  /** Subscribe to data change events */
570
- onDataChange(callback: DataChangeCallback): () => void;
506
+ onDataChange(callback: () => void): () => void;
571
507
  /** Subscribe to selection change events */
572
- onSelectionChange(callback: (selectedRows: ReadonlySet<number>, selectedCells: ReadonlySet<string>) => void): () => void;
508
+ onSelectionChange(callback: (rows: ReadonlySet<number>, cells: ReadonlySet<string>) => void): () => void;
573
509
  /** Subscribe to focus change events */
574
510
  onFocusChange(callback: (cell: CellPosition | null) => void): () => void;
575
- /** Destroy and clean up */
511
+ /** Destroy and cleanup */
576
512
  destroy(): void;
577
513
  }
578
514