@guiexpert/table 1.1.94 → 1.1.97

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 (85) hide show
  1. package/README.md +16 -0
  2. package/css/main.css +299 -0
  3. package/css/table-calc.css +7 -0
  4. package/css/table-color-vars.css +58 -0
  5. package/css/table-fill-batch.css +58 -0
  6. package/css/table-master-detail.css +95 -0
  7. package/css/table-row-drag.css +81 -0
  8. package/index.cjs +37 -35
  9. package/index.d.ts +34 -0
  10. package/index.js +9749 -5000
  11. package/lib/table/action/action-id.type.d.ts +1 -1
  12. package/lib/table/aria/aria-ids.d.ts +7 -0
  13. package/lib/table/aria/aria-texts.d.ts +13 -0
  14. package/lib/table/aria/aria-texts.if.d.ts +101 -0
  15. package/lib/table/batch-edit/batch-edit-options.d.ts +21 -0
  16. package/lib/table/batch-edit/batch-edit-options.if.d.ts +20 -0
  17. package/lib/table/batch-edit/batch-edit-service.d.ts +104 -0
  18. package/lib/table/batch-edit/cell-change.if.d.ts +39 -0
  19. package/lib/table/batch-edit/cell-value-change.if.d.ts +18 -0
  20. package/lib/table/batch-edit/pending-cell-changes.d.ts +104 -0
  21. package/lib/table/calc/column-values.d.ts +55 -0
  22. package/lib/table/calc/show-values-as-internals.d.ts +4 -0
  23. package/lib/table/calc/show-values-as.d.ts +87 -0
  24. package/lib/table/calc/show-values-as.type.d.ts +55 -0
  25. package/lib/table/calc/value-getter-context.if.d.ts +35 -0
  26. package/lib/table/calc/value-getter.type.d.ts +36 -0
  27. package/lib/table/data/common/event/ge-batch-edit-event.d.ts +46 -0
  28. package/lib/table/data/common/event/ge-detail-event.d.ts +40 -0
  29. package/lib/table/data/common/event/ge-model-change-event.d.ts +27 -1
  30. package/lib/table/data/common/event/ge-row-drag-event.d.ts +89 -0
  31. package/lib/table/data/options/auto-restore-options.d.ts +2 -0
  32. package/lib/table/data/options/auto-restore-options.if.d.ts +6 -0
  33. package/lib/table/data/options/table-options.d.ts +8 -0
  34. package/lib/table/data/options/table-options.if.d.ts +62 -0
  35. package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +66 -0
  36. package/lib/table/data/tablemodel/areamodel/area-model-aggregate-footer.d.ts +5 -0
  37. package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +24 -0
  38. package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +70 -0
  39. package/lib/table/data/tablemodel/areamodel/area-model-pivot.d.ts +31 -0
  40. package/lib/table/data/tablemodel/areamodel/area-model-row-groups.d.ts +23 -1
  41. package/lib/table/data/tablemodel/areamodel/area-model-tree.d.ts +83 -0
  42. package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +55 -0
  43. package/lib/table/data/tablemodel/column/column-def.d.ts +31 -1
  44. package/lib/table/data/tablemodel/column/column-def.if.d.ts +86 -0
  45. package/lib/table/ele-scope.d.ts +14 -0
  46. package/lib/table/event-adapter.d.ts +10 -0
  47. package/lib/table/event-listener.if.d.ts +39 -0
  48. package/lib/table/factory/table-factory.d.ts +11 -0
  49. package/lib/table/fill/compute-fill-changes.d.ts +67 -0
  50. package/lib/table/fill/fill-direction.type.d.ts +7 -0
  51. package/lib/table/fill/fill-handle-options.d.ts +29 -0
  52. package/lib/table/fill/fill-handle-options.if.d.ts +35 -0
  53. package/lib/table/fill/fill-handle-service.d.ts +55 -0
  54. package/lib/table/fill/fill-series.d.ts +60 -0
  55. package/lib/table/fill/fill-value-context.if.d.ts +36 -0
  56. package/lib/table/formula/compile-formula.d.ts +86 -0
  57. package/lib/table/formula/evaluator.d.ts +19 -0
  58. package/lib/table/formula/formula-ast.if.d.ts +42 -0
  59. package/lib/table/formula/formula-error.d.ts +59 -0
  60. package/lib/table/formula/formula-options.if.d.ts +41 -0
  61. package/lib/table/formula/formula-values.d.ts +13 -0
  62. package/lib/table/formula/functions.d.ts +18 -0
  63. package/lib/table/formula/parser.d.ts +10 -0
  64. package/lib/table/formula/tokenizer.d.ts +22 -0
  65. package/lib/table/master-detail/detail-renderer.if.d.ts +99 -0
  66. package/lib/table/master-detail/master-detail-options.d.ts +30 -0
  67. package/lib/table/master-detail/master-detail-options.if.d.ts +60 -0
  68. package/lib/table/master-detail/master-detail-service.d.ts +223 -0
  69. package/lib/table/pivot/pivot-value.type.d.ts +13 -0
  70. package/lib/table/render-scope.d.ts +154 -0
  71. package/lib/table/renderer/edit/input-cell-renderer.d.ts +1 -1
  72. package/lib/table/renderer/edit/select-cell-renderer.d.ts +1 -1
  73. package/lib/table/row-drag/move-rows.d.ts +157 -0
  74. package/lib/table/row-drag/row-drag-options.d.ts +28 -0
  75. package/lib/table/row-drag/row-drag-options.if.d.ts +36 -0
  76. package/lib/table/row-drag/row-drag-service.d.ts +130 -0
  77. package/lib/table/row-drag/row-drop-target.if.d.ts +29 -0
  78. package/lib/table/row-layout/row-layout.d.ts +120 -0
  79. package/lib/table/service/excel-service.d.ts +6 -0
  80. package/lib/table/service/excel-service.if.d.ts +35 -0
  81. package/lib/table/state/table-state.if.d.ts +4 -1
  82. package/lib/table/state/table-state.service.d.ts +4 -0
  83. package/lib/table/table-api.d.ts +378 -2
  84. package/lib/table/table-scope.d.ts +185 -0
  85. package/package.json +1 -1
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @category Keyboard
7
7
  */
