arthub-table 0.0.6 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +279 -0
  2. package/dist/arthub-table.common.js +1 -1
  3. package/dist/arthub-table.common.js.map +1 -1
  4. package/dist/arthub-table.umd.js +1 -1
  5. package/dist/arthub-table.umd.js.map +1 -1
  6. package/dist/arthub-table.umd.min.js +1 -1
  7. package/dist/arthub-table.umd.min.js.map +1 -1
  8. package/dist/types/adapters/DataGridEventAdapter.d.ts +109 -0
  9. package/dist/types/adapters/DataGridIntegration.d.ts +512 -0
  10. package/dist/types/adapters/columnAdapter.d.ts +73 -0
  11. package/dist/types/adapters/index.d.ts +9 -0
  12. package/dist/types/adapters/rowDataAdapter.d.ts +126 -0
  13. package/dist/types/adapters/styleAdapter.d.ts +38 -0
  14. package/dist/types/assets/icon/defaultAvatar.d.ts +5 -0
  15. package/dist/types/core/AddTaskRow.d.ts +66 -0
  16. package/dist/types/core/Body.d.ts +35 -26
  17. package/dist/types/core/Cell.d.ts +30 -0
  18. package/dist/types/core/ColumnHeader.d.ts +13 -0
  19. package/dist/types/core/Context.d.ts +2 -1
  20. package/dist/types/core/DataGrid.d.ts +770 -9
  21. package/dist/types/core/Editor.d.ts +1 -0
  22. package/dist/types/core/Events.d.ts +1 -0
  23. package/dist/types/core/GifOverlay.d.ts +5 -5
  24. package/dist/types/core/GroupRow.d.ts +84 -2
  25. package/dist/types/core/Header.d.ts +5 -0
  26. package/dist/types/core/ImageManager.d.ts +133 -0
  27. package/dist/types/core/NestedGrid.d.ts +158 -3
  28. package/dist/types/core/Paint.d.ts +16 -1
  29. package/dist/types/core/Row.d.ts +1 -1
  30. package/dist/types/core/RowHeader.d.ts +2 -0
  31. package/dist/types/core/StyleManager.d.ts +285 -0
  32. package/dist/types/core/constants.d.ts +35 -8
  33. package/dist/types/core/extension-type-mapping.d.ts +1 -1
  34. package/dist/types/core/types.d.ts +18 -1
  35. package/dist/types/core/viewers/AddButtonViewer.d.ts +16 -0
  36. package/dist/types/core/viewers/BooleanViewer.d.ts +8 -1
  37. package/dist/types/core/viewers/ChildrenViewer.d.ts +19 -0
  38. package/dist/types/core/viewers/DatetimeViewer.d.ts +4 -7
  39. package/dist/types/core/viewers/DeliverableReviewViewer.d.ts +11 -9
  40. package/dist/types/core/viewers/{SelectViewer.d.ts → DropdownViewer.d.ts} +6 -6
  41. package/dist/types/core/viewers/FileStorageSpecViewer.d.ts +3 -2
  42. package/dist/types/core/viewers/FileViewer.d.ts +44 -2
  43. package/dist/types/core/viewers/GroupHeaderViewer.d.ts +2 -1
  44. package/dist/types/core/viewers/HyperlinkTextViewer.d.ts +1 -0
  45. package/dist/types/core/viewers/ImageViewer.d.ts +45 -4
  46. package/dist/types/core/viewers/ItfsPathViewer.d.ts +32 -5
  47. package/dist/types/core/viewers/ModuleColExpandViewer.d.ts +16 -0
  48. package/dist/types/core/viewers/ModuleViewer.d.ts +4 -0
  49. package/dist/types/core/viewers/NameInputViewer.d.ts +11 -0
  50. package/dist/types/core/viewers/NestedGridViewer.d.ts +16 -1
  51. package/dist/types/core/viewers/OnlyShowErrorViewer.d.ts +20 -0
  52. package/dist/types/core/viewers/PersonViewer.d.ts +13 -6
  53. package/dist/types/core/viewers/PerspectiveViewer.d.ts +15 -0
  54. package/dist/types/core/viewers/ProgressViewer.d.ts +2 -4
  55. package/dist/types/core/viewers/PunchTimingViewer.d.ts +16 -4
  56. package/dist/types/core/viewers/PunchViewer.d.ts +5 -1
  57. package/dist/types/core/viewers/RichTextViewer.d.ts +8 -0
  58. package/dist/types/core/viewers/TableActionButtonViewer.d.ts +7 -0
  59. package/dist/types/core/viewers/TaskNodeViewer.d.ts +6 -0
  60. package/dist/types/core/viewers/TextViewer.d.ts +20 -0
  61. package/dist/types/core/viewers/TextViewerWithSwitcher.d.ts +21 -0
  62. package/dist/types/core/viewers/UpstreamViewer.d.ts +2 -1
  63. package/dist/types/core/viewers/WfStateViewer.d.ts +27 -0
  64. package/dist/types/core/viewers/WorkflowViewer.d.ts +5 -0
  65. package/dist/types/core/viewers/index.d.ts +21 -6
  66. package/dist/types/core/viewers/types.d.ts +95 -38
  67. package/dist/types/core/viewers/utils.d.ts +19 -0
  68. package/dist/types/index.d.ts +13 -3
  69. package/dist/types/testing/TestHooks.d.ts +117 -0
  70. package/package.json +1 -1
  71. package/dist/types/core/viewers/TreeDropdownViewer.d.ts +0 -55
