@guiexpert/table 1.1.93 → 1.1.96

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 (123) hide show
  1. package/README.md +25 -0
  2. package/css/main.css +334 -0
  3. package/css/table-calc.css +7 -0
  4. package/css/table-classes.css +34 -0
  5. package/css/table-color-vars.css +78 -0
  6. package/css/table-fill-batch.css +58 -0
  7. package/css/table-pivot.css +42 -0
  8. package/css/table-row-drag.css +81 -0
  9. package/css/table-row-group.css +25 -0
  10. package/css/table-tree.css +9 -0
  11. package/index.cjs +57 -47
  12. package/index.d.ts +67 -0
  13. package/index.js +11290 -4985
  14. package/lib/table/action/action-id.type.d.ts +1 -1
  15. package/lib/table/aggregation/aggregate-internals.d.ts +30 -0
  16. package/lib/table/aggregation/aggregate-spec.if.d.ts +51 -0
  17. package/lib/table/aggregation/aggregate.d.ts +58 -0
  18. package/lib/table/aggregation/aggregator-name.type.d.ts +39 -0
  19. package/lib/table/aggregation/aggregator.if.d.ts +51 -0
  20. package/lib/table/aggregation/aggregators.d.ts +37 -0
  21. package/lib/table/aggregation/create-value-getter.d.ts +18 -0
  22. package/lib/table/aggregation/selection-aggregates.if.d.ts +35 -0
  23. package/lib/table/aggregation/value-accessor.type.d.ts +13 -0
  24. package/lib/table/aria/aria-texts.d.ts +11 -0
  25. package/lib/table/aria/aria-texts.if.d.ts +87 -0
  26. package/lib/table/batch-edit/batch-edit-options.d.ts +21 -0
  27. package/lib/table/batch-edit/batch-edit-options.if.d.ts +20 -0
  28. package/lib/table/batch-edit/batch-edit-service.d.ts +104 -0
  29. package/lib/table/batch-edit/cell-change.if.d.ts +39 -0
  30. package/lib/table/batch-edit/cell-value-change.if.d.ts +18 -0
  31. package/lib/table/batch-edit/pending-cell-changes.d.ts +104 -0
  32. package/lib/table/calc/column-values.d.ts +55 -0
  33. package/lib/table/calc/show-values-as-internals.d.ts +4 -0
  34. package/lib/table/calc/show-values-as.d.ts +87 -0
  35. package/lib/table/calc/show-values-as.type.d.ts +55 -0
  36. package/lib/table/calc/value-getter-context.if.d.ts +35 -0
  37. package/lib/table/calc/value-getter.type.d.ts +36 -0
  38. package/lib/table/data/common/event/ge-batch-edit-event.d.ts +46 -0
  39. package/lib/table/data/common/event/ge-model-change-event.d.ts +27 -1
  40. package/lib/table/data/common/event/ge-row-drag-event.d.ts +89 -0
  41. package/lib/table/data/common/row-number-column-def.d.ts +107 -0
  42. package/lib/table/data/common/row-number-columns.d.ts +17 -0
  43. package/lib/table/data/common/row-number-options.d.ts +19 -0
  44. package/lib/table/data/common/row-number-options.if.d.ts +44 -0
  45. package/lib/table/data/options/table-options.d.ts +6 -0
  46. package/lib/table/data/options/table-options.if.d.ts +44 -0
  47. package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +66 -0
  48. package/lib/table/data/tablemodel/areamodel/aggregate-footer-options.if.d.ts +73 -0
  49. package/lib/table/data/tablemodel/areamodel/area-model-aggregate-footer.d.ts +150 -0
  50. package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +24 -0
  51. package/lib/table/data/tablemodel/areamodel/area-model-cell-groups.d.ts +18 -1
  52. package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +70 -0
  53. package/lib/table/data/tablemodel/areamodel/area-model-pivot-footer.d.ts +47 -0
  54. package/lib/table/data/tablemodel/areamodel/area-model-pivot.d.ts +281 -0
  55. package/lib/table/data/tablemodel/areamodel/area-model-row-groups.d.ts +336 -0
  56. package/lib/table/data/tablemodel/areamodel/area-model-tree.d.ts +97 -0
  57. package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +94 -0
  58. package/lib/table/data/tablemodel/areamodel/derived-values-change.if.d.ts +30 -0
  59. package/lib/table/data/tablemodel/column/column-def.d.ts +31 -1
  60. package/lib/table/data/tablemodel/column/column-def.if.d.ts +86 -0
  61. package/lib/table/event-adapter.d.ts +7 -0
  62. package/lib/table/event-listener.if.d.ts +32 -0
  63. package/lib/table/factory/pivot-factory.d.ts +63 -0
  64. package/lib/table/factory/pivot-table-model-para.if.d.ts +44 -0
  65. package/lib/table/factory/row-group-factory.d.ts +70 -0
  66. package/lib/table/factory/row-group-table-model-para.if.d.ts +66 -0
  67. package/lib/table/factory/table-factory.d.ts +56 -1
  68. package/lib/table/fill/compute-fill-changes.d.ts +67 -0
  69. package/lib/table/fill/fill-direction.type.d.ts +7 -0
  70. package/lib/table/fill/fill-handle-options.d.ts +29 -0
  71. package/lib/table/fill/fill-handle-options.if.d.ts +35 -0
  72. package/lib/table/fill/fill-handle-service.d.ts +55 -0
  73. package/lib/table/fill/fill-series.d.ts +60 -0
  74. package/lib/table/fill/fill-value-context.if.d.ts +36 -0
  75. package/lib/table/formula/compile-formula.d.ts +86 -0
  76. package/lib/table/formula/evaluator.d.ts +19 -0
  77. package/lib/table/formula/formula-ast.if.d.ts +42 -0
  78. package/lib/table/formula/formula-error.d.ts +59 -0
  79. package/lib/table/formula/formula-options.if.d.ts +41 -0
  80. package/lib/table/formula/formula-values.d.ts +13 -0
  81. package/lib/table/formula/functions.d.ts +18 -0
  82. package/lib/table/formula/parser.d.ts +10 -0
  83. package/lib/table/formula/tokenizer.d.ts +22 -0
  84. package/lib/table/instanceof-workaround.d.ts +143 -6
  85. package/lib/table/pivot/area-model-pivot-header.d.ts +9 -0
  86. package/lib/table/pivot/pivot-column-def.d.ts +28 -0
  87. package/lib/table/pivot/pivot-column-info.if.d.ts +25 -0
  88. package/lib/table/pivot/pivot-config.if.d.ts +58 -0
  89. package/lib/table/pivot/pivot-internals.d.ts +13 -0
  90. package/lib/table/pivot/pivot-layout.d.ts +40 -0
  91. package/lib/table/pivot/pivot-result.d.ts +157 -0
  92. package/lib/table/pivot/pivot-table-model.d.ts +86 -0
  93. package/lib/table/pivot/pivot-value.type.d.ts +80 -0
  94. package/lib/table/render-scope.d.ts +142 -4
  95. package/lib/table/renderer/aggregate-cell-renderer.d.ts +27 -0
  96. package/lib/table/renderer/edit/input-cell-renderer.d.ts +1 -1
  97. package/lib/table/renderer/edit/select-cell-renderer.d.ts +1 -1
  98. package/lib/table/renderer/row-number-cell-renderer.d.ts +27 -0
  99. package/lib/table/row-drag/move-rows.d.ts +157 -0
  100. package/lib/table/row-drag/row-drag-options.d.ts +28 -0
  101. package/lib/table/row-drag/row-drag-options.if.d.ts +36 -0
  102. package/lib/table/row-drag/row-drag-service.d.ts +130 -0
  103. package/lib/table/row-drag/row-drop-target.if.d.ts +29 -0
  104. package/lib/table/rowgroup/group-rows-internals.d.ts +14 -0
  105. package/lib/table/rowgroup/group-rows-options.if.d.ts +13 -0
  106. package/lib/table/rowgroup/group-rows.d.ts +48 -0
  107. package/lib/table/rowgroup/row-group-column-def.d.ts +26 -0
  108. package/lib/table/rowgroup/row-group-column-options.if.d.ts +27 -0
  109. package/lib/table/rowgroup/row-group-detail-row.d.ts +8 -0
  110. package/lib/table/rowgroup/row-group-field.type.d.ts +56 -0
  111. package/lib/table/rowgroup/row-group-internals.d.ts +31 -0
  112. package/lib/table/rowgroup/row-group-layout.d.ts +13 -0
  113. package/lib/table/rowgroup/row-group-model-options.if.d.ts +39 -0
  114. package/lib/table/rowgroup/row-group.d.ts +51 -0
  115. package/lib/table/rowgroup/row-group.if.d.ts +48 -0
  116. package/lib/table/selection/selection-aggregator.d.ts +37 -0
  117. package/lib/table/selection/selection-service.d.ts +7 -0
  118. package/lib/table/service/convenience-dom.service.d.ts +5 -0
  119. package/lib/table/service/excel-service.d.ts +6 -0
  120. package/lib/table/service/excel-service.if.d.ts +35 -0
  121. package/lib/table/table-api.d.ts +389 -3
  122. package/lib/table/table-scope.d.ts +140 -0
  123. package/package.json +3 -2