8
- export declare const actionIds: readonly ["COPY_2_CLIPBOARD", "START_EDITING", "TOGGLE_SELECTION", "SELECT_ALL", "DESELECT_ALL", "NAVIGATE_LEFT", "NAVIGATE_RIGHT", "NAVIGATE_UP", "NAVIGATE_DOWN", "NAVIGATE_ROW_START", "NAVIGATE_ROW_END", "NAVIGATE_FIRST_CELL", "NAVIGATE_LAST_CELL", "NAVIGATE_PAGE_UP", "NAVIGATE_PAGE_DOWN", "ACTIVATE_CELL"];
8
+ export declare const actionIds: readonly ["COPY_2_CLIPBOARD", "START_EDITING", "TOGGLE_SELECTION", "SELECT_ALL", "DESELECT_ALL", "NAVIGATE_LEFT", "NAVIGATE_RIGHT", "NAVIGATE_UP", "NAVIGATE_DOWN", "NAVIGATE_ROW_START", "NAVIGATE_ROW_END", "NAVIGATE_FIRST_CELL", "NAVIGATE_LAST_CELL", "NAVIGATE_PAGE_UP", "NAVIGATE_PAGE_DOWN", "ACTIVATE_CELL", "MOVE_ROW_UP", "MOVE_ROW_DOWN", "FILL_DOWN", "FILL_RIGHT"];
9
9
  /**
10
10
  * Represents an action ID.
11
11
  *
@@ -47,6 +47,13 @@ export declare class AriaIds {
47
47
  * @returns {string} e.g. `"ge-t1-rg-body-center"`
48
48
  */
49
49
  rowGroup(area: AreaIdent, side: SideIdent): string;
50
+ /**
51
+ * The ID of the row group of the detail rows (master/detail), referenced by `aria-owns` of the host.
52
+ *
53
+ * @returns {string} e.g. `"ge-t1-rg-detail"`
54
+ * @since 1.1.97
55
+ */
56
+ detailRowGroup(): string;
50
57
  /**
51
58
  * The ID of the live region (the element that speaks announcements, see {@link LiveAnnouncer}).
52
59
  *
@@ -31,4 +31,17 @@ export declare class AriaTexts implements AriaTextsIf {
31
31
  selectAllRows(): string;
32
32
  expandGroup(groupLabel: string): string;
33
33
  collapseGroup(groupLabel: string): string;
34
+ rowDragStarted(rowCount: number): string;
35
+ rowMoved(position: number, rowCount: number): string;
36
+ rowMoveNotPossible(): string;
37
+ rowDragCancelled(): string;
38
+ cellsFilled(cellCount: number): string;
39
+ detailExpanded(): string;
40
+ detailCollapsed(): string;
41
+ fillTooLarge(maxCells: number): string;
42
+ pendingChanges(pendingCount: number): string;
43
+ changesCommitted(cellCount: number): string;
44
+ changesDiscarded(): string;
45
+ commitBlocked(invalidCount: number): string;
46
+ invalidValue(message: string): string;
34
47
  }
@@ -85,4 +85,105 @@ export interface AriaTextsIf {
85
85
  * @returns {string} default: `"Collapse group Q1"`
86
86
  */
87
87
  collapseGroup(groupLabel: string): string;