package/README.md CHANGED
@@ -252,6 +252,285 @@ git tag v1.0.1
252
252
  git push origin v1.0.1
253
253
  ```
254
254
 
255
+ ## Table CRUD Operations — Best Practices
256
+
257
+ > This section documents how to perform Create, Read, Update, Delete operations on cells, rows, and columns using the DataGrid component.
258
+
259
+ ### Core Concepts
260
+
261
+ | Concept | Description |
262
+ | ---------------------- | ---------------------------------------------------------------------------------------- |
263
+ | `ref="datagrid"` | The Vue template ref to access the DataGrid component instance |
264
+ | `datagrid.value?.grid` | The underlying core `DataGrid` engine (for advanced low-level API) |
265
+ | `loadData(data)` | Re-render all rows with new data; resets editor and selection state |
266
+ | `reload()` | Recalculate table dimensions and scroll positions (after structural changes) |
267
+ | `markDirty()` | Lightweight: flags the canvas for repaint on the next animation frame |
268
+ | Vue Watcher | Modifying `columns` or `data` refs automatically triggers `loadColumns()` + `loadData()` |
269
+
270
+ ---
271
+
272
+ ### 1. Update a Single Cell
273
+
274
+ Use `grid.setData(value, { colIndex, rowIndex })` to write a value into a specific cell by its column and row index.
275
+
276
+ ```ts
277
+ const grid = (datagrid.value as any)?.grid;
278
+
279
+ // Update cell at row 0, column 2
280
+ grid.setData("New Value", { colIndex: 2, rowIndex: 0 });
281
+
282
+ // Trigger canvas repaint
283
+ grid.markDirty();
284
+ ```
285
+
286
+ > **Note:** `setData()` respects `readonly` columns. The cell's `originalValue` is preserved for change tracking.
287
+
288
+ ---
289
+
290
+ ### 2. Update an Entire Column
291
+
292
+ Loop through all data rows and call `cell.setData()` on each cell object:
293
+
294
+ ```ts
295
+ const grid = (datagrid.value as any)?.grid;
296
+ const colIndex = 2; // Target column index
297
+
298
+ gridData.value.forEach((_row, rowIndex) => {
299
+ if (_row.isGroup || _row.isSeparateRow) return; // Skip group/separator rows
300
+ const cell = grid.body.getCell(colIndex, rowIndex);
301
+ if (cell) {
302
+ cell.setData(`Col_Value_${rowIndex}`);
303
+ }
304
+ });
305
+
306
+ grid.markDirty();
307
+ ```
308
+
309
+ ---
310
+
311
+ ### 3. Batch Update a Rectangular Area
312
+
313
+ Use `grid.batchSetData({ colIndex, rowIndex, value })` where `value` is a 2D array:
314
+
315
+ ```ts
316
+ const grid = (datagrid.value as any)?.grid;
317
+
318
+ // Write a 3-row × 2-column block starting at [row=0, col=1]
319
+ grid.batchSetData({
320
+ colIndex: 1,
321
+ rowIndex: 0,
322
+ value: [
323
+ ["A1", "B1"],
324
+ ["A2", "B2"],
325
+ ["A3", "B3"],
326
+ ],
327
+ });
328
+
329
+ grid.markDirty();
330
+ ```
331
+
332
+ ---
333
+
334
+ ### 4. Update Rows by `rowKey` Match (Partial Update)
335
+
336
+ Use `updateData(data)` to merge updates into existing rows matched by the `rowKey` field (default `"id"`):
337
+
338
+ ```ts
339
+ datagrid.value?.updateData([
340
+ { id: 1, emp_name: "Updated Name 1", emp_no: "001" },
341
+ { id: 3, job_name: "Updated Job 3" },
342
+ ]);
343
+ ```
344
+
345
+ > **Behavior:** Only the fields you provide will be updated. Other fields in the row are unchanged. This does NOT trigger a full reload; it updates in-place.
346
+
347
+ ---
348
+
349
+ ### 5. Refresh the Visible Area
350
+
351
+ There are two levels of refresh:
352
+
353
+ | Method | When to Use |
354
+ | -------------------------- | ------------------------------------------------------------------------------------------------- |
355
+ | `grid.markDirty()` | After data-only changes (cell values). Lightweight, uses `requestAnimationFrame`. |
356
+ | `datagrid.value?.reload()` | After structural changes (columns added/removed, row heights changed). Full resize + recalculate. |
357
+
358
+ ```ts
359
+ // Lightweight repaint
360
+ const grid = (datagrid.value as any)?.grid;
361
+ grid.markDirty();
362
+
363
+ // Full reload (after structural changes)
364
+ await nextTick();
365
+ datagrid.value?.reload();
366
+ ```
367
+
368
+ ---
369
+
370
+ ### 6. Add a Row
371
+
372
+ Append a new row object to the data array and call `loadData()`:
373
+
374
+ ```ts
375
+ const newRow = {
376
+ _rowId: `row_${Date.now()}`,
377
+ id: gridData.value.length + 1,
378
+ };
379
+
380
+ // Dynamically fill all column keys with default values
381
+ for (const col of columns.value) {
382
+ if (col.key && !(col.key in newRow)) {
383
+ newRow[col.key] = col.type === "number" ? 0 : "";
384
+ }
385
+ }
386
+
387
+ gridData.value.push(newRow);
388
+ datagrid.value?.loadData(gridData.value);
389
+ ```
390
+
391
+ > **Grouped mode:** Insert the row at the correct position within `groupedDataCache`, then filter and reload. See the `onAddRow()` handler in `App.vue` for a complete example.
392
+
393
+ ---
394
+
395
+ ### 7. Delete a Row
396
+
397
+ Remove the row from the data array and reload:
398
+
399
+ ```ts
400
+ const indexToDelete = gridData.value.findIndex(
401
+ (row) => !row.isGroup && !row.isSeparateRow,
402
+ );
403
+
404
+ if (indexToDelete >= 0) {
405
+ gridData.value.splice(indexToDelete, 1);
406
+ datagrid.value?.loadData(gridData.value);
407
+ }
408
+ ```
409
+
410
+ ---
411
+
412
+ ### 8. Add a Column
413
+
414
+ Add a new column definition to the `columns` ref. The Vue watcher will automatically trigger `loadColumns()` + `loadData()`:
415
+
416
+ ```ts
417
+ const newCol = {
418
+ title: "New Column",
419
+ key: "new_col",
420
+ size: "small",
421
+ align: "left",
422
+ };
423
+
424
+ // Insert at a specific position
425
+ const newColumns = [...columns.value];
426
+ newColumns.splice(insertIndex, 0, newCol);
427
+ columns.value = newColumns;
428
+
429
+ // Fill data for the new column
430
+ gridData.value.forEach((row, i) => {
431
+ if (!row.isGroup) {
432
+ row[newCol.key] = `Value_${i}`;
433
+ }
434
+ });
435
+ ```
436
+
437
+ ---
438
+
439
+ ### 9. Delete a Column
440
+
441
+ Remove the column from the `columns` ref:
442
+
443
+ ```ts
444
+ const colIndexToDelete = columns.value.findIndex(
445
+ (col) => col.key === "target_key",
446
+ );
447
+
448
+ if (colIndexToDelete >= 0) {
449
+ const newColumns = [...columns.value];
450
+ newColumns.splice(colIndexToDelete, 1);
451
+ columns.value = newColumns;
452
+ }
453
+ ```
454
+
455
+ ---
456
+
457
+ ### 10. Read Data
458
+
459
+ | Method | Returns | Description |
460
+ | --------------------------------------- | ----------- | --------------------------------------- |
461
+ | `datagrid.value?.getData()` | `RowData[]` | All row data with merged cell values |
462
+ | `datagrid.value?.getCheckedRows()` | `RowData[]` | Rows where checkbox is checked |
463
+ | `datagrid.value?.getChangedRows()` | `RowData[]` | Rows that have been modified since load |
464
+ | `grid.body.getRowData(rowIndex)` | `RowData` | A single row by index |
465
+ | `grid.body.getCell(colIndex, rowIndex)` | `Cell` | A single cell object |
466
+
467
+ ```ts
468
+ // Get all data
469
+ const allData = datagrid.value?.getData();
470
+
471
+ // Get changed rows only
472
+ const changedRows = datagrid.value?.getChangedRows();
473
+
474
+ // Get a single cell's value
475
+ const grid = (datagrid.value as any)?.grid;
476
+ const cell = grid.body.getCell(2, 0);
477
+ console.log(cell.value); // Current cell value
478
+ ```
479
+
480
+ ---
481
+
482
+ ### 11. Validation
483
+
484
+ ```ts
485
+ // Validate all cells
486
+ datagrid.value?.validate((valid) => {
487
+ if (!valid) {
488
+ const errors = datagrid.value?.getValidations();
489
+ console.log("Validation errors:", errors);
490
+ }
491
+ });
492
+
493
+ // Validate only changed rows
494
+ datagrid.value?.validateChanged((valid) => {
495
+ /* ... */
496
+ });
497
+
498
+ // Set external validation errors (matched by rowKey)
499
+ datagrid.value?.setValidations([
500
+ { id: 1, emp_name: "Name is required", emp_no: "Invalid number" },
501
+ { id: 3, job_name: "Job name too long" },
502
+ ]);
503
+
504
+ // Clear all validations
505
+ datagrid.value?.clearValidations();
506
+ ```
507
+
508
+ ---
509
+
510
+ ### 12. Undo / Redo
511
+
512
+ Built-in keyboard shortcuts:
513
+
514
+ | Shortcut | Action |
515
+ | ------------------------ | -------------- |
516
+ | `Ctrl+Z` / `Cmd+Z` | Undo last edit |
517
+ | `Ctrl+Y` / `Cmd+Shift+Z` | Redo last undo |
518
+
519
+ > History is automatically tracked for `doneEdit()`, `pasteData()`, `autofillData()`, and `clearSelectedData()` operations. Max 20 history entries.
520
+
521
+ ---
522
+
523
+ ### Complete Example
524
+
525
+ See `App.vue` for interactive demonstrations of all these patterns. The toolbar includes buttons for:
526
+
527
+ - **✏️ 更新单个格子** — Single cell update via `grid.setData()`
528
+ - **📝 更新整列** — Column-wide update via `cell.setData()` loop
529
+ - **📋 批量更新区域** — Batch area update via `grid.batchSetData()`
530
+ - **🔄 刷新可见区域** — Canvas repaint via `grid.markDirty()`
531
+ - **➕ 新增一行 / ➕ 新增一列** — Dynamic row/column addition
532
+ - **🗑️ 删除首行 / 🗑️ 删除末列** — Row/column deletion
533
+
255
534
  ## License
256
535
 
257
536
  [MIT](LICENSE)