package/README.md CHANGED
@@ -29,6 +29,31 @@ This is the UI-agnostic table component for your next web app. 😊
29
29
  sorting, filter and copy) and full keyboard navigation (arrows, Home/End, Page Up/Down, header focus, Enter) – since 1.1.91
30
30
  - Overlays "Loading…" (CSS spinner, `tableApi.showLoadingOverlay()`, `loading` prop in the wrappers) and
31
31
  "No rows to show" / "No matching rows" (automatic) – plain HTML/CSS, since 1.1.92
32
+ - Row numbers like in a spreadsheet (`rowNumbersVisible: true` or `RowNumberColumnDef`): fixed on the left, width
33
+ fits the largest number, click selects the row, view or original order – since 1.1.93
34
+ - Aggregation: total rows in the footer that follow filter and sorting (`footerAggregates: { quantity: "sum", total: "avg" }`,
35
+ `AreaModelAggregateFooter`), helpers `aggregate()` / `aggregateColumns()` with mergeable aggregators (sum, count, avg,
36
+ min, max, countDistinct, first, last or your own), and count/sum/average of the selected cells for a status bar
37
+ (`tableApi.getSelectionAggregates()`) – since 1.1.94
38
+ - Row grouping with aggregation: flat rows grouped by one or more properties or functions, group rows with arrow,
39
+ label (`"Berlin (12)"`) and sum/average/… per column, total row, filter and sorting by aggregate, regroup at runtime
40
+ (`RowGroupFactory.createTableModel({ rows, groupBy, aggregations })`, `tableApi.setRowGroupBy()`) – since 1.1.94
41
+ - Pivot tables: row fields (a hierarchy with subtotals) × column fields (their values become columns, several fields
42
+ = a multi-row header with collapsible groups) × aggregated values, total column and total row, filter before the
43
+ aggregation, pivot again at runtime (`PivotFactory.createTableModel({ rows, rowFields, columnFields, values })`,
44
+ `tableApi.setPivotConfig()`, engine `pivotRows()`) – since 1.1.94
45
+ - Calculated columns (`ColumnDef.valueGetter` – sorting, filter via `tableApi.getRowValue()`, copy, Excel, totals and
46
+ row grouping use the computed value), „Show values as“ (`showValuesAs`: share of the column / row / grand / parent
47
+ total, running total, difference, rank – also per pivot value) and formulas (`formula: "[price] * [quantity] * 1.19"`,
48
+ own parser and interpreter without `eval`, functions like `ROUND`, `IF`, `SUM([x])`, error values `#DIV/0!`,
49
+ `tableApi.setColumnFormula()`) – since 1.1.95
50
+ - Row drag: drag handle per row (`ColumnDef.rowDrag` or `rowDrag: true` in the factory), mouse, touch and pen, ghost,
51
+ drop marker, auto-scroll, Escape, keyboard alternative Ctrl+Alt+↑/↓, several selected rows, trees; the table moves
52
+ the rows (managed) or only reports the drop (`rowDragOptions: { managed: false }`, `onRowDragEnd`) – since 1.1.95
53
+ - Fill handle and batch edit: a square at the corner of the selected range copies values or continues series (numbers,
54
+ dates, `Item 1` → `Item 2`; ⌥/Alt switches, Ctrl/⌘+D, Ctrl/⌘+R), batch edit collects changes (`ge-table-cell-pending`)
55
+ until `tableApi.commitBatchEdit()` / `cancelBatchEdit()`, `ColumnDef.validate`, one `onModelChanged` per change with
56
+ old and new values (`tableOptions.fillHandle`, `tableOptions.batchEdit`) – since 1.1.96
32
57
  - Custom Filtering