88
+ /**
89
+ * Announced when a row drag starts (optional – {@link AriaTexts} has a default).
90
+ *
91
+ * @param {number} rowCount - number of dragged rows
92
+ * @returns {string} default: `"Dragging 1 row. Press Escape to cancel."`
93
+ * @since 1.1.95
94
+ */
95
+ rowDragStarted?(rowCount: number): string;
96
+ /**
97
+ * Announced after rows were moved by drag and drop or Ctrl+Alt+↑/↓ (optional – {@link AriaTexts} has a default).
98
+ *
99
+ * @param {number} position - 1-based position of the first moved row
100
+ * @param {number} rowCount - number of displayed rows
101
+ * @returns {string} default: `"Row moved to position 7 of 20"`
102
+ * @since 1.1.95
103
+ */
104
+ rowMoved?(position: number, rowCount: number): string;
105
+ /**
106
+ * Announced when rows cannot be moved: the table is sorted or filtered (managed row drag), or the row cannot move
107
+ * further (optional – {@link AriaTexts} has a default).
108
+ *
109
+ * @returns {string} default: `"Rows cannot be moved while the table is sorted or filtered"`
110
+ * @since 1.1.95
111
+ */
112
+ rowMoveNotPossible?(): string;
113
+ /**
114
+ * Announced when a row drag was cancelled (Escape) – optional, {@link AriaTexts} has a default.
115
+ *
116
+ * @returns {string} default: `"Drag cancelled"`
117
+ * @since 1.1.95
118
+ */
119
+ rowDragCancelled?(): string;
120
+ /**
121
+ * Announced after a fill (fill handle, Ctrl/⌘+D, Ctrl/⌘+R) – optional, {@link AriaTexts} has a default.
122
+ *
123
+ * @param {number} cellCount - the number of filled cells
124
+ * @returns {string} default: `"3 cells filled"`
125
+ * @since 1.1.96
126
+ */
127
+ cellsFilled?(cellCount: number): string;
128
+ /**
129
+ * Announced when a fill is refused because it covers too many cells ({@link FillHandleOptionsIf.maxCells}).
130
+ *
131
+ * @param {number} maxCells - the limit
132
+ * @returns {string} default: `"Too many cells to fill (at most 100000)"`
133
+ * @since 1.1.96
134
+ */
135
+ fillTooLarge?(maxCells: number): string;
136
+ /**
137
+ * Announced after a value was marked in a batch edit (or set back).
138
+ *
139
+ * @param {number} pendingCount - the number of pending cells
140
+ * @returns {string} default: `"3 changes not saved"`, `"No unsaved changes"`
141
+ * @since 1.1.96
142
+ */
143
+ pendingChanges?(pendingCount: number): string;
144
+ /**
145
+ * Announced after {@link TableApi.commitBatchEdit}.
146
+ *
147
+ * @param {number} cellCount - the number of written cells
148
+ * @returns {string} default: `"3 changes saved"`
149
+ * @since 1.1.96
150
+ */
151
+ changesCommitted?(cellCount: number): string;
152
+ /**
153
+ * Announced after {@link TableApi.cancelBatchEdit}.
154
+ *
155
+ * @returns {string} default: `"Changes discarded"`
156
+ * @since 1.1.96
157
+ */
158
+ changesDiscarded?(): string;
159
+ /**
160
+ * Announced when invalid values block {@link TableApi.commitBatchEdit}.
161
+ *
162
+ * @param {number} invalidCount - the number of invalid cells
163
+ * @returns {string} default: `"2 invalid values – nothing saved"`
164
+ * @since 1.1.96
165
+ */
166
+ commitBlocked?(invalidCount: number): string;
167
+ /**
168
+ * Announced when an edited value is invalid ({@link ColumnDefIf.validate}) and not written (without batch edit).
169
+ *
170
+ * @param {string} message - the message of the validator
171
+ * @returns {string} default: `"Invalid value: <message>"`
172
+ * @since 1.1.96
173
+ */
174
+ invalidValue?(message: string): string;
175
+ /**
176
+ * Announced after a detail row was expanded (master/detail).
177
+ *
178
+ * @returns {string} default: `"Details expanded"`
179
+ * @since 1.1.97
180
+ */
181
+ detailExpanded?(): string;
182
+ /**
183
+ * Announced after a detail row was collapsed (master/detail).
184
+ *
185
+ * @returns {string} default: `"Details collapsed"`
186
+ * @since 1.1.97
187
+ */
188
+ detailCollapsed?(): string;
88
189
  }
