@mikestools/usetable 0.0.5 → 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/README.md CHANGED
@@ -16,15 +16,13 @@ A Vue 3 composable for HTML table manipulation with native DOM APIs. Two-layer a
16
16
  | Feature | Description |
17
17
  |------------------|-----------------------------------------------|
18
18
  | 📋 **Headers** | Set, update, add, remove header cells |
19
- | ➕ **Rows** | Add, remove, update, move, swap rows |
20
- | 📐 **Sections** | Section-specific row ops (thead/tfoot/tbody) |
21
- | 📊 **Columns** | Add, remove, move, swap columns |
19
+ | ➕ **Rows** | Add, remove, update rows |
20
+ | 📊 **Columns** | Add, remove columns |
22
21
  | 🔲 **Cells** | Get, set individual cell values |
23
- | ☑️ **Selection** | Row and cell selection with range support |
22
+ | ☑️ **Selection** | Row and cell selection |
24
23
  | 🎯 **Focus** | Cell focus with keyboard navigation |
25
24
  | 📝 **Footer** | Footer row for totals/summaries |
26
- | 🗄️ **Records** | Work with typed records by ID |
27
- | 🔔 **Events** | Granular change callbacks |
25
+ | 🔔 **Events** | Data change callbacks |
28
26
  | ⌨️ **Keyboard** | Arrow key cell navigation |
29
27
  | ⚡ **Reactive** | Vue computed properties |
30
28
  | 🔄 **Sync** | Sync with pre-existing DOM tables |