33
58
  - In-place Cell Editing
34
59
  - Userdefined Key and Mouse Events
package/css/main.css CHANGED
@@ -1,3 +1,10 @@
1
+ /* Calculated columns, „Show values as“, formulas (since 1.1.95) */
2
+
3
+ /* a cell with a formula error (#DIV/0!, #NAME? …): the message is the tooltip */
4
+ .ge-table-col-div.ge-table-cell-error {
5
+ color: var(--ge-table-cell-error-color);
6
+ font-variant-numeric: tabular-nums;
7
+ }
1
8
  /* Defaults for the host element. :where() = zero specificity, so the app's own rules always win –
2
9
  e.g. ".table-div { height: 500px }" no longer depends on the order in which the stylesheets are bundled. */
3
10
  :where(.ge-table) {
@@ -46,6 +53,27 @@
46
53
  padding-right: 10px;
47
54
  }
48
55
 
56
+ /* Total rows of AreaModelAggregateFooter (1.1.94) – before the align classes, so a column's footer class wins */
57
+ .ge-table-footer-aggregate {
58
+ text-align: end;
59
+ font-variant-numeric: tabular-nums;
60
+ }
61
+
62
+ .ge-table-footer-label {
63
+ font-weight: 600;
64
+ text-align: start;
65
+ }
66
+
67
+ /* the next footer cell is empty: the label may run into it instead of being cut off */
68
+ .ge-table-footer-label-overflow {
69
+ z-index: 1;
70
+ white-space: nowrap;
71
+ }
72
+
73
+ .ge-table-footer-label-overflow .ge-table-label-div {
74
+ overflow: visible;
75
+ }
76
+
49
77
  .ge-table-text-align-left {
50
78
  text-align: left;
51
79
  }
@@ -154,6 +182,19 @@
154
182
  }
155
183
 
156
184
 
185
+ /* Row numbers (RowNumberColumnDef, since 1.1.93): right aligned, digits of equal width. Before the color classes
186
+ in main.css, so that the selection colors (.ge-table-body-west-selected-range …) still win. */
187
+ .ge-table-row-number {
188
+ background-color: var(--ge-table-row-number-bg);
189
+ color: var(--ge-table-row-number-color);
190
+ }
191
+ .ge-table-row-number .ge-table-label,
192
+ .ge-table-row-number-header .ge-table-label {
193
+ padding-inline: 6px;
194
+ font-variant-numeric: tabular-nums;
195
+ }
196
+
197
+
157
198
  /* Overlays over the body: "Loading…" with a CSS spinner, "No rows to show", "No matching rows" (since 1.1.92).
158
199
  Position and size are set inline by the table (the visible body), display is switched inline (none / flex). */
