@mikestools/usetable 0.0.2 → 0.0.4

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,15 +1,6 @@
1
+ import { ComputedRef } from 'vue';
1
2
  import { Ref } from 'vue';
2
3
 
3
- /**
4
- * Configuration for custom aggregation.
5
- */
6
- export declare interface AggregateConfig<T> {
7
- /** Initial accumulator value */
8
- readonly initial: T;
9
- /** Reducer function */
10
- readonly reducer: (accumulator: T, value: unknown, rowIndex: number) => T;
11
- }
12
-
13
4
  /**
14
5
  * Base record interface - all records must have an id.
15
6
  * This is the foundation for the shared reactive data schema.
@@ -20,129 +11,71 @@ export declare interface BaseRecord {
20
11
  }
21
12
 
22
13
  /**
23
- * Cell change record for dirty tracking.
14
+ * Cell change record for tracking modifications.
24
15
  */
25
16
  export declare interface CellChange {
26
- /** Row index */
27
17
  readonly row: number;
28
- /** Column index */
29
18
  readonly column: number;
30
- /** Previous value */
31
- readonly oldValue: unknown;
32
- /** New value */
33
- readonly newValue: unknown;
19
+ readonly oldValue: CellValue;
20
+ readonly newValue: CellValue;
34
21
  }
35
22
 
36
- /**
37
- * Configuration for a table cell with content and attributes.
38
- */
39
- export declare interface CellConfig {
40
- /** The cell value - can be any type including HTML elements */
41
- readonly value: unknown;
42
- /** Optional HTML attributes to apply to the cell */
43
- readonly attributes?: ElementAttributes;
44
- /** Column span (colspan attribute) */
45
- readonly columnSpan?: number;
46
- /** Row span (rowspan attribute) */
47
- readonly rowSpan?: number;
48
- }
23
+ export declare type CellChangeCallback = (row: number, column: number, oldValue: CellValue, newValue: CellValue) => void;
49
24
 
50
25
  /**
51
- * Cell position for focus/navigation.
26
+ * Cell position for navigation and selection.
52
27
  */
53
28
  export declare interface CellPosition {
54
- /** Row index */
55
29
  readonly row: number;
56
- /** Column index */
57
30
  readonly column: number;
58
31
  }
59
32
 
60
33
  /**
61
- * Validator function for a single cell.
62
- * Returns true if valid, or a string error message if invalid.
63
- */
64
- export declare type CellValidator = (value: unknown) => boolean | string;
65
-
66
- /**
67
- * Configuration for a table column.
68
- */
69
- export declare interface ColumnConfig {
70
- /** Header content - string or CellConfig */
71
- readonly header: string | CellConfig;
72
- /** Default value for new cells in this column */
73
- readonly defaultValue?: unknown;
74
- /** Default attributes for cells in this column */
75
- readonly defaultAttributes?: ElementAttributes;
76
- }
77
-
78
- /**
79
- * Column definition for type parsing/formatting.
34
+ * Cell value can be a string, number, or DOM element.
80
35
  */
81
- export declare interface ColumnDefinition {
82
- /** Data type of the column */
83
- readonly type: 'string' | 'number' | 'date' | 'boolean';
84
- /** Custom parser function */
85
- readonly parser?: (value: unknown) => unknown;
86
- /** Custom formatter function */
87
- readonly formatter?: (value: unknown) => string;
88
- /** Default value when cell is empty */
89
- readonly defaultValue?: unknown;
90
- /** Whether null/undefined values are allowed */
91
- readonly nullable?: boolean;
92
- }
36
+ export declare type CellValue = string | number | boolean | null | undefined | HTMLElement | Node;
93
37
 
94
38
  /**
95
- * Configuration for computed columns.
39
+ * Create a table instance for manipulating an HTML table element.
40
+ *
41
+ * Uses native table DOM APIs exclusively - no querySelector/querySelectorAll.
42
+ * DOM-first architecture where the HTML table is the source of truth.
43
+ *
44
+ * @param element - The HTML table element
45
+ * @param initialData - Optional initial body data
46
+ * @param options - Configuration options
47
+ * @returns TableInstance for table manipulation
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const table = document.createElement('table')
52
+ * const instance = createTable(table, [['Alice', 30], ['Bob', 25]], {
53
+ * headers: ['Name', 'Age'],
54
+ * caption: 'Users'
55
+ * })
56
+ *
57
+ * instance.addRow(['Carol', 35])
58
+ * instance.setCell(0, 1, 31)
59
+ * console.log(instance. getData())
60
+ * ```
96
61
  */
97
- export declare interface ComputedColumnConfig {
98
- /** Function to compute the column value from row data */
99
- readonly computeFunction: (row: unknown[]) => unknown;
100
- /** Column header label */
101
- readonly label: string;
102
- /** Position to insert the column */
103
- readonly index?: number;
104
- }
62
+ export declare function createTable(element: HTMLTableElement, initialData?: TableData, options?: CreateTableOptions): TableInstance;
105
63
 
106
64
  /**
107
- * Configuration for editable cells.
65
+ * Options for creating a table.
108
66
  */