@@ -122,8 +120,8 @@ function addEmployee() {
122
120
 
123
121
  ```typescript
124
122
  function useTable(
125
- elementRef: Ref<HTMLTableElement | null>,
126
- initialData?: readonly (readonly CellValue[])[],
123
+ elementRef: MaybeRef<HTMLTableElement | null>,
124
+ initialData?: TableData,
127
125
  options?: UseTableOptions
128
126
  ): UseTableReturn
129
127
  ```
@@ -132,111 +130,90 @@ function useTable(
132
130
 
133
131
  | Option | Type | Description |
134
132
  |----------------|-------------------------|--------------------------------|
135
- | `headers` | `readonly CellValue[]` | Initial header values |
133
+ | `headers` | `readonly string[]` | Initial header values |
136
134
  | `caption` | `string` | Table caption text |
137
- | `footer` | `readonly CellValue[]` | Initial footer values |
135
+ | `footer` | `RowData` | Initial footer values |
138
136
  | `idGenerator` | `() => string` | Custom row ID generator |
139
137
 
140
138
  #### Reactive State
141
139
 
142
- | Property | Type | Description |
143
- |---------------|-----------------------------------------|--------------------------------|
144
- | `element` | `Readonly<Ref<HTMLTableElement>>` | The table element |
145
- | `headers` | `ComputedRef<readonly string[]>` | Header values |
146
- | `data` | `ComputedRef<readonly CellValue[][]>` | Body data as 2D array |
147
- | `rowCount` | `ComputedRef<number>` | Number of body rows |
148
- | `columnCount` | `ComputedRef<number>` | Number of columns |
149
- | `rowIds` | `ComputedRef<readonly string[]>` | Array of row IDs |
150
- | `footerData` | `ComputedRef<CellValue[] \| undefined>` | Footer row values |
151
- | `captionText` | `ComputedRef<string \| undefined>` | Caption text |
152
- | `version` | `Ref<number>` | Version counter for reactivity |
140
+ | Property | Type | Description |
141
+ |---------------|---------------------------------------------|--------------------------------|
142
+ | `element` | `Readonly<Ref<HTMLTableElement \| null>>` | The table element |
143
+ | `headers` | `ComputedRef<readonly string[]>` | Header values |
144
+ | `data` | `ComputedRef<readonly CellValue[][]>` | Body data as 2D array |
145
+ | `rowCount` | `ComputedRef<number>` | Number of body rows |
146
+ | `columnCount` | `ComputedRef<number>` | Number of columns |
147
+ | `rowIds` | `ComputedRef<readonly string[]>` | Array of row IDs |
148
+ | `footerData` | `ComputedRef<readonly CellValue[] \| null>` | Footer row values |
149
+ | `captionText` | `ComputedRef<string \| null>` | Caption text |
150
+ | `version` | `Readonly<Ref<number>>` | Version counter for reactivity |
153
151
 
154
152
  #### Selection State
155
153
 
156
- | Property | Type | Description |
157
- |-------------------|--------------------|------------------------------|
158
- | `selection.rows` | `Ref<Set<number>>` | Selected row indices |
159
- | `selection.cells` | `Ref<Set<string>>` | Selected cell keys (row,col) |
154
+ | Property | Type | Description |
155
+ |-------------------|--------------------------------------|----------------------|
156
+ | `selection.rows` | `Readonly<Ref<ReadonlySet<number>>>` | Selected row indices |
157
+ | `selection.cells` | `Readonly<Ref<ReadonlySet<string>>>` | Selected cell keys |
160
158
 
161
159
  #### Focus State
162
160
 
163
- | Property | Type | Description |
164
- |--------------|----------------------------------------------|-----------------------|
165
- | `focus.cell` | `Ref<{row: number, column: number} \| null>` | Focused cell position |
161
+ | Property | Type | Description |
162
+ |--------------|-----------------------------------------|-----------------------|
163
+ | `focus.cell` | `Readonly<Ref<CellPosition \| null>>` | Focused cell position |
166
164
 
167
165
  ### Methods
168
166
 
169
- #### Header Methods
167
+ #### Structure Methods
170
168
 
171
169
  ```typescript
172
- setHeaders(headers: readonly CellValue[]): void
173
- setHeader(index: number, value: CellValue): void
174
- addHeader(value: CellValue, index?: number): void
175
- removeHeader(index: number): CellValue | undefined
170
+ createCaption(): HTMLTableCaptionElement | null
171
+ deleteCaption(): void
172
+ createTHead(): HTMLTableSectionElement | null
173
+ deleteTHead(): void
174
+ createTFoot(): HTMLTableSectionElement | null
175
+ deleteTFoot(): void
176
+ createTBody(): HTMLTableSectionElement | null
176
177
  ```
177
178
 
178
- #### Row Methods
179
+ #### Header Methods
179
180
 
180
181
  ```typescript
181
- addRow(data: readonly CellValue[], index?: number, id?: string): HTMLTableRowElement
182
- removeRow(index: number): CellValue[] | undefined
183
- removeRowById(id: string): CellValue[] | undefined
184
- updateRow(index: number, data: readonly CellValue[]): void
185
- updateRowById(id: string, data: readonly CellValue[]): boolean
186
- moveRow(fromIndex: number, toIndex: number): void
187
- swapRows(index1: number, index2: number): void
188
- clearRows(): void
189
- getRowData(index: number): readonly CellValue[] | undefined
190
- getRowId(index: number): string | undefined
191
- getRowIndex(id: string): number
182
+ setHeaders(headers: readonly string[]): void
183
+ addHeader(text: string, index?: number): void
184
+ removeHeader(index: number): void
185
+ clearHeaders(): void
192
186
  ```
193
187
 
194
- #### Section-Specific Row Methods
195
-
196
- Methods using native `HTMLTableSectionElement` APIs for direct section manipulation:
188
+ #### Row Methods
197
189
 
198
190
  ```typescript
199
- // Generic section methods
200
- getSectionRows(section: HTMLTableSectionElement): HTMLCollectionOf<HTMLTableRowElement>
201
- insertSectionRow(section: HTMLTableSectionElement, data: RowData, index?: number, id?: string): HTMLTableRowElement
202
- deleteSectionRow(section: HTMLTableSectionElement, index: number): CellValue[] | undefined
203
- getSectionRowCount(section: HTMLTableSectionElement): number
204
-
205
- // thead-specific
206
- addHeadRow(data: RowData, index?: number): HTMLTableRowElement
207
- removeHeadRow(index: number): CellValue[] | undefined
208
- getHeadRowCount(): number
209
-
210
- // tfoot-specific
211
- addFootRow(data: RowData, index?: number): HTMLTableRowElement
212
- removeFootRow(index: number): CellValue[] | undefined
213
- getFootRowCount(): number
214
-
215
- // tbody-specific (supports multiple tbodies)
216
- addBodyRow(data: RowData, tbodyIndex?: number, rowIndex?: number, id?: string): HTMLTableRowElement
217
- removeBodyRow(rowIndex: number, tbodyIndex?: number): CellValue[] | undefined
218
- getBodyRowCount(tbodyIndex?: number): number
191
+ addRow(data: RowData, index?: number): HTMLTableRowElement | null
192
+ addRowWithId(data: RowData, id: string, index?: number): HTMLTableRowElement | null
193
+ removeRow(index: number): RowData | null
194
+ removeRowById(id: string): RowData | null
195
+ updateRow(index: number, data: RowData): void
196
+ clearRows(): void
197
+ getRow(index: number): HTMLTableRowElement | null
198
+ getRowById(id: string): HTMLTableRowElement | null
199
+ getRowId(index: number): string | null
219
200
  ```
220
201
 
221
202
  #### Column Methods
222
203
 
223
204
  ```typescript
224
- addColumn(header: CellValue, defaultValue?: CellValue, index?: number): void
205
+ addColumn(header?: string, index?: number): void
225
206
  removeColumn(index: number): void
226
- moveColumn(fromIndex: number, toIndex: number): void
227
- swapColumns(index1: number, index2: number): void
228
- getColumnData(columnIndex: number): readonly CellValue[]
229
- setColumnData(columnIndex: number, data: readonly CellValue[]): void
207
+ getColumnData(index: number): readonly CellValue[]
208
+ setColumnData(index: number, data: readonly CellValue[]): void
230
209
  ```
231
210
 
232
211
  #### Cell Methods
233
212
 
234
213
  ```typescript
235
- getCell(rowIndex: number, columnIndex: number): CellValue | undefined
236
- setCell(rowIndex: number, columnIndex: number, value: CellValue): void
237
- setCellByRowId(rowId: string, columnIndex: number, value: CellValue): boolean
238
- setCellRange(startRow: number, startCol: number, data: readonly (readonly CellValue[])[]): void
239
- getCellElement(rowIndex: number, columnIndex: number): HTMLTableCellElement | null
214
+ getCell(row: number, column: number): HTMLTableCellElement | null
215
+ getCellValue(row: number, column: number): CellValue
216
+ setCell(row: number, column: number, value: CellValue): void
240
217
  ```
241
218
 
242
219
  #### Selection Methods
@@ -247,84 +224,66 @@ deselectRow(index: number): void
247
224
  toggleRowSelection(index: number): void
248
225
  selectAllRows(): void
249
226
  deselectAllRows(): void
250
- selectRowRange(startIndex: number, endIndex: number): void
251
227
  isRowSelected(index: number): boolean
252
- getSelectedRowIndices(): number[]
253
- getSelectedRowData(): readonly CellValue[][]
228
+ getSelectedRowIndices(): readonly number[]
229
+ getSelectedRowData(): readonly (readonly CellValue[])[]
254
230
 
255
- selectCell(rowIndex: number, columnIndex: number): void
256
- deselectCell(rowIndex: number, columnIndex: number): void
257
- toggleCellSelection(rowIndex: number, columnIndex: number): void
258
- isCellSelected(rowIndex: number, columnIndex: number): boolean
231
+ selectCell(row: number, column: number): void
232
+ deselectCell(row: number, column: number): void
233
+ toggleCellSelection(row: number, column: number): void
234
+ isCellSelected(row: number, column: number): boolean
259
235
  clearSelection(): void
260
236
  ```
261
237
 
262
238
  #### Focus Methods
263
239
 
264
240
  ```typescript
265
- focusCell(rowIndex: number, columnIndex: number): void
241
+ focusCell(row: number, column: number): void
266
242
  clearFocus(): void
267
- getFocusedCell(): { row: number; column: number } | null
268
- isCellFocused(rowIndex: number, columnIndex: number): boolean
243
+ getFocusedCell(): CellPosition | null
244
+ isCellFocused(row: number, column: number): boolean
269
245
  moveFocusUp(): boolean
270
246
  moveFocusDown(): boolean
271
247
  moveFocusLeft(): boolean
272
248
  moveFocusRight(): boolean
273
- moveFocusToFirst(): void
274
- moveFocusToLast(): void
249
+ enableKeyboardNavigation(): () => void // Returns cleanup function
275
250
  ```
276
251
 
277
252
  #### Footer Methods
278
253
 
279
254
  ```typescript
280
- setFooter(data: readonly CellValue[]): void
281
- setFooterCell(index: number, value: CellValue): void
282
- getFooterCell(index: number): string | undefined
255
+ getFooter(): RowData | null
256
+ setFooter(data: RowData): void
283
257
  clearFooter(): void
284
258
  ```
285
259
 
286
- #### Record Methods
260
+ #### Caption Methods
287
261
 
288
262
  ```typescript
289
- setRecords<T extends BaseRecord>(
290
- records: readonly T[],
291
- fields: readonly (keyof T | ((record: T) => CellValue))[]
292
- ): void
293
-
294
- addRecord<T extends BaseRecord>(
295
- record: T,
296
- fields: readonly (keyof T | ((record: T) => CellValue))[],
297
- index?: number
298
- ): string
299
-
300
- getRecordData(id: string): readonly CellValue[] | undefined
301
- updateRecordRow(id: string, data: readonly CellValue[]): boolean
302
- removeRecord(id: string): boolean
303
- hasRecord(id: string): boolean
304
- selectRecords(ids: readonly string[]): void
305
- getSelectedRecordIds(): string[]
263
+ getCaption(): string | null
264
+ setCaption(text: string): void
265
+ ```
266
+
267
+ #### Bulk Operations
268
+
269
+ ```typescript
270
+ getData(): TableData
271
+ setData(data: TableData): void
272
+ sync(): void // Trigger reactive update
306
273
  ```
307
274
 
308
275
  #### Event Subscriptions
309
276
 
310
277
  ```typescript
311
- onRowAdd(callback: RowAddCallback): () => void
312
- onRowRemove(callback: RowRemoveCallback): () => void
313
- onRowUpdate(callback: RowUpdateCallback): () => void
314
- onCellChange(callback: CellChangeCallback): () => void
315
- onHeaderChange(callback: HeaderChangeCallback): () => void
316
- onDataChange(callback: DataChangeCallback): () => void
317
- onSelectionChange(callback: SelectionChangeCallback): () => void
318
- onFocusChange(callback: FocusChangeCallback): () => void
278
+ onRowAdd(callback: (index: number, id: string | null) => void): () => void
279
+ onRowRemove(callback: (index: number, id: string | null) => void): () => void
280
+ onDataChange(callback: () => void): () => void
319
281
  ```
320
282
 
321
283
  #### Lifecycle Methods
322
284
 
323
285
  ```typescript
324
- enableKeyboardNavigation(): () => void // Returns cleanup function
325
- sync(): void // Re-sync state from DOM
326
- destroy(): void // Cleanup all resources
327
- reset(): void // Clear all table content
286
+ destroy(): void // Cleanup all resources
328
287
  ```
329
288
 
330
289
  ### createTable
@@ -353,21 +312,22 @@ console.log(table.getRowCount()) // 3
353
312
  // Cell value can be string, number, boolean, null, or DOM element
354
313
  type CellValue = string | number | boolean | null | undefined | Node
355
314
 
356
- // Base record interface for record-based operations
357
- interface BaseRecord {
358
- id: string
359
- [key: string]: unknown
315
+ // Row data is an array of cell values
316
+ type RowData = readonly CellValue[]
317
+
318
+ // Table data is a 2D array
319
+ type TableData = readonly RowData[]
320
+
321
+ // Cell position for focus/navigation
322
+ interface CellPosition {
323
+ readonly row: number
324
+ readonly column: number
360
325
  }
361
326
 
362
327
  // Callback types
363
- type RowAddCallback = (data: readonly CellValue[], index: number, id: string | undefined) => void
364
- type RowRemoveCallback = (data: readonly CellValue[], index: number, id: string | undefined) => void
365
- type RowUpdateCallback = (data: readonly CellValue[], index: number) => void
366
- type CellChangeCallback = (rowIndex: number, columnIndex: number, oldValue: CellValue, newValue: CellValue) => void
367
- type HeaderChangeCallback = (headers: readonly string[]) => void
328
+ type RowAddCallback = (data: readonly CellValue[], index: number, id: string | null) => void
329
+ type RowRemoveCallback = (data: readonly CellValue[], index: number, id: string | null) => void
368
330
  type DataChangeCallback = (data: readonly (readonly CellValue[])[]) => void
369
- type SelectionChangeCallback = (rows: ReadonlySet<number>, cells: ReadonlySet<string>) => void
370
- type FocusChangeCallback = (cell: { row: number; column: number } | null) => void
371
331
  ```
372
332
 
373
333
  ## Examples