159
200
  .ge-table-overlay {
@@ -400,6 +441,21 @@
400
441
  --ge-table-color-star-rating: #a86f00;
401
442
  --ge-table-color-progress-bar: #1e874b;
402
443
 
444
+ /* Row grouping: group rows (since 1.1.94) */
445
+ --ge-table-row-group-bg: rgba(0, 0, 0, 0.045);
446
+ --ge-table-row-group-text: inherit;
447
+ --ge-table-row-group-label-font-weight: 600;
448
+
449
+ /* Pivot tables: subtotals, totals, empty cells (since 1.1.94) */
450
+ --ge-table-pivot-subtotal-bg: rgba(0, 0, 0, 0.035);
451
+ --ge-table-pivot-subtotal-font-weight: 600;
452
+ --ge-table-pivot-total-bg: rgba(0, 0, 0, 0.07);
453
+ --ge-table-pivot-total-font-weight: 600;
454
+ --ge-table-pivot-empty-text: #6b7280;
455
+
456
+ /* Formulas: error values #DIV/0!, #NAME? … (since 1.1.95) */
457
+ --ge-table-cell-error-color: #b91c1c;
458
+
403
459
  /* Overlays "Loading…" / "No rows" (since 1.1.92) */
404
460
  --ge-table-overlay-bg: rgba(255, 255, 255, 0.7);
405
461
  --ge-table-overlay-content-bg: #fff;
@@ -407,6 +463,30 @@
407
463
  --ge-table-spinner-color: #1a73e8;
408
464
  --ge-table-spinner-track-color: rgba(0, 0, 0, 0.12);
409
465
  --ge-table-spinner-size: 28px;
466
+
467
+ /* Row numbers (since 1.1.93): like the header, muted digits (#555 on the header gray ≈ 6.9 : 1) */
468
+ --ge-table-row-number-bg: var(--ge-table-header-west-bg);
469
+ --ge-table-row-number-color: #555;
470
+
471
+ /* Row drag (since 1.1.95): handle ≥ 3 : 1 against white (WCAG 1.4.11), marker, ghost */
472
+ --ge-table-row-drag-handle-color: #6b7280;
473
+ --ge-table-row-drop-indicator-color: #1a73e8;
474
+ --ge-table-row-drop-inside-bg: rgba(26, 115, 232, 0.12);
475
+ --ge-table-row-drag-ghost-bg: #fff;
476
+ --ge-table-row-drag-ghost-text: #1f2937;
477
+ --ge-table-row-drag-ghost-border: #1a73e8;
478
+ --ge-table-row-dragging-opacity: 0.4;
479
+
480
+ /* Fill handle and batch edit (since 1.1.96): handle and preview like the selection, pending = yellow, invalid = red */
481
+ --ge-table-fill-handle-color: #0a6ebd;
482
+ --ge-table-fill-handle-border: #fff;
483
+ --ge-table-fill-preview-border: #0a6ebd;
484
+ --ge-table-cell-pending-bg: #fff3c4;
485
+ --ge-table-cell-pending-text: #3d2e00;
486
+ --ge-table-cell-pending-marker: #c27c00;
487
+ --ge-table-cell-invalid-bg: #fde2e1;
488
+ --ge-table-cell-invalid-text: #8a1c14;
489
+ --ge-table-cell-invalid-border: #d93025;
410
490
  }
411
491
 
412
492
 