@@ -0,0 +1,21 @@
1
+ import { BatchEditOptionsIf } from './batch-edit-options.if.js';
2
+
3
+ /**
4
+ * The defaults of {@link BatchEditOptionsIf}.
5
+ *
6
+ * @example
7
+ * BatchEditOptions.create(true).blockCommitOnInvalid; // true
8
+ *
9
+ * @category Fill handle & batch edit
10
+ * @since 1.1.96
11
+ */
12
+ export declare class BatchEditOptions implements BatchEditOptionsIf {
13
+ blockCommitOnInvalid: boolean;
14
+ /**
15
+ * The options of {@link TableOptionsIf.batchEdit} (`true`, `false` or an object) with defaults.
16
+ *
17
+ * @param {boolean | Partial<BatchEditOptionsIf>} [option] - `tableOptions.batchEdit`
18
+ * @returns {BatchEditOptionsIf} complete options
19
+ */
20
+ static create(option?: boolean | Partial<BatchEditOptionsIf>): BatchEditOptionsIf;
21
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Options of the batch edit ({@link TableOptionsIf.batchEdit}): changes are collected (marked, not written) and
3
+ * written with {@link TableApi.commitBatchEdit} or discarded with {@link TableApi.cancelBatchEdit}.
4
+ *
5
+ * @example
6
+ * const tableOptions: TableOptionsIf = {
7
+ * ...new TableOptions(),
8
+ * batchEdit: { blockCommitOnInvalid: false }, // always collect; invalid values don't block saving
9
+ * };
10
+ *
11
+ * @category Fill handle & batch edit
12
+ * @since 1.1.96
13
+ */
14
+ export interface BatchEditOptionsIf {
15
+ /**
16
+ * `true` (default): {@link TableApi.commitBatchEdit} writes nothing while a pending value is invalid
17
+ * ({@link ColumnDefIf.validate}) and returns `false`.
18
+ */
19
+ blockCommitOnInvalid: boolean;
20
+ }
@@ -0,0 +1,104 @@
1
+ import { TableScope } from '../table-scope.js';
2
+ import { CellChangeIf } from './cell-change.if.js';
3
+ import { BatchEditOptionsIf } from './batch-edit-options.if.js';
4
+ import { PendingCellIf } from './pending-cell-changes.js';
5
+
6
+ /** A value to mark as pending – prepared by {@link TableScope.applyCellChanges}. */
7
+ export interface PendingInputIf {
8
+ rowIndex: number;
9
+ columnIndex: number;
10
+ /** after the editInputPipe */
11
+ value: unknown;
12
+ /** as entered */
13
+ rawValue: unknown;
14
+ error?: string;
15
+ }
16
+ /**
17
+ * Batch edit of one table (`tableScope.batchEditService`): collects changes instead of writing them, shows them
18
+ * (`ge-table-cell-pending`) and writes them on commit. Use {@link TableApi.startBatchEdit},
19
+ * {@link TableApi.commitBatchEdit}, {@link TableApi.cancelBatchEdit} and {@link TableApi.getPendingChanges}.
20
+ *
21
+ * The pending values belong to the row **objects** – sorting and filtering keep them on their rows. They are shown, but
22
+ * sorting, filtering, totals, copy and the Excel export use the written data (like ag-Grid).
23
+ *
24
+ * @category Internals
25
+ * @since 1.1.96
26
+ */
27
+ export declare class BatchEditService {
28
+ private readonly tableScope;
29
+ private readonly pending;
30
+ private started;
31
+ constructor(tableScope: TableScope);
32
+ /** The options of this table ({@link TableOptionsIf.batchEdit} + defaults). */
33
+ get options(): BatchEditOptionsIf;
34
+ /** `tableOptions.batchEdit` is set: changes are always collected. */
35
+ isPermanent(): boolean;
36
+ /** True while changes are collected (started, or {@link isPermanent}). */
37
+ isActive(): boolean;
38
+ /** True if values are pending. */
39
+ hasPending(): boolean;
40
+ /**
41
+ * Starts collecting changes (until commit or cancel).
42
+ *
43
+ * @returns {boolean} false if a batch edit is already running
44
+ */
45
+ start(): boolean;
46
+ /** The key of a shown row: its object (tree: the data), the index for models without objects. */
47
+ rowKeyOf(rowIndex: number): unknown;
48
+ /** The key of a column: its property, `#<index>` without one. */
49
+ propertyOf(columnIndex: number): string;
50
+ /**
51
+ * The pending value of a shown body cell – asked for every rendered cell (one map lookup, nothing while empty).
52
+ *
53
+ * @param {number} rowIndex - display index
54
+ * @param {number} columnIndex - model index
55
+ * @returns {PendingCellIf | undefined} the entry
56
+ */
57
+ getPendingAt(rowIndex: number, columnIndex: number): PendingCellIf | undefined;
58
+ /**
59
+ * The value a body cell shows: the pending value, otherwise the model value.
60
+ *
61
+ * @param {number} rowIndex - display index
62
+ * @param {number} columnIndex - model index
63
+ * @returns {unknown} the shown value
64
+ */
65
+ getShownValue(rowIndex: number, columnIndex: number): unknown;
66
+ /**
67
+ * Marks values as pending (B1, B6, B8) and reports the step (`onBatchEditChanged`, announcement). The caller repaints.
68
+ *
69
+ * @param {PendingInputIf[]} inputs - cells with piped and raw value
70
+ * @returns {CellChangeIf[]} the cells whose pending state changed
71
+ */
72
+ addPending(inputs: PendingInputIf[]): CellChangeIf[];
73
+ /**
74
+ * All pending changes with the current display indices (one scan of the shown rows).
75
+ *
76
+ * @returns {CellChangeIf[]} the pending cells
77
+ */
78
+ getPendingChanges(): CellChangeIf[];
79
+ /**
80
+ * Writes the pending values (B3): shown rows through `setValue` (the pipe runs once, row groupings regroup), rows a
81
+ * filter hides directly into their objects. One `onModelChanged` with all cells, then `onBatchEditChanged` "commit".
82
+ *
83
+ * @returns {boolean} false if invalid values block the commit ({@link BatchEditOptionsIf.blockCommitOnInvalid})
84
+ */
85
+ commit(): boolean;
86
+ /** Discards the pending values (B4) and ends a started batch edit. */
87
+ cancel(): void;
88
+ /**
89
+ * Forgets pending values of rows that are no longer in the model (`setRows`, a reloaded tree): they would never be
90
+ * shown, block a commit with an invalid value and be written into stale objects. Only for models whose rows are known
91
+ * (object arrays, trees, row groupings); others keep their entries.
92
+ *
93
+ * @returns {number} the number of removed entries
94
+ */
95
+ pruneOrphans(): number;
96
+ /** All row keys of the body (also filtered and collapsed rows) – `undefined` if the model can't tell. */
97
+ private collectRowKeys;
98
+ private toChange;
99
+ private findColumnIndex;
100
+ /** Row key → display index, for the rows with pending values only. */
101
+ private createRowIndexMap;
102
+ private fire;
103
+ private texts;
104
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * What started a change of cells: `"edit"` (cell editor), `"fill"` (fill handle, Ctrl/⌘+D, Ctrl/⌘+R),
3
+ * `"commit"` ({@link TableApi.commitBatchEdit}) or `"api"` ({@link TableApi.applyCellChanges}).
4
+ *
5
+ * @category Fill handle & batch edit
6
+ * @since 1.1.96
7
+ */
8
+ export type CellChangeSource = "edit" | "fill" | "commit" | "api";
9
+ /**
10
+ * One changed cell: row, column, old and new value – the unit of a change set ({@link GeModelChangeEvent.changes},
11
+ * {@link TableApi.getPendingChanges}). With old **and** new value it is enough for undo and redo.
12
+ *
13
+ * @example
14
+ * const listener = new EventAdapter();
15
+ * listener.onModelChanged = (evt: GeModelChangeEvent) => {
16
+ * for (const change of evt.changes ?? []) {
17
+ * console.log(change.property, change.oldValue, "→", change.newValue, change.row);
18
+ * }
19
+ * };
20
+ *
21
+ * @category Fill handle & batch edit
22
+ * @since 1.1.96
23
+ */
24
+ export interface CellChangeIf<T = any> {
25
+ /** The row object (tree: the data of the `TreeRow`); `undefined` for own area models without row objects. */
26
+ row: T;
27
+ /** Display index of the row when the change was reported, `-1` if a filter hides the row. */
28
+ rowIndex: number;
29
+ /** Model index of the column when the change was reported, `-1` if the column no longer exists. */
30
+ columnIndex: number;
31
+ /** The property of the column (`"#3"` for a column without property). */
32
+ property: string;
33
+ /** The value before the change (batch edit: before the first change of the cell). */
34
+ oldValue: unknown;
35
+ /** The new value (after the column's `editInputPipe`). */
36
+ newValue: unknown;
37
+ /** Batch edit: the message of {@link ColumnDefIf.validate} if the new value is invalid. */
38
+ error?: string;
39
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * A value to write into a body cell – the input of {@link TableApi.applyCellChanges} (and of the fill handle).
3
+ *
4
+ * @example
5
+ * const change: CellValueChangeIf = { rowIndex: 3, column: "price", value: 9.9 };
6
+ * tableApi.applyCellChanges([change]);
7
+ *
8
+ * @category Fill handle & batch edit
9
+ * @since 1.1.96
10
+ */
11
+ export interface CellValueChangeIf {
12
+ /** Display index of the row in the body. */
13
+ rowIndex: number;
14
+ /** Model index of the column, or its property. */
15
+ column: number | string;
16
+ /** The new value – like typed into the editor: it runs through the column's `editInputPipe`. */
17
+ value: unknown;
18
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * One pending (not yet written) cell value of a batch edit – an entry of {@link PendingCellChanges}.
3
+ *
4
+ * @category Internals
5
+ * @since 1.1.96
6
+ */
7
+ export interface PendingCellIf {
8
+ /** The key of the row: the row object (tree: the data of the `TreeRow`), or the row index for models without objects. */
9
+ rowKey: unknown;
10
+ /** The property of the column (`"#3"` for a column without property). */
11
+ property: string;
12
+ /** The value before the first change. */
13
+ oldValue: unknown;
14
+ /** The value shown (after the column's `editInputPipe`). */
15
+ newValue: unknown;
16
+ /** The value as entered (written with `setValue` on commit – the pipe runs there once). */
17
+ rawValue: unknown;
18
+ /** The message of {@link ColumnDefIf.validate}, if the value is invalid. */
19
+ error?: string;
20
+ }
21
+ /**
22
+ * What {@link PendingCellChanges.set} did: a new entry, a changed entry, an entry removed because the value is the
23
+ * old one again (B8), or nothing (the value equals the old one and there was no entry).
24
+ *
25
+ * @category Internals
26
+ * @since 1.1.96
27
+ */
28
+ export type PendingChangeResult = "added" | "changed" | "removed" | "unchanged";
29
+ /**
30
+ * True if two cell values are the same for a batch edit: `Object.is`, dates by time, a number and the text of the same
31
+ * number (an editor without `editInputPipe` returns texts), and `null` / `undefined` / `""` as "empty".
32
+ *
33
+ * @param {unknown} a - one value
34
+ * @param {unknown} b - another value
35
+ * @returns {boolean} whether the cell would not change
36
+ *
37
+ * @example
38
+ * isSameCellValue(5, "5"); // true
39
+ * isSameCellValue(new Date(2026, 0, 1), new Date(2026, 0, 1)); // true
40
+ * isSameCellValue(undefined, ""); // true
41
+ *
42
+ * @category Fill handle & batch edit
43
+ * @since 1.1.96
44
+ */
45
+ export declare function isSameCellValue(a: unknown, b: unknown): boolean;
46
+ /**
47
+ * The pending values of a batch edit: per row (the row **object**, not its index – sorting and filtering don't
48
+ * change the assignment) and property one entry with old and new value. DOM-free; the table keeps one in its
49
+ * batch edit service.
50
+ *
51
+ * @example
52
+ * const pending = new PendingCellChanges();
53
+ * const row = { price: 10 };
54
+ * pending.set(row, "price", 10, 12, "12"); // "added"
55
+ * pending.set(row, "price", 12, 10, "10"); // "removed" – the old value again
56
+ *
57
+ * @category Internals
58
+ * @since 1.1.96
59
+ */
60
+ export declare class PendingCellChanges {
61
+ private readonly rows;
62
+ private count;
63
+ /**
64
+ * Sets the pending value of a cell. The old value of an existing entry stays (the value before the first change);
65
+ * a value equal to it removes the entry (B8).
66
+ *
67
+ * @param {unknown} rowKey - the row object (or the row index for models without objects)
68
+ * @param {string} property - the property of the column
69
+ * @param {unknown} oldValue - the current value in the model (used for a new entry)
70
+ * @param {unknown} newValue - the new value (after the pipe)
71
+ * @param {unknown} rawValue - the value as entered
72
+ * @param {string} [error] - validation message
73
+ * @returns {PendingChangeResult} what happened
74
+ */
75
+ set(rowKey: unknown, property: string, oldValue: unknown, newValue: unknown, rawValue: unknown, error?: string): PendingChangeResult;
76
+ /**
77
+ * The pending entry of a cell.
78
+ *
79
+ * @param {unknown} rowKey - the row object (or index)
80
+ * @param {string} property - the property of the column
81
+ * @returns {PendingCellIf | undefined} the entry, `undefined` if the cell is unchanged
82
+ */
83
+ get(rowKey: unknown, property: string): PendingCellIf | undefined;
84
+ /**
85
+ * Removes the entry of a cell.
86
+ *
87
+ * @param {unknown} rowKey - the row object (or index)
88
+ * @param {string} property - the property of the column
89
+ * @returns {boolean} true if there was an entry
90
+ */
91
+ remove(rowKey: unknown, property: string): boolean;
92
+ /** @returns {boolean} true if the row has pending values */
93
+ hasRow(rowKey: unknown): boolean;
94
+ /** @returns {number} the number of pending cells */
95
+ size(): number;
96
+ /** @returns {boolean} true if nothing is pending */
97
+ isEmpty(): boolean;
98
+ /** @returns {number} the number of pending cells with a validation message */
99
+ invalidCount(): number;
100
+ /** @returns {PendingCellIf[]} all entries, in the order they were first changed */
101
+ entries(): PendingCellIf[];
102
+ /** Forgets all entries. */
103
+ clear(): void;
104
+ }
@@ -0,0 +1,55 @@
1
+ import { ColumnDefIf } from '../data/tablemodel/column/column-def.if.js';
2
+ import { ValueGetter } from './value-getter.type.js';
3
+ import { ValueGetterContextIf } from './value-getter-context.if.js';
4
+ import { AggregatorRef } from '../aggregation/aggregator-name.type.js';
5
+ import { ShowValuesAsIf } from './show-values-as.type.js';
6
+
7
+ /** What an area model provides to its {@link ColumnValues}. */
8
+ export interface ColumnValuesOwner {
9
+ /** The column definitions (read lazily – they may be replaced, e.g. by a pivot). */
10
+ getColumnDefsForValues(): ColumnDefIf[];
11
+ /** The value of a property path (the model's own semantics – unchanged behaviour for normal columns). */
12
+ readPath(row: any, property: string): unknown;
13
+ /** The rows of column aggregates (filtered, data objects) and a cheap signal that changes with them. */
14
+ getAggregationSource(): {
15
+ signal: unknown;
16
+ length: number;
17
+ rows: () => ArrayLike<unknown>;
18
+ };
19
+ }
20
+ /**
21
+ * Resolves `valueGetter`s by property, detects cycles (`#CIRC!`), caches column aggregates.
22
+ * Without calculated columns `get()` is one empty-map lookup plus the model's own path read.
23
+ */
24
+ export declare class ColumnValues {
25
+ private readonly owner;
26
+ private getters?;
27
+ private showValuesAs?;
28
+ private properties?;
29
+ private defsLength;
30
+ /** property → rows whose value is being computed (a getter may read the same column of another row) */
31
+ private readonly computing;
32
+ private readonly contexts;
33
+ private aggregates;
34
+ private aggSignal;
35
+ private aggLength;
36
+ constructor(owner: ColumnValuesOwner);
37
+ /** Drops the getter lookup and the cached aggregates (`invalidateDerivedValues`). */
38
+ invalidate(): void;
39
+ /** The getter of a calculated column. */
40
+ getter(property: string | undefined): ValueGetter | undefined;
41
+ hasGetters(): boolean;
42
+ isCalculated(property: string): boolean;
43
+ hasColumn(property: string): boolean;
44
+ /** The „Show values as“ options of a column. */
45
+ getShowValuesAs(property: string | undefined): ShowValuesAsIf | undefined;
46
+ hasShowValuesAs(): boolean;
47
+ /** The value of a column for a row: its getter (cycle-safe, exceptions → `#VALUE!`) or the path. */
48
+ get(row: any, property: string): unknown;
49
+ /** An aggregate of a column over the filtered rows – cached. */
50
+ aggregate(property: string, aggregator: AggregatorRef): unknown;
51
+ /** The context passed to a getter. */
52
+ context(property: string): ValueGetterContextIf;
53
+ private call;
54
+ private lookup;
55
+ }
@@ -0,0 +1,4 @@
1
+ import { ShowValuesAsConfig } from './show-values-as.type.js';
2
+
3
+ /** The Excel number format of a shown value (percentages: `0.0%`), `undefined` for the default. */
4
+ export declare function excelFormatOfShowValuesAs(config: ShowValuesAsConfig | undefined): string | undefined;
@@ -0,0 +1,87 @@
1
+ import { ShowValuesAs, ShowValuesAsConfig, ShowValuesAsIf } from './show-values-as.type.js';
2
+
3
+ /**
4
+ * The full options of a „Show values as“ configuration – `undefined` for none or an unknown mode.
5
+ *
6
+ * @param {ShowValuesAsConfig | undefined} config - a mode or mode with options
7
+ * @returns {ShowValuesAsIf | undefined} the options
8
+ *
9
+ * @example
10
+ * resolveShowValuesAs("rank"); // { mode: "rank" }
11
+ *
12
+ * @since 1.1.95
13
+ * @category Calculated columns & formulas
14
+ */
15
+ export declare function resolveShowValuesAs(config: ShowValuesAsConfig | undefined | null): ShowValuesAsIf | undefined;
16
+ /**
17
+ * All modes of {@link ShowValuesAs}, e.g. for an own select box.
18
+ *
19
+ * @example
20
+ * select.append(...SHOW_VALUES_AS_MODES.map(mode => new Option(mode, mode)));
21
+ *
22
+ * @since 1.1.95
23
+ * @category Calculated columns & formulas
24
+ */
25
+ export declare const SHOW_VALUES_AS_MODES: readonly ShowValuesAs[];
26
+ /**
27
+ * True for the modes that show a share (a fraction, shown as percentage).
28
+ *
29
+ * @param {ShowValuesAs} mode - the mode
30
+ * @returns {boolean} whether the shown value is a fraction
31
+ *
32
+ * @example
33
+ * isPercentShowValuesAs("percentOfColumnTotal"); // true
34
+ * isPercentShowValuesAs("rank"); // false
35
+ *
36
+ * @since 1.1.95
37
+ * @category Calculated columns & formulas
38
+ */
39
+ export declare function isPercentShowValuesAs(mode: ShowValuesAs | undefined): boolean;
40
+ /**
41
+ * The text of a shown value: percentages with one decimal (`"66.7%"`), ranks without decimals, differences and
42
+ * running totals like totals (`"1,234.5"`). Not a number → `""`.
43
+ *
44
+ * @param {unknown} value - the shown value (a fraction for percentages)
45
+ * @param {ShowValuesAsConfig} config - the configuration of the column
46
+ * @returns {string} the text
47
+ *
48
+ * @example
49
+ * formatShowValuesAs(0.667, "percentOfColumnTotal"); // "66.7%"
50
+ * formatShowValuesAs(0.667, { mode: "percentOfColumnTotal", fractionDigits: 2 }); // "66.70%"
51
+ *
52
+ * @since 1.1.95
53
+ * @category Calculated columns & formulas
54
+ */
55
+ export declare function formatShowValuesAs(value: unknown, config: ShowValuesAsConfig): string;
56
+ /**
57
+ * The sum of the numbers of a list (Neumaier, like {@link Aggregators}.sum); other values are skipped.
58
+ *
59
+ * @param {ArrayLike<unknown>} values - the values
60
+ * @returns {number} the sum, 0 for none
61
+ *
62
+ * @example
63
+ * sumOfNumbers([1, "2", 3, undefined]); // 4
64
+ *
65
+ * @since 1.1.95
66
+ * @category Calculated columns & formulas
67
+ */
68
+ export declare function sumOfNumbers(values: ArrayLike<unknown>): number;
69
+ /**
70
+ * „Show values as“ over a list of values in display order – DOM-free, for own area models. Percentages are
71
+ * fractions (`0.667`); the reference is the list itself (`percentOfRowTotal` is not applicable to a list: the values are
72
+ * returned unchanged). Values that are no numbers → `undefined`.
73
+ *
74
+ * @param {ArrayLike<unknown>} values - the raw values in display order
75
+ * @param {ShowValuesAs} mode - the mode
76
+ * @returns {(number | undefined)[]} the shown values
77
+ *
78
+ * @example
79
+ * calculateShowValuesAs([2598, 1047, 250], "percentOfColumnTotal"); // [0.667…, 0.268…, 0.064…]
80
+ * calculateShowValuesAs([10, 20, 20, 5], "rank"); // [3, 1, 1, 4]
81
+ * calculateShowValuesAs([10, 20, 5], "runningTotal"); // [10, 30, 35]
82
+ * calculateShowValuesAs([10, 20, 5], "differenceFromPrevious"); // [undefined, 10, -15]
83
+ *
84
+ * @since 1.1.95
85
+ * @category Calculated columns & formulas
86
+ */
87
+ export declare function calculateShowValuesAs(values: ArrayLike<unknown>, mode: ShowValuesAs): (number | undefined)[];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * How a column shows its numbers – without changing the data („Show values as“):
3
+ *
4
+ * | Mode | Shows | Flat table | Tree / row groups | Pivot |
5
+ * |---|---|---|---|---|
6
+ * | `"percentOfColumnTotal"` | value / sum of the column | ✓ | sum of the (filtered) leaf rows | cell / column total |
7
+ * | `"percentOfGrandTotal"` | value / grand total | = column total | = column total | cell / grand total |
8
+ * | `"percentOfParentTotal"` | value / total of the parent | = column total | value / sum of its siblings (each group = 100 %) | cell / parent row |
9
+ * | `"percentOfRowTotal"` | value / row total | – | – | cell / row total |
10
+ * | `"differenceFromPrevious"` | value − value of the row above | ✓ (first row empty) | among siblings | – |
11
+ * | `"runningTotal"` | sum up to this row (display order) | ✓ | among siblings | – |
12
+ * | `"rank"` | 1 = largest value, ties share a rank (1, 2, 2, 4) | ✓ | among siblings | – |
13
+ *
14
+ * The reference are the **filtered** rows (like the total row). Not applicable (–): the raw value is shown.
15
+ * Values that are no numbers and a total of 0 give an empty cell.
16
+ *
17
+ * @example
18
+ * ColumnDef.create({ property: "share", headerLabel: "Share", valueGetter: o => o.total,
19
+ * showValuesAs: "percentOfColumnTotal" });
20
+ *
21
+ * @since 1.1.95
22
+ * @category Calculated columns & formulas
23
+ */
24
+ export type ShowValuesAs = "percentOfColumnTotal" | "percentOfGrandTotal" | "percentOfParentTotal" | "percentOfRowTotal" | "differenceFromPrevious" | "runningTotal" | "rank";
25
+ /**
26
+ * „Show values as“ with options: mode, decimals, own text.
27
+ *
28
+ * @example
29
+ * ColumnDef.create({
30
+ * property: "total", headerLabel: "Share",
31
+ * showValuesAs: { mode: "percentOfColumnTotal", fractionDigits: 2 } // "66.70%"
32
+ * });
33
+ *
34
+ * @since 1.1.95
35
+ * @category Calculated columns & formulas
36
+ */
37
+ export interface ShowValuesAsIf {
38
+ /** The mode. */
39
+ mode: ShowValuesAs;
40
+ /** Decimals of the text. Default: 1 for percentages, at most 2 otherwise, 0 for `rank`. */
41
+ fractionDigits?: number;
42
+ /** An own text of the shown value (a fraction for percentages, e.g. `0.667`). Text only – never HTML. */
43
+ format?: (value: number) => string;
44
+ }
45
+ /**
46
+ * The configuration of a column: a mode or a mode with options.
47
+ *
48
+ * @example
49
+ * const share: ShowValuesAsConfig = "percentOfColumnTotal";
50
+ * const precise: ShowValuesAsConfig = { mode: "percentOfColumnTotal", fractionDigits: 2 };
51
+ *
52
+ * @since 1.1.95
53
+ * @category Calculated columns & formulas
54
+ */
55
+ export type ShowValuesAsConfig = ShowValuesAs | ShowValuesAsIf;