109
- export declare interface EditableConfig {
110
- /** Enable cell editing */
111
- readonly cells?: boolean;
112
- /** Enable header editing */
113
- readonly headers?: boolean;
114
- /** Enable footer editing */
115
- readonly footers?: boolean;
116
- /** Specific columns that are editable */
117
- readonly editableColumns?: readonly number[];
118
- /** Specific rows that are editable */
119
- readonly editableRows?: readonly number[];
120
- /** Validator function */
121
- readonly validator?: (value: string, row: number, column: number) => boolean | string;
122
- /** Parser function to convert string input to stored value */
123
- readonly parser?: (value: string, row: number, column: number) => unknown;
124
- /** Callback when a cell is edited */
125
- readonly onEdit?: (value: unknown, row: number, column: number) => void;
67
+ export declare interface CreateTableOptions {
68
+ /** Initial headers */
69
+ readonly headers?: readonly string[];
70
+ /** Initial footer data */
71
+ readonly footer?: RowData;
72
+ /** Caption text */
73
+ readonly caption?: string;
74
+ /** ID generator for records */
75
+ readonly idGenerator?: IdGenerator;
126
76
  }
127
77
 
128
- /**
129
- * Comprehensive HTML element attributes for table elements.
130
- * Supports class, style, data attributes, ARIA attributes, and event handlers.
131
- */
132
- export declare interface ElementAttributes extends Partial<Omit<HTMLElement, 'style' | 'className' | 'classList' | 'children' | 'childNodes' | 'parentNode' | 'parentElement' | 'attributes' | 'tagName' | 'namespaceURI' | 'shadowRoot' | 'assignedSlot' | 'offsetParent' | 'offsetTop' | 'offsetLeft' | 'offsetWidth' | 'offsetHeight' | 'clientTop' | 'clientLeft' | 'clientWidth' | 'clientHeight' | 'scrollTop' | 'scrollLeft' | 'scrollWidth' | 'scrollHeight' | 'innerHTML' | 'outerHTML' | 'innerText' | 'outerText' | 'textContent' | 'addEventListener' | 'removeEventListener' | 'dispatchEvent' | 'getAttribute' | 'setAttribute' | 'removeAttribute' | 'hasAttribute' | 'appendChild' | 'removeChild' | 'replaceChild' | 'insertBefore' | 'querySelector' | 'querySelectorAll' | 'getElementsByTagName' | 'getElementsByClassName' | 'getElementById' | 'animate' | 'getAnimations' | 'attachShadow' | 'closest' | 'matches' | 'webkitMatchesSelector' | 'getBoundingClientRect' | 'getClientRects' | 'scrollIntoView' | 'scroll' | 'scrollBy' | 'scrollTo' | 'focus' | 'blur' | 'click'>>, Partial<GlobalEventHandlers>, Partial<ARIAMixin> {
133
- /** CSS class - string, array of strings, or object with boolean values */
134
- class?: string | string[] | Record<string, boolean>;
135
- /** Inline styles - string or object */
136
- style?: string | Partial<CSSStyleDeclaration> | Record<string, string | number>;
137
- /** Data attributes as object */
138
- dataset?: Record<string, string>;
139
- /** Data attributes with prefix */
140
- [key: `data-${string}`]: string | undefined;
141
- /** ARIA attributes with prefix */
142
- [key: `aria-${string}`]: string | undefined;
143
- /** Allow any other attributes */
144
- [key: string]: unknown;
145
- }
78
+ export declare type DataChangeCallback = (data: CellValue[][]) => void;
146
79
 
147
80
  /**
148
81
  * Ensure a record has an ID, generating one if missing.
@@ -151,34 +84,26 @@ export declare function ensureId<T extends Record<string, unknown>>(record: T, g
151
84
  id: string;
152
85
  };
153
86
 
154
- /**
155
- * Filter state for tracking row filtering.
156
- */
157
- export declare interface FilterState {
158
- /** Whether any filter is active */
159
- readonly isFiltered: Readonly<Ref<boolean>>;
160
- /** Number of visible rows after filtering */
161
- readonly filteredRowCount: Readonly<Ref<number>>;
162
- /** Indices of visible rows */
163
- readonly filteredIndices: Readonly<Ref<readonly number[]>>;
164
- }
165
-
166
87
  /**
167
88
  * Find record by ID in array.
168
89
  */
169
90
  export declare function findById<T extends BaseRecord>(records: readonly T[], id: string): T | undefined;
170
91
 
171
92
  /**
172
- * Validator function for all cells.
173
- * Returns null if valid, or a string error message if invalid.
93
+ * Focus state.
174
94
  */
175
- export declare type FullValidator = (value: unknown, row: number, column: number) => string | null;
95
+ export declare interface FocusState {
96
+ /** Currently focused cell position */
97
+ readonly cell: Readonly<Ref<CellPosition | null>>;
98
+ }
176
99
 
177
100
  /**
178
101
  * Default ID generator using crypto.randomUUID.
179
102
  */
180
103
  export declare function generateId(): string;
181
104
 
105
+ export declare type HeaderChangeCallback = (headers: readonly string[]) => void;
106
+
182
107
  /**
183
108
  * Symbol for tracking auto-generated IDs.
184
109
  * Internal use only - invisible to JSON.stringify, Object.keys, for...in.
@@ -195,534 +120,406 @@ export declare type IdGenerator = () => string;
195
120
  */
196
121
  export declare function indexById<T extends BaseRecord>(records: readonly T[], id: string): number;
197
122
 
198
- /**
199
- * Type guard for CellConfig.
200
- */
201
- export declare function isCellConfig(value: unknown): value is CellConfig;
202
-
203
- /**
204
- * Type guard for ValidationError.
205
- */
206
- export declare function isValidationError(value: unknown): value is ValidationError;
207
-
208
- /**
209
- * Type guard for ValidationError array.
210
- */
211
- export declare function isValidationErrorArray(value: unknown): value is ValidationError[];
212
-
213
- /**
214
- * Type guard for ValidationResult.
215
- */
216
- export declare function isValidationResult(value: unknown): value is ValidationResult;
217
-
218
123
  /**
219
124
  * Check if a value is a valid ID.
220
125
  */
221
126
  export declare function isValidId(value: unknown): value is string;
222
127
 
223
128
  /**
224
- * Pagination configuration.
129
+ * Event callback types.
225
130
  */
226
- export declare interface PaginationConfig {
227
- /** Number of rows per page */
228
- readonly pageSize: number;
229
- /** Initial page (1-based) */
230
- readonly currentPage?: number;
231
- }
131
+ export declare type RowAddCallback = (rowData: CellValue[], rowIndex: number, rowId: string | undefined) => void;
232
132
 
233
133
  /**
234
- * Pagination state.
134
+ * Row data is an array of cell values.
235
135
  */
236
- export declare interface PaginationState {
237
- /** Total number of pages */
238
- readonly totalPages: Readonly<Ref<number>>;
239
- /** Current page (1-based) */
240
- readonly currentPage: Ref<number>;
241
- /** Number of rows per page */
242
- readonly pageSize: Ref<number>;
243
- /** Indices of visible rows on current page */
244
- readonly visibleRows: Ref<number[]>;
245
- }
246
-
247
- /* Excluded from this release type: ReactiveCellCollection */
136
+ export declare type RowData = readonly CellValue[];
248
137
 
249
- /* Excluded from this release type: ReactiveRowCollection */
250
-
251
- /* Excluded from this release type: ReactiveTBodyCollection */
252
-
253
- /**
254
- * Column definition for record-based tables.
255
- * Maps record fields to table columns.
256
- */
257
- export declare interface RecordColumnDef<T extends BaseRecord = BaseRecord> {
258
- /** Field name (string) or accessor function */
259
- readonly field: string | ((record: T) => unknown);
260
- /** Column header text */
261
- readonly header: string;
262
- /** Format value for display */
263
- readonly format?: (value: unknown, record: T) => string;
264
- /** Parse display value back to data value */
265
- readonly parse?: (value: string, record: T) => unknown;
266
- /** Whether column is editable (default: true for fields, false for functions) */
267
- readonly editable?: boolean;
268
- /** Column width */
269
- readonly width?: string | number;
270
- /** Default value for new records */
271
- readonly defaultValue?: unknown;
272
- }
138
+ export declare type RowRemoveCallback = (rowData: CellValue[], rowIndex: number, rowId: string | undefined) => void;
273
139
 
274
- /**
275
- * Options for record-based table configuration.
276
- */
277
- export declare interface RecordTableOptions<T extends BaseRecord = BaseRecord> {
278
- /** Column definitions mapping fields to columns */
279
- readonly columns: readonly RecordColumnDef<T>[];
280
- /** ID generator for new records */
281
- readonly idGenerator?: IdGenerator;
282
- /** Callback when a cell is edited */
283
- readonly onCellEdit?: (recordId: string, field: keyof T | string, value: unknown) => void;
284
- /** Callback when a row is inserted */
285
- readonly onRowInsert?: (values: Omit<T, 'id'>) => void;
286
- /** Callback when a row is deleted */
287
- readonly onRowDelete?: (recordId: string) => void;
288
- /** Callback when row selection changes */
289
- readonly onRowSelect?: (recordId: string | null) => void;
290
- }
140
+ export declare type RowUpdateCallback = (rowIndex: number, oldData: CellValue[], newData: CellValue[], rowId: string | undefined) => void;
291
141
 
292
142
  /**
293
- * Record-based table state.
143
+ * Selection state.
294
144
  */
295
- export declare interface RecordTableState<T extends BaseRecord = BaseRecord> {
296
- /** All records in the table */
297
- readonly records: readonly T[];
298
- /** Currently selected record ID */
299
- readonly selectedRecordId: string | null;
300
- /** Record IDs in display order */
301
- readonly displayOrder: readonly string[];
145
+ export declare interface SelectionState {
146
+ /** Selected row indices */
147
+ readonly rows: Readonly<Ref<ReadonlySet<number>>>;
148
+ /** Selected cell positions as "row,column" strings */
149
+ readonly cells: Readonly<Ref<ReadonlySet<string>>>;
302
150
  }
303
151
 
304
152
  /**
305
- * Validator function for a row.
306
- * Returns true if valid, or a string error message if invalid.
307
- */
308
- export declare type RowValidator = (rowData: unknown[]) => boolean | string;
309
-
310
- /**
311
- * Options for search operations.
153
+ * Strip generated ID from record (for export).
312
154
  */
313
- export declare interface SearchOptions {
314
- /** Whether search is case-sensitive */
315
- readonly caseSensitive?: boolean;
316
- }
155
+ export declare function stripGeneratedId<T extends {
156
+ id: string;
157
+ }>(record: T): Omit<T, 'id'> | T;
317
158
 
318
159
  /**
319
- * Search result for a found cell.
160
+ * Table data is a 2D array of cell values.
320
161
  */
321
- export declare interface SearchResult {
322
- /** Row index */
323
- readonly row: number;
324
- /** Column index */
325
- readonly column: number;
326
- /** The found value */
327
- readonly value: unknown;
328
- }
162
+ export declare type TableData = readonly RowData[];
329
163
 
330
164
  /**
331
- * Sort state for tracking column sorting.
165
+ * Return type for createTable.
332
166
  */
333
- export declare interface SortState {
334
- /** Currently sorted column index */
335
- readonly columnIndex: Readonly<Ref<number | null>>;
336
- /** Whether sorted ascending */
337
- readonly ascending: Readonly<Ref<boolean>>;
338
- /** Whether sorted descending */
339
- readonly descending: Readonly<Ref<boolean>>;
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 */
217
+ createCaption(): HTMLTableCaptionElement;
218
+ /** Delete caption */
219
+ deleteCaption(): void;
220
+ /** Create or get thead */
221
+ createTHead(): HTMLTableSectionElement;
222
+ /** Delete thead */
223
+ deleteTHead(): void;
224
+ /** Create or get tfoot */
225
+ createTFoot(): HTMLTableSectionElement;
226
+ /** Delete tfoot */
227
+ deleteTFoot(): void;
228
+ /** Create a new tbody */
229
+ createTBody(): HTMLTableSectionElement;
230
+ /** Set all headers */
231
+ setHeaders(headers: readonly string[]): void;
232
+ /** Set single header */
233
+ setHeader(index: number, text: string): void;
234
+ /** Add header column */
235
+ addHeader(text: string, index?: number): void;
236
+ /** Remove header column */
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 */
245
+ 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
+ /** Clear all body rows */
253
+ clearRows(): void;
254
+ /** Add a column */
255
+ addColumn(header: string, defaultValue?: CellValue, index?: number): void;
256
+ /** Remove a column */
257
+ 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;
262
+ /** Set column data */
263
+ 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;
270
+ /** Set footer row */
271
+ 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
+ /** Clear footer */
277
+ clearFooter(): void;
278
+ /** Set caption text */
279
+ setCaption(text: string): void;
280
+ /** 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;
340
318
  }
341
319
 
342
320
  /**
343
- * Strip generated ID from record (for export).
321
+ * Vue 3 composable for HTML table manipulation.
322
+ *
323
+ * Wraps createTable with Vue reactivity and state management.
324
+ * Uses native table DOM APIs - no querySelector/querySelectorAll.
325
+ *
326
+ * @param elementRef - Ref to the HTML table element
327
+ * @param initialData - Optional initial body data
328
+ * @param options - Configuration options
329
+ * @returns UseTableReturn for reactive table manipulation
330
+ *
331
+ * @example
332
+ * ```vue
333
+ * <script setup lang="ts">
334
+ * import { ref, onMounted } from 'vue'
335
+ * import { useTable } from '@mikestools/usetable'
336
+ *
337
+ * const tableRef = ref<HTMLTableElement>()
338
+ *
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)
356
+ * })
357
+ * </script>
358
+ *
359
+ * <template>
360
+ * <table ref="tableRef"></table>
361
+ * </template>
362
+ * ```
344
363
  */
345
- export declare function stripGeneratedId<T extends {
346
- id: string;
347
- }>(record: T): Omit<T, 'id'> | T;
348
-
349
- /* Excluded from this release type: TableCell */
350
-
351
- /* Excluded from this release type: TableRow */
352
-
353
- /* Excluded from this release type: TableSection */
364
+ export declare function useTable(elementRef: Ref<HTMLTableElement>, initialData?: TableData, options?: UseTableOptions): UseTableReturn;
354
365
 
355
366
  /**
356
- * A comprehensive Vue composable for direct HTML table DOM manipulation.
357
- * DOM is the source of truth - data and headers are computed from DOM state.
358
- * @public
367
+ * Options for useTable composable.
359
368
  */
360
- export declare function useTable(element: Ref<HTMLTableElement>): UseTableReturn;
369
+ export declare type UseTableOptions = CreateTableOptions;
361
370
 
362
371
  /**
363
- * Main table composable return type.
364
- *
365
- * Provides comprehensive table manipulation capabilities including:
366
- * - DOM structure methods
367
- * - Data layer methods
368
- * - Sorting, filtering, and searching
369
- * - Selection and focus management
370
- * - Validation and transformation
371
- * - Import/export functionality
372
- * - Undo/redo support
373
- * - Pagination and virtual scrolling
372
+ * Return type for useTable composable.
374
373
  */
375
- export declare interface UseTableReturn extends ReactiveRowCollection, ReactiveTBodyCollection {
374
+ export declare interface UseTableReturn {
375
+ /** Underlying table instance */
376
+ readonly instance: TableInstance;
376
377
  /** The table element */
377
378
  readonly element: Readonly<Ref<HTMLTableElement>>;
378
- /** Caption element */
379
- readonly caption: Ref<HTMLTableCaptionElement | null>;
380
- /** Thead element */
381
- readonly tHead: Ref<HTMLTableSectionElement | null>;
382
- /** Tfoot element */
383
- readonly tFoot: Ref<HTMLTableSectionElement | null>;
384
- /** Table body data as 2D array */
385
- readonly data: Ref<unknown[][]>;
386
- /** Header texts */
387
- readonly headers: Ref<string[]>;
388
- /** Number of columns */
389
- readonly columnCount: Readonly<Ref<number>>;
390
- /** Create or get existing caption */
379
+ /** Reactive headers */
380
+ readonly headers: ComputedRef<readonly string[]>;
381
+ /** Reactive body data */
382
+ readonly data: ComputedRef<readonly (readonly CellValue[])[]>;
383
+ /** Reactive row count */
384
+ readonly rowCount: ComputedRef<number>;
385
+ /** Reactive column count */
386
+ readonly columnCount: ComputedRef<number>;
387
+ /** Reactive row IDs */
388
+ readonly rowIds: ComputedRef<readonly string[]>;
389
+ /** Reactive footer data */
390
+ readonly footerData: ComputedRef<readonly CellValue[] | undefined>;
391
+ /** Reactive caption text */
392
+ readonly captionText: ComputedRef<string | undefined>;
393
+ /** Version counter for reactivity (incremented on changes) */
394
+ readonly version: Readonly<Ref<number>>;
395
+ /** Selection state */
396
+ readonly selection: SelectionState;
397
+ /** Focus state */
398
+ readonly focus: FocusState;
399
+ /** Create or get caption */
391
400
  createCaption(): HTMLTableCaptionElement;
392
401
  /** Delete caption */
393
402
  deleteCaption(): void;
394
- /** Create or get existing thead */
403
+ /** Create or get thead */
395
404
  createTHead(): HTMLTableSectionElement;
396
405
  /** Delete thead */
397
406
  deleteTHead(): void;
398
- /** Create or get existing tfoot */
407
+ /** Create or get tfoot */
399
408
  createTFoot(): HTMLTableSectionElement;
400
409
  /** Delete tfoot */
401
410
  deleteTFoot(): void;
402
- /** Create new tbody */
411
+ /** Create a new tbody */
403
412
  createTBody(): HTMLTableSectionElement;
404
- /** Insert row at index */
405
- insertRow(index?: number): HTMLTableRowElement;
406
- /** Delete row at index */
407
- deleteRow(index: number): void;
408
- /** Get thead as TableSection */
409
- getTHead(): TableSection | undefined;
410
- /** Get tfoot as TableSection */
411
- getTFoot(): TableSection | undefined;
412
- /** Get tbody at index as TableSection */
413
- getTBody(index: number): TableSection | undefined;
414
- /** Get row at index as TableRow */
415
- getRow(index: number): TableRow | undefined;
413
+ /** Set all headers */
414
+ setHeaders(headers: readonly string[]): void;
415
+ /** Set single header */
416
+ setHeader(index: number, text: string): void;
417
+ /** Add header column */
418
+ addHeader(text: string, index?: number): void;
419
+ /** Remove header column */
420
+ removeHeader(index: number): void;
416
421
  /** Add a row with data */
417
- addRow(rowData: readonly unknown[], index?: number): HTMLTableRowElement;
418
- /** Remove row at index */
419
- removeRow(index: number): void;
422
+ addRow(data: RowData, index?: number, id?: string): HTMLTableRowElement;
423
+ /** Remove row by index */
424
+ removeRow(index: number): CellValue[] | undefined;
425
+ /** Remove row by ID */
426
+ removeRowById(id: string): CellValue[] | undefined;
427
+ /** Update entire row */
428
+ updateRow(index: number, data: RowData): void;
429
+ /** Update row by ID */
430
+ updateRowById(id: string, data: RowData): void;
431
+ /** Move row from one index to another */
432
+ moveRow(fromIndex: number, toIndex: number): void;
433
+ /** Swap two rows */
434
+ swapRows(indexA: number, indexB: number): void;
435
+ /** Clear all body rows */
436
+ clearRows(): void;
420
437
  /** Add a column */
421
- addColumn(headerText?: string, defaultValue?: unknown, index?: number): void;
422
- /** Remove column at index */
438
+ addColumn(header: string, defaultValue?: CellValue, index?: number): void;
439
+ /** Remove a column */
423
440
  removeColumn(index: number): void;
424
- /** Set cell value */
425
- setCell(rowIndex: number, columnIndex: number, value: unknown): void;
441
+ /** Move column */
442
+ moveColumn(fromIndex: number, toIndex: number): void;
443
+ /** Swap two columns */
444
+ swapColumns(indexA: number, indexB: number): void;
445
+ /** Set column data */
446
+ setColumnData(index: number, data: readonly CellValue[]): void;
426
447
  /** Get cell value */
427
- getCell(rowIndex: number, columnIndex: number): unknown;
448
+ getCell(row: number, column: number): CellValue;
449
+ /** Set cell value */
450
+ 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[];
471
+ /** Set footer row */
472
+ 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
+ /** Clear footer */
478
+ clearFooter(): void;
428
479
  /** Set caption text */
429
480
  setCaption(text: string): void;
430
- /** Set all headers */
431
- setHeaders(headerTexts: readonly string[]): void;
432
- /** Set footer row */
433
- setFooter(footerData: readonly unknown[]): void;
434
- /** Set all data */
435
- setData(newData: readonly (readonly unknown[])[]): void;
436
- /** Clear body data (keep headers) */
437
- clearData(): void;
438
- /** Reset entire table */
481
+ /** Set all data (replaces body rows) */
482
+ setData(data: TableData): void;
483
+ /** Reset table (clear all content) */
439
484
  reset(): void;
440
- /** Sync reactive state with DOM */
485
+ /** Sync internal state with DOM */
441
486
  sync(): void;
442
- /** Add row with cell configs */
443
- addRowWithAttributes(rowData: readonly (unknown | CellConfig)[], attributes?: ElementAttributes, index?: number): HTMLTableRowElement;
444
- /** Add column with config */
445
- addColumnWithAttributes(config: ColumnConfig, index?: number): void;
446
- /** Set headers with configs */
447
- setHeadersWithAttributes(headerConfigs: readonly (string | CellConfig)[]): void;
448
- /** Set cell with attributes */
449
- setCellWithAttributes(rowIndex: number, columnIndex: number, value: unknown, attributes?: ElementAttributes): void;
450
- /** Get row data copy */
451
- getRowData(index: number): unknown[] | undefined;
452
- /** Set row data */
453
- setRowData(index: number, rowData: readonly unknown[]): void;
454
- /** Get all row data as copy */
455
- getAllRowData(): unknown[][];
456
- /** Get column data */
457
- getColumnData(index: number): unknown[];
458
- /** Set column data */
459
- setColumnData(index: number, columnData: readonly unknown[]): void;
460
- /** Get cell range */
461
- getCellRange(rowStart: number, rowEnd: number, columnStart: number, columnEnd: number): unknown[][];
462
- /** Set cell range */
463
- setCellRange(rowStart: number, columnStart: number, rangeData: readonly (readonly unknown[])[]): void;
464
- /** Get header data copy */
465
- getHeaderData(): string[];
466
- /** Get footer data */
467
- getFooterData(): unknown[] | undefined;
468
- /** Set footer cell */
469
- setFooterCell(columnIndex: number, value: unknown): void;
470
- /** Get footer cell */
471
- getFooterCell(columnIndex: number): unknown;
472
- /** Update cell with config */
473
- updateCell(rowIndex: number, columnIndex: number, config: CellConfig): void;
474
- /** Update row data */
475
- updateRow(index: number, rowData: readonly (unknown | CellConfig)[]): void;
476
- /** Get cell DOM element */
477
- getCellElement(rowIndex: number, columnIndex: number): HTMLTableCellElement | undefined;
478
- /** Get row DOM element */
479
- getRowElement(index: number): HTMLTableRowElement | undefined;
480
- /** Select multiple rows */
481
- selectRows(indices: readonly number[]): unknown[][];
482
- /** Select multiple columns */
483
- selectColumns(indices: readonly number[]): unknown[][];
484
- /** Update multiple rows */
485
- updateRows(updates: ReadonlyMap<number, readonly (unknown | CellConfig)[]>): void;
486
- /** Update multiple cells */
487
- updateCells(updates: ReadonlyMap<readonly [number, number], unknown | CellConfig>): void;
488
- /** Get all row elements */
489
- getRowElements(): readonly HTMLTableRowElement[];
490
- /** Get cells for a row */
491
- getRowCellElements(rowIndex: number): readonly HTMLTableCellElement[];
492
- /** Set multiple rows */
493
- setRows(startIndex: number, rows: readonly (readonly (unknown | CellConfig)[])[]): void;
494
- /** Validate single cell */
495
- validateCell(rowIndex: number, columnIndex: number, validator: CellValidator): true | ValidationError;
496
- /** Validate single row */
497
- validateRow(index: number, validator: RowValidator): true | ValidationError[];
498
- /** Validate single column */
499
- validateColumn(index: number, validator: CellValidator): true | ValidationError[];
500
- /** Validate all cells */
501
- validateAll(validator: FullValidator): ValidationResult;
502
- /** Sum of column values */
503
- sum(columnIndex: number): number;
504
- /** Average of column values */
505
- average(columnIndex: number): number;
506
- /** Minimum value in column */
507
- min(columnIndex: number): unknown;
508
- /** Maximum value in column */
509
- max(columnIndex: number): unknown;
510
- /** Count values in column */
511
- count(columnIndex: number, predicate?: (value: unknown) => boolean): number;
512
- /** Custom aggregation */
513
- aggregate<T>(columnIndex: number, options: AggregateConfig<T>): T;
514
- /** Transform all cells in column */
515
- transformColumn(columnIndex: number, transformer: (value: unknown, rowIndex: number) => unknown): void;
516
- /** Transform all cells in row */
517
- transformRow(rowIndex: number, transformer: (value: unknown, colIndex: number) => unknown): void;
518
- /** Transform all cells */
519
- transformCells(transformer: (value: unknown, rowIndex: number, colIndex: number) => unknown): void;
520
- /** Export to CSV string */
521
- exportToCSV(): string;
522
- /** Export to JSON string */
523
- exportToJSON(): string;
524
- /** Import from 2D array */
525
- importFromArray(data: readonly (readonly unknown[])[]): void;
526
- /** Import from CSV string */
527
- importFromCSV(csv: string): void;
528
- /** Import from JSON string */
529
- importFromJSON(json: string): void;
530
- /** Search all cells */
531
- search(query: string, options?: SearchOptions): SearchResult[];
532
- /** Search single column */
533
- searchColumn(columnIndex: number, query: string, options?: SearchOptions): SearchResult[];
534
- /** Selected row indices */
535
- readonly selectedRows: Readonly<Ref<Set<number>>>;
536
- /** Selected cell keys (row,column format) */
537
- readonly selectedCells: Readonly<Ref<Set<string>>>;
538
- /** Select a row */
487
+ /** Select a row by index */
539
488
  selectRow(index: number): void;
540
- /** Deselect a row */
489
+ /** Deselect a row by index */
541
490
  deselectRow(index: number): void;
542
491
  /** Toggle row selection */
543
492
  toggleRowSelection(index: number): void;
544
- /** Check if row is selected */
545
- isRowSelected(index: number): boolean;
546
- /** Select a cell */
547
- selectCell(rowIndex: number, columnIndex: number): void;
548
- /** Clear all selection */
549
- clearSelection(): void;
550
- /** Enable cell editing */
551
- enableCellEditing(config?: EditableConfig): void;
552
- /** Disable cell editing */
553
- disableCellEditing(): void;
554
- /** Enable header editing */
555
- enableHeaderEditing(config?: Omit<EditableConfig, 'cells'>): void;
556
- /** Disable header editing */
557
- disableHeaderEditing(): void;
558
- /** Enable editing for specific column */
559
- enableColumnEditing(columnIndex: number, config?: EditableConfig): void;
560
- /** Disable editing for specific column */
561
- disableColumnEditing(columnIndex: number): void;
562
- /** Enable editing for specific row */
563
- enableRowEditing(rowIndex: number, config?: EditableConfig): void;
564
- /** Disable editing for specific row */
565
- disableRowEditing(rowIndex: number): void;
566
- /** Enable double-click to edit (returns cleanup) */
567
- enableEditing(): () => void;
568
- /** Group rows by key function */
569
- groupBy(keyFunction: (row: unknown[]) => string | number): Map<string | number, number[]>;
570
- /** Add computed column */
571
- addComputedColumn(config: ComputedColumnConfig): number;
572
- /** Remove computed column */
573
- removeComputedColumn(index: number): void;
574
- /** Current pagination state */
575
- readonly pagination: PaginationState | null;
576
- /** Enable pagination */
577
- paginate(config: PaginationConfig): void;
578
- /** Go to next page */
579
- nextPage(): void;
580
- /** Go to previous page */
581
- previousPage(): void;
582
- /** Go to specific page */
583
- goToPage(page: number): void;
584
- /** Current virtual scroll state */
585
- readonly virtualScroll: VirtualScrollState | null;
586
- /** Enable virtual scrolling */
587
- enableVirtualScrolling(config: VirtualScrollConfig): void;
588
- /** Disable virtual scrolling */
589
- disableVirtualScrolling(): void;
590
- /** Execute operations with rollback on error */
591
- transaction<T>(callback: () => T | Promise<T>): T | Promise<T>;
592
- /** Subscribe to data changes (returns unsubscribe) */
593
- onDataChange(callback: (data: unknown[][]) => void): () => void;
594
- /** Current sort state */
595
- readonly sortState: SortState;
596
- /** Sort column ascending */
597
- sortColumnAscending(columnIndex: number): void;
598
- /** Sort column descending */
599
- sortColumnDescending(columnIndex: number): void;
600
- /** Sort column ascending with custom comparator */
601
- sortColumnAscendingWith(columnIndex: number, comparator: (a: unknown, b: unknown) => number): void;
602
- /** Sort column descending with custom comparator */
603
- sortColumnDescendingWith(columnIndex: number, comparator: (a: unknown, b: unknown) => number): void;
604
- /** Clear sorting */
605
- clearColumnSort(): void;
606
- /** Get sorted column index */
607
- getSortedColumnIndex(): number | null;
608
- /** Check if sorted ascending */
609
- isSortedAscending(): boolean;
610
- /** Check if sorted descending */
611
- isSortedDescending(): boolean;
612
- /** Check if any sort is active */
613
- isSorted(): boolean;
614
- /** Current filter state */
615
- readonly filterState: FilterState;
616
- /** Filter rows by predicate */
617
- filterRows(predicate: (rowData: unknown[], rowIndex: number) => boolean): void;
618
- /** Filter by column predicate */
619
- filterColumn(columnIndex: number, predicate: (value: unknown) => boolean): void;
620
- /** Filter by exact value */
621
- filterColumnByValue(columnIndex: number, value: unknown): void;
622
- /** Filter by multiple values */
623
- filterColumnByValues(columnIndex: number, values: readonly unknown[]): void;
624
- /** Clear all filters */
625
- clearFilters(): void;
626
- /** Get visible row indices */
627
- getFilteredRowIndices(): readonly number[];
628
- /** Set function to generate row keys */
629
- setRowKeyFunction(keyFunction: (rowData: unknown[], rowIndex: number) => string | number): void;
630
- /** Clear row key function */
631
- clearRowKeyFunction(): void;
632
- /** Check if row key function is set */
633
- hasRowKeyFunction(): boolean;
634
- /** Get row data by key */
635
- getRowByKey(key: string | number): unknown[] | undefined;
636
- /** Get row index by key */
637
- getRowIndexByKey(key: string | number): number | undefined;
638
- /** Update row by key */
639
- updateRowByKey(key: string | number, rowData: readonly unknown[]): boolean;
640
- /** Remove row by key */
641
- removeRowByKey(key: string | number): boolean;
642
- /** Check if row with key exists */
643
- hasRowWithKey(key: string | number): boolean;
644
- /** Get key for row */
645
- getRowKey(rowIndex: number): string | number | undefined;
646
- /** Get all row keys */
647
- getAllRowKeys(): readonly (string | number)[];
648
- /** Set column definition */
649
- setColumnDefinition(columnIndex: number, definition: ColumnDefinition): void;
650
- /** Set all column definitions */
651
- setColumnDefinitions(definitions: readonly (ColumnDefinition | undefined)[]): void;
652
- /** Clear column definition */
653
- clearColumnDefinition(columnIndex: number): void;
654
- /** Clear all column definitions */
655
- clearColumnDefinitions(): void;
656
- /** Get column definition */
657
- getColumnDefinition(columnIndex: number): ColumnDefinition | undefined;
658
- /** Check if column has definition */
659
- hasColumnDefinition(columnIndex: number): boolean;
660
- /** Get parsed cell value */
661
- getParsedCell(rowIndex: number, columnIndex: number): unknown;
662
- /** Get parsed row data */
663
- getParsedRowData(rowIndex: number): unknown[];
664
- /** Get parsed column data */
665
- getParsedColumnData(columnIndex: number): unknown[];
666
- /** Get all parsed data */
667
- getParsedData(): unknown[][];
668
- /** Whether table has unsaved changes */
669
- readonly dirtyState: Readonly<Ref<boolean>>;
670
- /** Mark as clean (save point) */
671
- markClean(): void;
672
- /** Mark as dirty */
673
- markDirty(): void;
674
- /** Check if dirty */
675
- isDirty(): boolean;
676
- /** Check if has changes */
677
- hasChanges(): boolean;
678
- /** Get all cell changes */
679
- getChangedCells(): readonly CellChange[];
680
- /** Get changed row indices */
681
- getChangedRowIndices(): readonly number[];
682
- /** Get changed column indices */
683
- getChangedColumnIndices(): readonly number[];
684
- /** Undo last change */
685
- undo(): boolean;
686
- /** Redo last undone change */
687
- redo(): boolean;
688
- /** Clear history */
689
- clearHistory(): void;
690
- /** Check if can undo */
691
- canUndo(): boolean;
692
- /** Check if can redo */
693
- canRedo(): boolean;
694
- /** Get undo stack size */
695
- getUndoStackSize(): number;
696
- /** Get redo stack size */
697
- getRedoStackSize(): number;
698
- /** Set history limit */
699
- setHistoryLimit(limit: number): void;
700
- /** Get history limit */
701
- getHistoryLimit(): number;
702
493
  /** Select all rows */
703
494
  selectAllRows(): void;
704
495
  /** Deselect all rows */
705
496
  deselectAllRows(): void;
706
- /** Select range of rows */
497
+ /** Select row range */
707
498
  selectRowRange(startIndex: number, endIndex: number): void;
708
- /** Invert row selection */
709
- invertRowSelection(): void;
710
- /** Get data for selected rows */
711
- getSelectedRowData(): readonly unknown[][];
499
+ /** Check if row is selected */
500
+ isRowSelected(index: number): boolean;
712
501
  /** Get selected row indices */
713
502
  getSelectedRowIndices(): readonly number[];
714
- /** Get selected cell positions */
715
- getSelectedCellIndices(): readonly CellPosition[];
716
- /** Currently focused cell */
717
- readonly focusedCell: Readonly<Ref<CellPosition | null>>;
503
+ /** Get selected row data */
504
+ getSelectedRowData(): readonly (readonly CellValue[])[];
505
+ /** Select a cell */
506
+ selectCell(row: number, column: number): void;
507
+ /** Deselect a cell */
508
+ deselectCell(row: number, column: number): void;
509
+ /** Toggle cell selection */
510
+ toggleCellSelection(row: number, column: number): void;
511
+ /** Check if cell is selected */
512
+ isCellSelected(row: number, column: number): boolean;
513
+ /** Clear all selection */
514
+ clearSelection(): void;
718
515
  /** Focus a cell */
719
- focusCell(rowIndex: number, columnIndex: number): void;
516
+ focusCell(row: number, column: number): void;
720
517
  /** Clear cell focus */
721
- clearCellFocus(): void;
518
+ clearFocus(): void;
722
519
  /** Get focused cell position */
723
520
  getFocusedCell(): CellPosition | null;
724
521
  /** Check if cell is focused */
725
- isCellFocused(rowIndex: number, columnIndex: number): boolean;
522
+ isCellFocused(row: number, column: number): boolean;
726
523
  /** Move focus up */
727
524
  moveFocusUp(): boolean;
728
525
  /** Move focus down */
@@ -732,369 +529,51 @@ export declare interface UseTableReturn extends ReactiveRowCollection, ReactiveT
732
529
  /** Move focus right */
733
530
  moveFocusRight(): boolean;
734
531
  /** Move focus to first cell */
735
- moveFocusToFirstCell(): void;
532
+ moveFocusToFirst(): void;
736
533
  /** Move focus to last cell */
737
- moveFocusToLastCell(): void;
738
- /** Move focus to row start */
739
- moveFocusToRowStart(): void;
740
- /** Move focus to row end */
741
- moveFocusToRowEnd(): void;
742
- /** Enable keyboard navigation (returns cleanup) */
534
+ moveFocusToLast(): void;
535
+ /** Enable keyboard navigation (returns cleanup function) */
743
536
  enableKeyboardNavigation(): () => void;
744
- /** Count of visible columns */
745
- readonly visibleColumnCount: Readonly<Ref<number>>;
746
- /** Hide a column */
747
- hideColumn(columnIndex: number): void;
748
- /** Show a column */
749
- showColumn(columnIndex: number): void;
750
- /** Toggle column visibility */
751
- toggleColumnVisibility(columnIndex: number): void;
752
- /** Check if column is visible */
753
- isColumnVisible(columnIndex: number): boolean;
754
- /** Get visible column indices */
755
- getVisibleColumnIndices(): readonly number[];
756
- /** Get hidden column indices */
757
- getHiddenColumnIndices(): readonly number[];
758
- /** Move row from one position to another */
759
- moveRow(fromIndex: number, toIndex: number): void;
760
- /** Move row up */
761
- moveRowUp(rowIndex: number): boolean;
762
- /** Move row down */
763
- moveRowDown(rowIndex: number): boolean;
764
- /** Move row to top */
765
- moveRowToTop(rowIndex: number): void;
766
- /** Move row to bottom */
767
- moveRowToBottom(rowIndex: number): void;
768
- /** Swap two rows */
769
- swapRows(indexA: number, indexB: number): void;
770
- /** Move column from one position to another */
771
- moveColumn(fromIndex: number, toIndex: number): void;
772
- /** Move column left */
773
- moveColumnLeft(columnIndex: number): boolean;
774
- /** Move column right */
775
- moveColumnRight(columnIndex: number): boolean;
776
- /** Move column to start */
777
- moveColumnToStart(columnIndex: number): void;
778
- /** Move column to end */
779
- moveColumnToEnd(columnIndex: number): void;
780
- /** Swap two columns */
781
- swapColumns(indexA: number, indexB: number): void;
782
- /** Copy selected cells to string */
783
- copySelectedCells(): string;
784
- /** Copy selected rows to string */
785
- copySelectedRows(): string;
786
- /** Copy row to string */
787
- copyRow(rowIndex: number): string;
788
- /** Copy column to string */
789
- copyColumn(columnIndex: number): string;
790
- /** Copy cell to string */
791
- copyCell(rowIndex: number, columnIndex: number): string;
792
- /** Copy cell range to string */
793
- copyCellRange(rowStart: number, columnStart: number, rowEnd: number, columnEnd: number): string;
794
- /** Paste data at cell */
795
- pasteAtCell(rowIndex: number, columnIndex: number, data: string): void;
796
- /** Expanded row indices */
797
- readonly expandedRows: Readonly<Ref<ReadonlySet<number>>>;
798
- /** Rows pinned to top */
799
- readonly pinnedTopRows: Readonly<Ref<readonly number[]>>;
800
- /** Rows pinned to bottom */
801
- readonly pinnedBottomRows: Readonly<Ref<readonly number[]>>;
802
- /** Expand a row */
803
- expandRow(rowIndex: number): void;
804
- /** Collapse a row */
805
- collapseRow(rowIndex: number): void;
806
- /** Toggle row expansion */
807
- toggleRowExpansion(rowIndex: number): void;
808
- /** Expand all rows */
809
- expandAllRows(): void;
810
- /** Collapse all rows */
811
- collapseAllRows(): void;
812
- /** Check if row is expanded */
813
- isRowExpanded(rowIndex: number): boolean;
814
- /** Get expanded row indices */
815
- getExpandedRowIndices(): readonly number[];
816
- /** Pin row to top */
817
- pinRowTop(rowIndex: number): void;
818
- /** Pin row to bottom */
819
- pinRowBottom(rowIndex: number): void;
820
- /** Unpin a row */
821
- unpinRow(rowIndex: number): void;
822
- /** Unpin all rows */
823
- unpinAllRows(): void;
824
- /** Check if row is pinned to top */
825
- isRowPinnedTop(rowIndex: number): boolean;
826
- /** Check if row is pinned to bottom */
827
- isRowPinnedBottom(rowIndex: number): boolean;
828
- /** Get indices of rows pinned to top */
829
- getPinnedTopRowIndices(): readonly number[];
830
- /** Get indices of rows pinned to bottom */
831
- getPinnedBottomRowIndices(): readonly number[];
832
- /** Set cell metadata */
833
- setCellMeta<T>(rowIndex: number, columnIndex: number, key: string, value: T): void;
834
- /** Get cell metadata */
835
- getCellMeta<T>(rowIndex: number, columnIndex: number, key: string): T | undefined;
836
- /** Check if cell has metadata */
837
- hasCellMeta(rowIndex: number, columnIndex: number, key: string): boolean;
838
- /** Clear all cell metadata */
839
- clearCellMeta(rowIndex: number, columnIndex: number): void;
840
- /** Clear specific cell metadata key */
841
- clearCellMetaKey(rowIndex: number, columnIndex: number, key: string): void;
842
- /** Set row metadata */
843
- setRowMeta<T>(rowIndex: number, key: string, value: T): void;
844
- /** Get row metadata */
845
- getRowMeta<T>(rowIndex: number, key: string): T | undefined;
846
- /** Check if row has metadata */
847
- hasRowMeta(rowIndex: number, key: string): boolean;
848
- /** Clear all row metadata */
849
- clearRowMeta(rowIndex: number): void;
850
- /** Clear specific row metadata key */
851
- clearRowMetaKey(rowIndex: number, key: string): void;
852
- /** Set column metadata */
853
- setColumnMeta<T>(columnIndex: number, key: string, value: T): void;
854
- /** Get column metadata */
855
- getColumnMeta<T>(columnIndex: number, key: string): T | undefined;
856
- /** Check if column has metadata */
857
- hasColumnMeta(columnIndex: number, key: string): boolean;
858
- /** Clear all column metadata */
859
- clearColumnMeta(columnIndex: number): void;
860
- /** Clear specific column metadata key */
861
- clearColumnMetaKey(columnIndex: number, key: string): void;
862
- /** Subscribe to row add events */
863
- onRowAdd(callback: (rowData: unknown[], rowIndex: number) => void): () => void;
864
- /** Subscribe to row remove events */
865
- onRowRemove(callback: (rowData: unknown[], rowIndex: number) => void): () => void;
866
- /** Subscribe to row update events */
867
- onRowUpdate(callback: (rowIndex: number, oldRowData: unknown[], newRowData: unknown[]) => void): () => void;
868
- /** Subscribe to cell change events */
869
- onCellChange(callback: (rowIndex: number, columnIndex: number, oldValue: unknown, newValue: unknown) => void): () => void;
870
- /** Subscribe to row selection change events */
871
- onRowSelectionChange(callback: (selectedIndices: ReadonlySet<number>) => void): () => void;
872
- /** Subscribe to cell selection change events */
873
- onCellSelectionChange(callback: (selectedCells: ReadonlySet<string>) => void): () => void;
874
- /** Subscribe to sort change events */
875
- onSortChange(callback: (columnIndex: number | null, ascending: boolean) => void): () => void;
876
- /** Subscribe to filter change events */
877
- onFilterChange(callback: (filteredIndices: readonly number[]) => void): () => void;
878
- /** Subscribe to cell focus change events */
879
- onCellFocusChange(callback: (cell: CellPosition | null) => void): () => void;
880
- /** Subscribe to column visibility change events */
881
- onColumnVisibilityChange(callback: (columnIndex: number, visible: boolean) => void): () => void;
882
- /** Begin batch update (defer reactivity) */
883
- beginBatchUpdate(): void;
884
- /** End batch update (commit changes) */
885
- endBatchUpdate(): void;
886
- /** Cancel batch update (rollback) */
887
- cancelBatchUpdate(): void;
888
- /** Check if batch updating */
889
- isBatchUpdating(): boolean;
890
- /** Execute callback as batch */
891
- batchUpdate(callback: () => void): void;
892
- /** Whether table is loading */
893
- readonly tableLoading: Readonly<Ref<boolean>>;
894
- /** Set table loading state */
895
- setTableLoading(loading: boolean): void;
896
- /** Set cell loading state */
897
- setCellLoading(rowIndex: number, columnIndex: number, loading: boolean): void;
898
- /** Set row loading state */
899
- setRowLoading(rowIndex: number, loading: boolean): void;
900
- /** Set column loading state */
901
- setColumnLoading(columnIndex: number, loading: boolean): void;
902
- /** Check if table is loading */
903
- isTableLoading(): boolean;
904
- /** Check if cell is loading */
905
- isCellLoading(rowIndex: number, columnIndex: number): boolean;
906
- /** Check if row is loading */
907
- isRowLoading(rowIndex: number): boolean;
908
- /** Check if column is loading */
909
- isColumnLoading(columnIndex: number): boolean;
910
- /** Load data with fetcher */
911
- loadData(fetcher: () => Promise<readonly (readonly unknown[])[]>): Promise<void>;
912
- /** Append rows asynchronously */
913
- appendRowsAsync(fetcher: () => Promise<readonly (readonly unknown[])[]>): Promise<void>;
914
- /** Prepend rows asynchronously */
915
- prependRowsAsync(fetcher: () => Promise<readonly (readonly unknown[])[]>): Promise<void>;
916
- /** Number of columns frozen on left */
917
- readonly frozenLeftColumnCount: Readonly<Ref<number>>;
918
- /** Number of columns frozen on right */
919
- readonly frozenRightColumnCount: Readonly<Ref<number>>;
920
- /** Freeze columns on left */
921
- freezeColumnsLeft(count: number): void;
922
- /** Freeze columns on right */
923
- freezeColumnsRight(count: number): void;
924
- /** Unfreeze columns on left */
925
- unfreezeColumnsLeft(): void;
926
- /** Unfreeze columns on right */
927
- unfreezeColumnsRight(): void;
928
- /** Unfreeze all columns */
929
- unfreezeAllColumns(): void;
930
- /** Get frozen left column count */
931
- getFrozenLeftColumnCount(): number;
932
- /** Get frozen right column count */
933
- getFrozenRightColumnCount(): number;
934
- /** Check if column is frozen on left */
935
- isColumnFrozenLeft(columnIndex: number): boolean;
936
- /** Check if column is frozen on right */
937
- isColumnFrozenRight(columnIndex: number): boolean;
938
- /** Check if any columns are frozen */
939
- hasFrozenColumns(): boolean;
940
- /**
941
- * Configure table for record-based data.
942
- * This enables integration with useDatabase and other composables.
943
- */
944
- setRecordColumns<T extends BaseRecord>(columns: readonly RecordColumnDef<T>[]): void;
945
- /**
946
- * Clear record column configuration.
947
- */
948
- clearRecordColumns(): void;
949
- /**
950
- * Check if record columns are configured.
951
- */
952
- hasRecordColumns(): boolean;
953
- /**
954
- * Get the configured record columns.
955
- */
956
- getRecordColumns<T extends BaseRecord>(): readonly RecordColumnDef<T>[] | undefined;
957
- /**
958
- * Set table data from an array of records.
959
- * Records must have an `id` field.
960
- */
961
- setRecords<T extends BaseRecord>(records: readonly T[]): void;
962
- /**
963
- * Get all records from the table.
964
- * Returns records reconstructed from table data using column definitions.
965
- */
966
- getRecords<T extends BaseRecord>(): readonly T[];
967
- /**
968
- * Get a single record by ID.
969
- */
970
- getRecordById<T extends BaseRecord>(id: string): T | undefined;
971
- /**
972
- * Get record ID for a row index.
973
- */
974
- getRecordId(rowIndex: number): string | undefined;
975
- /**
976
- * Get row index for a record ID.
977
- */
978
- getRowIndexForRecord(recordId: string): number | undefined;
979
- /**
980
- * Update a record by ID.
981
- * Only updates the specified fields.
982
- */
983
- updateRecord<T extends BaseRecord>(id: string, updates: Partial<Omit<T, 'id'>>): boolean;
984
- /**
985
- * Add a new record to the table.
986
- * If no ID is provided, one will be generated.
987
- */
988
- addRecord<T extends BaseRecord>(record: T | Omit<T, 'id'>, index?: number): string;
989
- /**
990
- * Remove a record by ID.
991
- */
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 */
992
546
  removeRecord(id: string): boolean;
993
- /**
994
- * Check if a record with the given ID exists.
995
- */
547
+ /** Check if record exists */
996
548
  hasRecord(id: string): boolean;
997
- /**
998
- * Get record IDs for selected rows.
999
- */
549
+ /** Get selected record IDs */
1000
550
  getSelectedRecordIds(): readonly string[];
1001
- /**
1002
- * Select rows by record IDs.
1003
- */
551
+ /** Select records by IDs */
1004
552
  selectRecords(ids: readonly string[]): void;
1005
- /**
1006
- * Deselect rows by record IDs.
1007
- */
553
+ /** Deselect records by IDs */
1008
554
  deselectRecords(ids: readonly string[]): void;
1009
- /**
1010
- * Get the selected records.
1011
- */
1012
- getSelectedRecords<T extends BaseRecord>(): readonly T[];
1013
- /**
1014
- * Subscribe to record changes.
1015
- * Callback receives the record ID and the updated record.
1016
- */
1017
- onRecordChange<T extends BaseRecord>(callback: (recordId: string, record: T, changeType: 'add' | 'update' | 'remove') => void): () => void;
1018
- /**
1019
- * Set the ID generator for new records.
1020
- */
555
+ /** Set the ID generator function */
1021
556
  setIdGenerator(generator: IdGenerator): void;
1022
- /**
1023
- * Convert array row data to a record object using column definitions.
1024
- */
1025
- rowToRecord<T extends BaseRecord>(rowIndex: number): T | undefined;
1026
- /**
1027
- * Convert a record to array row data using column definitions.
1028
- */
1029
- recordToRow<T extends BaseRecord>(record: T): unknown[];
1030
- /**
1031
- * Export records to JSON (uses column definitions).
1032
- */
1033
- exportRecordsToJSON(): string;
1034
- /**
1035
- * Import records from JSON.
1036
- */
1037
- importRecordsFromJSON(json: string): void;
1038
- }
1039
-
1040
- /**
1041
- * Validation error for a specific cell.
1042
- */
1043
- export declare interface ValidationError {
1044
- /** Row index */
1045
- readonly row: number;
1046
- /** Column index */
1047
- readonly column: number;
1048
- /** The invalid value */
1049
- readonly value: unknown;
1050
- /** Error message */
1051
- readonly message: string;
1052
- }
1053
-
1054
- /**
1055
- * Result of validation operations.
1056
- */
1057
- export declare interface ValidationResult {
1058
- /** Whether validation passed */
1059
- readonly valid: boolean;
1060
- /** Array of validation errors */
1061
- readonly errors: readonly ValidationError[];
1062
- }
1063
-
1064
- /**
1065
- * Virtual scrolling configuration.
1066
- */
1067
- export declare interface VirtualScrollConfig {
1068
- /** Height of each row in pixels */
1069
- readonly rowHeight: number;
1070
- /** Number of extra rows to render above/below viewport */
1071
- readonly overscan: number;
1072
- /** Height of the scroll container in pixels */
1073
- readonly containerHeight: number;
1074
- }
1075
-
1076
- /**
1077
- * Virtual scrolling state.
1078
- */
1079
- export declare interface VirtualScrollState {
1080
- /** Current scroll position */
1081
- readonly scrollTop: Ref<number>;
1082
- /** Height of each row */
1083
- readonly rowHeight: number;
1084
- /** Overscan count */
1085
- readonly overscan: number;
1086
- /** Container height */
1087
- readonly containerHeight: number;
1088
- /** Indices of currently visible rows */
1089
- readonly visibleRows: Ref<number[]>;
1090
- /** Start index of visible range */
1091
- readonly startIndex: Ref<number>;
1092
- /** End index of visible range */
1093
- readonly endIndex: Ref<number>;
1094
- /** Scroll event handler (internal) */
1095
- scrollHandler?: () => void;
1096
- /** Container element (internal) */
1097
- container?: HTMLElement;
557
+ /** Generate a new ID */
558
+ generateId(): string;
559
+ /** Subscribe to row add events */
560
+ onRowAdd(callback: RowAddCallback): () => void;
561
+ /** 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;
569
+ /** Subscribe to data change events */
570
+ onDataChange(callback: DataChangeCallback): () => void;
571
+ /** Subscribe to selection change events */
572
+ onSelectionChange(callback: (selectedRows: ReadonlySet<number>, selectedCells: ReadonlySet<string>) => void): () => void;
573
+ /** Subscribe to focus change events */
574
+ onFocusChange(callback: (cell: CellPosition | null) => void): () => void;
575
+ /** Destroy and clean up */
576
+ destroy(): void;
1098
577
  }
1099
578
 
1100
579
  /**