@@ -482,6 +562,21 @@ html[data-theme="dark"] {
482
562
  --ge-table-color-star-rating: #fcb515;
483
563
  --ge-table-color-progress-bar: #36BB6C;
484
564
 
565
+ /* Row grouping: group rows (since 1.1.94) */
566
+ --ge-table-row-group-bg: rgba(255, 255, 255, 0.06);
567
+ --ge-table-row-group-text: inherit;
568
+ --ge-table-row-group-label-font-weight: 600;
569
+
570
+ /* Pivot tables: subtotals, totals, empty cells (since 1.1.94) */
571
+ --ge-table-pivot-subtotal-bg: rgba(255, 255, 255, 0.05);
572
+ --ge-table-pivot-subtotal-font-weight: 600;
573
+ --ge-table-pivot-total-bg: rgba(255, 255, 255, 0.1);
574
+ --ge-table-pivot-total-font-weight: 600;
575
+ --ge-table-pivot-empty-text: #9ca3af;
576
+
577
+ /* Formulas: error values #DIV/0!, #NAME? … (since 1.1.95) */
578
+ --ge-table-cell-error-color: #f87171;
579
+
485
580
  /* Overlays "Loading…" / "No rows" (since 1.1.92) */
486
581
  --ge-table-overlay-bg: rgba(17, 24, 39, 0.7); /* --ge-table-bg of the dark theme */
487
582
  --ge-table-overlay-content-bg: #1f2937;
@@ -489,6 +584,236 @@ html[data-theme="dark"] {
489
584
  --ge-table-spinner-color: #8ab4f8;
490
585
  --ge-table-spinner-track-color: rgba(255, 255, 255, 0.18);
491
586
  --ge-table-spinner-size: 28px;
587
+
588
+ /* Row numbers (since 1.1.93) */
589
+ --ge-table-row-number-bg: var(--ge-table-header-west-bg);
590
+ --ge-table-row-number-color: #aaa;
591
+
592
+ /* Row drag (since 1.1.95) */
593
+ --ge-table-row-drag-handle-color: #9ca3af;
594
+ --ge-table-row-drop-indicator-color: #8ab4f8;
595
+ --ge-table-row-drop-inside-bg: rgba(138, 180, 248, 0.16);
596
+ --ge-table-row-drag-ghost-bg: #1f2937;
597
+ --ge-table-row-drag-ghost-text: #f3f4f6;
598
+ --ge-table-row-drag-ghost-border: #8ab4f8;
599
+ --ge-table-row-dragging-opacity: 0.4;
600
+
601
+ /* Fill handle and batch edit (since 1.1.96) */
602
+ --ge-table-fill-handle-color: #8ab4f8;
603
+ --ge-table-fill-handle-border: #1e1e1e;
604
+ --ge-table-fill-preview-border: #8ab4f8;
605
+ --ge-table-cell-pending-bg: #4a3b0b;
606
+ --ge-table-cell-pending-text: #fde68a;
607
+ --ge-table-cell-pending-marker: #f5b82e;
608
+ --ge-table-cell-invalid-bg: #5c1d1a;
609
+ --ge-table-cell-invalid-text: #fecaca;
610
+ --ge-table-cell-invalid-border: #f28b82;
611
+ }
612
+ /* Fill handle and batch edit (since 1.1.96) – colors in table-color-vars.css (--ge-table-fill-*, --ge-table-cell-*) */
613
+
614
+ /* the square at the bottom right corner of the selected range; its center sits on the corner */
615
+ .ge-table-fill-handle {
616
+ position: absolute;
617
+ z-index: 9000; /* above the cells, below the overlay (10000) */
618
+ width: 7px;
619
+ height: 7px;
620
+ margin: -4px 0 0 -4px;
621
+ box-sizing: border-box;
622
+ background: var(--ge-table-fill-handle-color);
623
+ border: 1px solid var(--ge-table-fill-handle-border);
624
+ cursor: crosshair;
625
+ touch-action: none; /* touch drags the handle instead of scrolling */
626
+ }
627
+
628
+ /* a bigger target for touch and pen (the visible square stays small) */
629
+ .ge-table-fill-handle::after {
630
+ content: "";
631
+ position: absolute;
632
+ inset: -8px;
633
+ }
634
+
635
+ /* the cells a fill will cover */
636
+ .ge-table-fill-preview {
637
+ position: absolute;
638
+ z-index: 8999;
639
+ box-sizing: border-box;
640
+ border: 2px dashed var(--ge-table-fill-preview-border);
641
+ pointer-events: none;
642
+ }
643
+
644
+ .ge-table-fill-active,
645
+ .ge-table-fill-active * {
646
+ cursor: crosshair !important;
647
+ user-select: none;
648
+ }
649
+
650
+ /* batch edit: a value that is not saved yet – a colored cell and a small corner mark (not color only, WCAG 1.4.1) */
651
+ .ge-table-col-div.ge-table-cell-pending {
652
+ background-image: linear-gradient(225deg, var(--ge-table-cell-pending-marker) 6px, transparent 6px);
653
+ }
654
+
655
+ /* the color only while the cell is not selected – a selected cell keeps the selection color (and the corner mark) */
656
+ .ge-table-col-div.ge-table-cell-pending:not([class*="-selected-range"]) {
657
+ background-color: var(--ge-table-cell-pending-bg);
658
+ color: var(--ge-table-cell-pending-text);
659
+ }
660
+
661
+ /* an invalid value (ColumnDef.validate): the message is the tooltip */
662
+ .ge-table-col-div.ge-table-cell-invalid:not([class*="-selected-range"]) {
663
+ background-color: var(--ge-table-cell-invalid-bg);
664
+ color: var(--ge-table-cell-invalid-text);
665
+ }
666
+
667
+ .ge-table-col-div.ge-table-cell-invalid {
668
+ box-shadow: inset 0 0 0 2px var(--ge-table-cell-invalid-border);
669
+ }
670
+ /* Pivot tables (PivotFactory / AreaModelPivot, since 1.1.94) */
671
+
672
+ /* every value cell: numbers on the end side, same digit widths */
673
+ .ge-table-pivot-value {
674
+ text-align: end;
675
+ font-variant-numeric: tabular-nums;
676
+ }
677
+
678
+ /* the label in the group column ("Nord") */
679
+ .ge-table-pivot-label .ge-table-label-div {
680
+ white-space: nowrap;
681
+ overflow: hidden;
682
+ text-overflow: ellipsis;
683
+ }
684
+
685
+ /* subtotals: group rows and the total columns of column groups */
686
+ .ge-table-col-div.ge-table-pivot-subtotal {
687
+ background-color: var(--ge-table-pivot-subtotal-bg);
688
+ font-weight: var(--ge-table-pivot-subtotal-font-weight);
689
+ }
690
+
691
+ /* totals: the total column(s) and the total row */
692
+ .ge-table-col-div.ge-table-pivot-total {
693
+ background-color: var(--ge-table-pivot-total-bg);
694
+ font-weight: var(--ge-table-pivot-total-font-weight);
695
+ }
696
+
697
+ /* a combination without data (emptyText, e.g. "–") */
698
+ .ge-table-pivot-empty {
699
+ color: var(--ge-table-pivot-empty-text);
700
+ }
701
+
702
+ /* header: a column group ("2026", "Jan") starts at the left of its span, a column label ("Q1", "Revenue") sits above
703
+ its numbers (value columns only – the group column keeps its alignment) */
704
+ .ge-table-pivot-header-group {
705
+ text-align: start;
706
+ padding-inline-start: 6px;
707
+ }
708
+
709
+ .ge-table-pivot-header.ge-table-pivot-header-column {
710
+ text-align: end;
711
+ }
712
+ /* Row drag (since 1.1.95): handle, ghost, drop marker – colors in table-color-vars.css (--ge-table-row-drag-*) */
713
+
714
+ /* the cell with the handle: room for the grip at the start (a tree cell has its indent already) */
715
+ .ge-table-row-drag-cell:not(.ge-table-col-tree) {
716
+ box-sizing: border-box;
717
+ padding-inline-start: 16px;
718
+ }
719
+
720
+ /* the grip: 2 × 3 dots, drawn with CSS (no text, no image); touch-action: none = touch drags instead of scrolling */
721
+ .ge-table-row-drag-handle {
722
+ position: absolute;
723
+ inset-inline-start: 2px;
724
+ top: 50%;
725
+ width: 12px;
726
+ height: 18px;
727
+ margin-top: -9px;
728
+ cursor: grab;
729
+ touch-action: none;
730
+ border-radius: 3px;
731
+ background-image: radial-gradient(circle, var(--ge-table-row-drag-handle-color) 1.5px, transparent 1.6px);
732
+ background-size: 6px 6px;
733
+ background-position: 0 0;
734
+ }
735
+
736
+ .ge-table-row-drag-handle:hover {
737
+ background-color: rgba(128, 128, 128, 0.15);
738
+ }
739
+
740
+ /* managed drag while the table is sorted or filtered */
741
+ .ge-table-row-drag-handle.ge-table-row-drag-handle-disabled {
742
+ cursor: not-allowed;
743
+ opacity: 0.35;
744
+ }
745
+
746
+ /* the dragged rows while the drag runs */
747
+ .ge-table-row-dragging {
748
+ opacity: var(--ge-table-row-dragging-opacity);
749
+ }
750
+
751
+ .ge-table-row-drag-active,
752
+ .ge-table-row-drag-active * {
753
+ cursor: grabbing !important;
754
+ }
755
+
756
+ .ge-table-row-drag-active.ge-table-row-drag-invalid,
757
+ .ge-table-row-drag-active.ge-table-row-drag-invalid * {
758
+ cursor: no-drop !important;
759
+ }
760
+
761
+ .ge-table-row-drag-ghost {
762
+ position: absolute;
763
+ z-index: 10001; /* above the overlay (10000) */
764
+ pointer-events: none;
765
+ max-width: 280px;
766
+ padding: 4px 10px;
767
+ overflow: hidden;
768
+ white-space: nowrap;
769
+ text-overflow: ellipsis;
770
+ font-size: 0.9em;
771
+ line-height: 1.5;
772
+ color: var(--ge-table-row-drag-ghost-text);
773
+ background: var(--ge-table-row-drag-ghost-bg);
774
+ border: 1px solid var(--ge-table-row-drag-ghost-border);
775
+ border-radius: 4px;
776
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
777
+ }
778
+
779
+ .ge-table-row-drop-indicator {
780
+ position: absolute;
781
+ display: none;
782
+ z-index: 10000;
783
+ pointer-events: none;
784
+ background: var(--ge-table-row-drop-indicator-color);
785
+ }
786
+
787
+ /* tree: drop into the row (becomes its child) */
788
+ .ge-table-row-drop-indicator.ge-table-row-drop-indicator-inside {
789
+ box-sizing: border-box;
790
+ background: var(--ge-table-row-drop-inside-bg);
791
+ border: 2px solid var(--ge-table-row-drop-indicator-color);
792
+ }
793
+ /* Row grouping (RowGroupFactory / AreaModelRowGroups, since 1.1.94) */
794
+
795
+ /* every cell of a group row */
796
+ .ge-table-col-div.ge-table-row-group {
797
+ background-color: var(--ge-table-row-group-bg);
798
+ color: var(--ge-table-row-group-text);
799
+ }
800
+
801
+ /* the label in the group column: "Nord (3)" */
802
+ .ge-table-row-group-label {
803
+ font-weight: var(--ge-table-row-group-label-font-weight);
804
+ }
805
+
806
+ .ge-table-row-group-label .ge-table-label-div {
807
+ white-space: nowrap;
808
+ overflow: hidden;
809
+ text-overflow: ellipsis;
810
+ }
811
+
812
+ /* the aggregates of a group row */
813
+ .ge-table-row-group-aggregate {
814
+ text-align: end;
815
+ font-variant-numeric: tabular-nums;
816
+ font-weight: var(--ge-table-row-group-label-font-weight);
492
817
  }
493
818
  /* Tree table */
494
819
 
@@ -507,6 +832,15 @@ html[data-theme="dark"] {
507
832
  text-align: left;
508
833
  }
509
834
 
835
+ /* Row numbers (RowNumberColumnDef) in a tree: no tree look – right aligned like in a flat table (since 1.1.93) */
836
+ .ge-table-col-div.ge-table-row-number.ge-table-tree-cell {
837
+ text-align: right;
838
+ }
839
+ .ge-table-row-number.ge-table-tree-cell .ge-table-label-div {
840
+ display: block;
841
+ padding: 0;
842
+ }
843
+
510
844
  .ge-padding-property-checkbox {
511
845
  padding-left: 0;
512
846
  }
@@ -0,0 +1,7 @@
1
+ /* Calculated columns, „Show values as“, formulas (since 1.1.95) */
2
+
3
+ /* a cell with a formula error (#DIV/0!, #NAME? …): the message is the tooltip */
4
+ .ge-table-col-div.ge-table-cell-error {
5
+ color: var(--ge-table-cell-error-color);
6
+ font-variant-numeric: tabular-nums;
7
+ }
@@ -46,6 +46,27 @@
46
46
  padding-right: 10px;
47
47
  }
48
48
 
49
+ /* Total rows of AreaModelAggregateFooter (1.1.94) – before the align classes, so a column's footer class wins */
50
+ .ge-table-footer-aggregate {
51
+ text-align: end;
52
+ font-variant-numeric: tabular-nums;
53
+ }
54
+
55
+ .ge-table-footer-label {
56
+ font-weight: 600;
57
+ text-align: start;
58
+ }
59
+
60
+ /* the next footer cell is empty: the label may run into it instead of being cut off */
61
+ .ge-table-footer-label-overflow {
62
+ z-index: 1;
63
+ white-space: nowrap;
64
+ }
65
+
66
+ .ge-table-footer-label-overflow .ge-table-label-div {
67
+ overflow: visible;
68
+ }
69
+
49
70
  .ge-table-text-align-left {
50
71
  text-align: left;
51
72
  }
@@ -154,6 +175,19 @@
154
175
  }
155
176
 
156
177
 
178
+ /* Row numbers (RowNumberColumnDef, since 1.1.93): right aligned, digits of equal width. Before the color classes
179
+ in main.css, so that the selection colors (.ge-table-body-west-selected-range …) still win. */
180
+ .ge-table-row-number {
181
+ background-color: var(--ge-table-row-number-bg);
182
+ color: var(--ge-table-row-number-color);
183
+ }
184
+ .ge-table-row-number .ge-table-label,
185
+ .ge-table-row-number-header .ge-table-label {
186
+ padding-inline: 6px;
187
+ font-variant-numeric: tabular-nums;
188
+ }
189
+
190
+
157
191
  /* Overlays over the body: "Loading…" with a CSS spinner, "No rows to show", "No matching rows" (since 1.1.92).
158
192
  Position and size are set inline by the table (the visible body), display is switched inline (none / flex). */
159
193
  .ge-table-overlay {
@@ -84,6 +84,21 @@ html, html[data-theme="light"] {
84
84
  --ge-table-color-star-rating: #a86f00;
85
85
  --ge-table-color-progress-bar: #1e874b;
86
86
 
87
+ /* Row grouping: group rows (since 1.1.94) */
88
+ --ge-table-row-group-bg: rgba(0, 0, 0, 0.045);
89
+ --ge-table-row-group-text: inherit;
90
+ --ge-table-row-group-label-font-weight: 600;
91
+
92
+ /* Pivot tables: subtotals, totals, empty cells (since 1.1.94) */
93
+ --ge-table-pivot-subtotal-bg: rgba(0, 0, 0, 0.035);
94
+ --ge-table-pivot-subtotal-font-weight: 600;
95
+ --ge-table-pivot-total-bg: rgba(0, 0, 0, 0.07);
96
+ --ge-table-pivot-total-font-weight: 600;
97
+ --ge-table-pivot-empty-text: #6b7280;
98
+
99
+ /* Formulas: error values #DIV/0!, #NAME? … (since 1.1.95) */
100
+ --ge-table-cell-error-color: #b91c1c;
101
+
87
102
  /* Overlays "Loading…" / "No rows" (since 1.1.92) */
88
103
  --ge-table-overlay-bg: rgba(255, 255, 255, 0.7);
89
104
  --ge-table-overlay-content-bg: #fff;
@@ -91,6 +106,30 @@ html, html[data-theme="light"] {
91
106
  --ge-table-spinner-color: #1a73e8;
92
107
  --ge-table-spinner-track-color: rgba(0, 0, 0, 0.12);
93
108
  --ge-table-spinner-size: 28px;
109
+
110
+ /* Row numbers (since 1.1.93): like the header, muted digits (#555 on the header gray ≈ 6.9 : 1) */
111
+ --ge-table-row-number-bg: var(--ge-table-header-west-bg);
112
+ --ge-table-row-number-color: #555;
113
+
114
+ /* Row drag (since 1.1.95): handle ≥ 3 : 1 against white (WCAG 1.4.11), marker, ghost */
115
+ --ge-table-row-drag-handle-color: #6b7280;
116
+ --ge-table-row-drop-indicator-color: #1a73e8;
117
+ --ge-table-row-drop-inside-bg: rgba(26, 115, 232, 0.12);
118
+ --ge-table-row-drag-ghost-bg: #fff;
119
+ --ge-table-row-drag-ghost-text: #1f2937;
120
+ --ge-table-row-drag-ghost-border: #1a73e8;
121
+ --ge-table-row-dragging-opacity: 0.4;
122
+
123
+ /* Fill handle and batch edit (since 1.1.96): handle and preview like the selection, pending = yellow, invalid = red */
124
+ --ge-table-fill-handle-color: #0a6ebd;
125
+ --ge-table-fill-handle-border: #fff;
126
+ --ge-table-fill-preview-border: #0a6ebd;
127
+ --ge-table-cell-pending-bg: #fff3c4;
128
+ --ge-table-cell-pending-text: #3d2e00;
129
+ --ge-table-cell-pending-marker: #c27c00;
130
+ --ge-table-cell-invalid-bg: #fde2e1;
131
+ --ge-table-cell-invalid-text: #8a1c14;
132
+ --ge-table-cell-invalid-border: #d93025;
94
133
  }
95
134
 
96
135
 
@@ -166,6 +205,21 @@ html[data-theme="dark"] {
166
205
  --ge-table-color-star-rating: #fcb515;
167
206
  --ge-table-color-progress-bar: #36BB6C;
168
207
 
208
+ /* Row grouping: group rows (since 1.1.94) */
209
+ --ge-table-row-group-bg: rgba(255, 255, 255, 0.06);
210
+ --ge-table-row-group-text: inherit;
211
+ --ge-table-row-group-label-font-weight: 600;
212
+
213
+ /* Pivot tables: subtotals, totals, empty cells (since 1.1.94) */
214
+ --ge-table-pivot-subtotal-bg: rgba(255, 255, 255, 0.05);
215
+ --ge-table-pivot-subtotal-font-weight: 600;
216
+ --ge-table-pivot-total-bg: rgba(255, 255, 255, 0.1);
217
+ --ge-table-pivot-total-font-weight: 600;
218
+ --ge-table-pivot-empty-text: #9ca3af;
219
+
220
+ /* Formulas: error values #DIV/0!, #NAME? … (since 1.1.95) */
221
+ --ge-table-cell-error-color: #f87171;
222
+
169
223
  /* Overlays "Loading…" / "No rows" (since 1.1.92) */
170
224
  --ge-table-overlay-bg: rgba(17, 24, 39, 0.7); /* --ge-table-bg of the dark theme */
171
225
  --ge-table-overlay-content-bg: #1f2937;
@@ -173,4 +227,28 @@ html[data-theme="dark"] {
173
227
  --ge-table-spinner-color: #8ab4f8;
174
228
  --ge-table-spinner-track-color: rgba(255, 255, 255, 0.18);
175
229
  --ge-table-spinner-size: 28px;
230
+
231
+ /* Row numbers (since 1.1.93) */
232
+ --ge-table-row-number-bg: var(--ge-table-header-west-bg);
233
+ --ge-table-row-number-color: #aaa;
234
+
235
+ /* Row drag (since 1.1.95) */
236
+ --ge-table-row-drag-handle-color: #9ca3af;
237
+ --ge-table-row-drop-indicator-color: #8ab4f8;
238
+ --ge-table-row-drop-inside-bg: rgba(138, 180, 248, 0.16);
239
+ --ge-table-row-drag-ghost-bg: #1f2937;
240
+ --ge-table-row-drag-ghost-text: #f3f4f6;
241
+ --ge-table-row-drag-ghost-border: #8ab4f8;
242
+ --ge-table-row-dragging-opacity: 0.4;
243
+
244
+ /* Fill handle and batch edit (since 1.1.96) */
245
+ --ge-table-fill-handle-color: #8ab4f8;
246
+ --ge-table-fill-handle-border: #1e1e1e;
247
+ --ge-table-fill-preview-border: #8ab4f8;
248
+ --ge-table-cell-pending-bg: #4a3b0b;
249
+ --ge-table-cell-pending-text: #fde68a;
250
+ --ge-table-cell-pending-marker: #f5b82e;
251
+ --ge-table-cell-invalid-bg: #5c1d1a;
252
+ --ge-table-cell-invalid-text: #fecaca;
253
+ --ge-table-cell-invalid-border: #f28b82;
176
254
  }
@@ -0,0 +1,58 @@
1
+ /* Fill handle and batch edit (since 1.1.96) – colors in table-color-vars.css (--ge-table-fill-*, --ge-table-cell-*) */
2
+
3
+ /* the square at the bottom right corner of the selected range; its center sits on the corner */
4
+ .ge-table-fill-handle {
5
+ position: absolute;
6
+ z-index: 9000; /* above the cells, below the overlay (10000) */
7
+ width: 7px;
8
+ height: 7px;
9
+ margin: -4px 0 0 -4px;
10
+ box-sizing: border-box;
11
+ background: var(--ge-table-fill-handle-color);
12
+ border: 1px solid var(--ge-table-fill-handle-border);
13
+ cursor: crosshair;
14
+ touch-action: none; /* touch drags the handle instead of scrolling */
15
+ }
16
+
17
+ /* a bigger target for touch and pen (the visible square stays small) */
18
+ .ge-table-fill-handle::after {
19
+ content: "";
20
+ position: absolute;
21
+ inset: -8px;
22
+ }
23
+
24
+ /* the cells a fill will cover */
25
+ .ge-table-fill-preview {
26
+ position: absolute;
27
+ z-index: 8999;
28
+ box-sizing: border-box;
29
+ border: 2px dashed var(--ge-table-fill-preview-border);
30
+ pointer-events: none;
31
+ }
32
+
33
+ .ge-table-fill-active,
34
+ .ge-table-fill-active * {
35
+ cursor: crosshair !important;
36
+ user-select: none;
37
+ }
38
+
39
+ /* batch edit: a value that is not saved yet – a colored cell and a small corner mark (not color only, WCAG 1.4.1) */
40
+ .ge-table-col-div.ge-table-cell-pending {
41
+ background-image: linear-gradient(225deg, var(--ge-table-cell-pending-marker) 6px, transparent 6px);
42
+ }
43
+
44
+ /* the color only while the cell is not selected – a selected cell keeps the selection color (and the corner mark) */
45
+ .ge-table-col-div.ge-table-cell-pending:not([class*="-selected-range"]) {
46
+ background-color: var(--ge-table-cell-pending-bg);
47
+ color: var(--ge-table-cell-pending-text);
48
+ }
49
+
50
+ /* an invalid value (ColumnDef.validate): the message is the tooltip */
51
+ .ge-table-col-div.ge-table-cell-invalid:not([class*="-selected-range"]) {
52
+ background-color: var(--ge-table-cell-invalid-bg);
53
+ color: var(--ge-table-cell-invalid-text);
54
+ }
55
+
56
+ .ge-table-col-div.ge-table-cell-invalid {
57
+ box-shadow: inset 0 0 0 2px var(--ge-table-cell-invalid-border);
58
+ }
@@ -0,0 +1,42 @@
1
+ /* Pivot tables (PivotFactory / AreaModelPivot, since 1.1.94) */
2
+
3
+ /* every value cell: numbers on the end side, same digit widths */
4
+ .ge-table-pivot-value {
5
+ text-align: end;
6
+ font-variant-numeric: tabular-nums;
7
+ }
8
+
9
+ /* the label in the group column ("Nord") */
10
+ .ge-table-pivot-label .ge-table-label-div {
11
+ white-space: nowrap;
12
+ overflow: hidden;
13
+ text-overflow: ellipsis;
14
+ }
15
+
16
+ /* subtotals: group rows and the total columns of column groups */
17
+ .ge-table-col-div.ge-table-pivot-subtotal {
18
+ background-color: var(--ge-table-pivot-subtotal-bg);
19
+ font-weight: var(--ge-table-pivot-subtotal-font-weight);
20
+ }
21
+
22
+ /* totals: the total column(s) and the total row */
23
+ .ge-table-col-div.ge-table-pivot-total {
24
+ background-color: var(--ge-table-pivot-total-bg);
25
+ font-weight: var(--ge-table-pivot-total-font-weight);
26
+ }
27
+
28
+ /* a combination without data (emptyText, e.g. "–") */
29
+ .ge-table-pivot-empty {
30
+ color: var(--ge-table-pivot-empty-text);
31
+ }
32
+
33
+ /* header: a column group ("2026", "Jan") starts at the left of its span, a column label ("Q1", "Revenue") sits above
34
+ its numbers (value columns only – the group column keeps its alignment) */
35
+ .ge-table-pivot-header-group {
36
+ text-align: start;
37
+ padding-inline-start: 6px;
38
+ }
39
+
40
+ .ge-table-pivot-header.ge-table-pivot-header-column {
41
+ text-align: end;
42
+ }