@one-grid-core/angular 0.1.0-beta.6 → 0.2.0

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 (66) hide show
  1. package/README.md +49 -4
  2. package/esm2022/lib/components/one-grid/one-grid.component.mjs +67 -16
  3. package/esm2022/lib/components/one-grid-body/one-grid-body.component.mjs +282 -30
  4. package/esm2022/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.mjs +10 -7
  5. package/esm2022/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.mjs +60 -4
  6. package/esm2022/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.mjs +14 -5
  7. package/esm2022/lib/components/one-grid-header/one-grid-header.component.mjs +50 -13
  8. package/esm2022/lib/components/one-grid-pagination/one-grid-pagination.component.mjs +39 -15
  9. package/esm2022/lib/components/one-grid-row-action/one-grid-row-action.component.mjs +54 -8
  10. package/esm2022/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.mjs +110 -0
  11. package/esm2022/lib/core/directives/one-cell-renderer-component.directive.mjs +9 -2
  12. package/esm2022/lib/core/directives/one-cell-text-expand.directive.mjs +33 -51
  13. package/esm2022/lib/core/instants/one-grid-api.class.mjs +429 -166
  14. package/esm2022/lib/core/instants/one-row-node.class.mjs +103 -37
  15. package/esm2022/lib/core/models/one-column-def-types.model.mjs +1 -1
  16. package/esm2022/lib/core/models/one-event-types.model.mjs +1 -1
  17. package/esm2022/lib/core/models/one-grid-types.model.mjs +1 -1
  18. package/esm2022/lib/core/models/one-row-drag.model.mjs +2 -0
  19. package/esm2022/lib/core/models/one-row.model.mjs +1 -1
  20. package/esm2022/lib/core/models/one-tree-data.model.mjs +1 -1
  21. package/esm2022/lib/core/models/one-validation.model.mjs +1 -1
  22. package/esm2022/lib/core/pipes/cell-field-value-empty.pipe.mjs +8 -3
  23. package/esm2022/lib/core/pipes/column-sort-state.pipe.mjs +3 -1
  24. package/esm2022/lib/core/services/og-column.service.mjs +120 -13
  25. package/esm2022/lib/core/services/one-grid-cell.service.mjs +123 -20
  26. package/esm2022/lib/core/services/one-grid-row-drag.service.mjs +351 -0
  27. package/esm2022/lib/core/services/one-grid-selection.service.mjs +19 -6
  28. package/esm2022/lib/helpers/one-column-def.helper.mjs +27 -2
  29. package/esm2022/lib/helpers/one-filter.helper.mjs +71 -12
  30. package/esm2022/lib/helpers/one-validation.helper.mjs +7 -2
  31. package/esm2022/lib/index.mjs +6 -1
  32. package/esm2022/lib/one-grid.module.mjs +7 -16
  33. package/fesm2022/one-grid-core-angular.mjs +1964 -421
  34. package/fesm2022/one-grid-core-angular.mjs.map +1 -1
  35. package/lib/components/one-grid/one-grid.component.d.ts +16 -1
  36. package/lib/components/one-grid-body/one-grid-body.component.d.ts +132 -5
  37. package/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.d.ts +6 -1
  38. package/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.d.ts +19 -2
  39. package/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.d.ts +5 -2
  40. package/lib/components/one-grid-header/one-grid-header.component.d.ts +15 -7
  41. package/lib/components/one-grid-pagination/one-grid-pagination.component.d.ts +24 -5
  42. package/lib/components/one-grid-row-action/one-grid-row-action.component.d.ts +44 -0
  43. package/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.d.ts +39 -0
  44. package/lib/core/directives/one-cell-text-expand.directive.d.ts +21 -9
  45. package/lib/core/instants/one-grid-api.class.d.ts +212 -26
  46. package/lib/core/instants/one-row-node.class.d.ts +67 -14
  47. package/lib/core/models/one-column-def-types.model.d.ts +89 -15
  48. package/lib/core/models/one-event-types.model.d.ts +24 -1
  49. package/lib/core/models/one-grid-types.model.d.ts +36 -1
  50. package/lib/core/models/one-row-drag.model.d.ts +44 -0
  51. package/lib/core/models/one-row.model.d.ts +0 -5
  52. package/lib/core/models/one-tree-data.model.d.ts +13 -0
  53. package/lib/core/models/one-validation.model.d.ts +12 -2
  54. package/lib/core/pipes/column-sort-state.pipe.d.ts +1 -1
  55. package/lib/core/services/og-column.service.d.ts +44 -3
  56. package/lib/core/services/one-grid-cell.service.d.ts +52 -4
  57. package/lib/core/services/one-grid-row-drag.service.d.ts +113 -0
  58. package/lib/core/services/one-grid-selection.service.d.ts +9 -0
  59. package/lib/helpers/one-column-def.helper.d.ts +19 -1
  60. package/lib/helpers/one-filter.helper.d.ts +29 -4
  61. package/lib/index.d.ts +5 -0
  62. package/lib/one-grid.module.d.ts +17 -19
  63. package/package.json +1 -2
  64. package/scss/_one-grid.scss +389 -17
  65. package/esm2022/lib/core/pipes/cell-disable-resolver.pipe.mjs +0 -26
  66. package/lib/core/pipes/cell-disable-resolver.pipe.d.ts +0 -9
@@ -1,18 +1,16 @@
1
- import { OneCellRendererComponent } from '../models/one-tree-data.model';
2
1
  import { OneColumnDef } from '../models/one-column-def-types.model';
3
2
  import { OneRowNode } from "./one-row-node.class";
4
- import { OneGridType, OneSortModel } from '../models/one-grid-types.model';
3
+ import { OneGridInitOptions, OneGridType, OneSortModel } from '../models/one-grid-types.model';
5
4
  import { OneGridEventService } from '../services/one-grid-event.service';
6
5
  import { OneGridSelectionService } from '../services/one-grid-selection.service';
7
- import { OneValidationResult } from '../models/one-validation.model';
6
+ import { OneRowValidationErrors, OneValidationResult } from '../models/one-validation.model';
8
7
  import { OneFilterModel } from "../models/one-filter.model";
9
8
  import { OneGridExpansionService } from '../services/one-grid-expansion.service';
10
- import { OneDetailCellRendererParams, OneGetDetailRowDataParams } from "../models/one-master-detail.model";
9
+ import { OneGetDetailRowDataParams } from "../models/one-master-detail.model";
11
10
  import { OneGridRowService } from "../services/one-grid-row.service";
11
+ import { OneRowDragSuppressedReason } from "../models/one-row-drag.model";
12
12
  import { OneGridCellService } from '../services/one-grid-cell.service';
13
- import { Type } from "@angular/core";
14
- import { ColumnChangedEvent, RowSelectionMode } from "../models/one-event-types.model";
15
- import { OneGroupColumnDef } from "../models/one-column-def-types.model";
13
+ import { ColumnChangedEvent, OnePinnedRowSide, RowSelectionMode } from "../models/one-event-types.model";
16
14
  import { OgColumnService } from "../services/og-column.service";
17
15
  import * as i0 from "@angular/core";
18
16
  export declare class OneGridApi<T = any> {
@@ -22,18 +20,31 @@ export declare class OneGridApi<T = any> {
22
20
  private eventService;
23
21
  private selectionService;
24
22
  private expansionService;
25
- id: string;
26
- context: any;
27
- rowSelection: RowSelectionMode;
28
- apiType: OneGridType;
29
- rowNodes: OneRowNode<T>[];
30
- sortModel: OneSortModel<T>[];
23
+ private _id;
24
+ private _context;
25
+ private _rowSelection;
26
+ private _apiType;
27
+ private _rowNodes;
28
+ private _sortModel;
29
+ /** Unique per grid instance, assigned during `init`. */
30
+ get id(): string;
31
+ /** The `[context]` the grid was given. */
32
+ get context(): any;
33
+ /** Selection mode, captured during `init`. Changing the input later has no effect. */
34
+ get rowSelection(): RowSelectionMode;
35
+ /** Which role this instance plays: simple, master, detail or tree. */
36
+ get apiType(): OneGridType;
37
+ /** Every node the grid holds, in flattened order. */
38
+ get rowNodes(): readonly OneRowNode<T>[];
39
+ /** The sort model currently applied. Change it with `onSortChanged`. */
40
+ get sortModel(): readonly OneSortModel<T>[];
31
41
  private rowHeight;
32
42
  private headerRowHeight;
33
43
  private _currentIndex;
34
44
  private _quickFilterValue;
35
45
  private _activeFilters;
36
46
  private _visibleRowNodes;
47
+ private readonly _pinnedRowNodes;
37
48
  private _originalRowNodes;
38
49
  private _nodeCleanupMap;
39
50
  private _destroyed;
@@ -43,17 +54,45 @@ export declare class OneGridApi<T = any> {
43
54
  private masterDetail;
44
55
  private detailCellRendererParams;
45
56
  private detailRendererComponent?;
46
- getDetailRowData: (params: OneGetDetailRowDataParams) => void;
57
+ /**
58
+ * Supplies a master row's detail rows. Set through `setGetDetailRowData`;
59
+ * previously a writable public field with a setter beside it, which left two
60
+ * ways to do the same thing and one of them unchecked.
61
+ */
62
+ private _getDetailRowData;
47
63
  constructor(columnService: OgColumnService, rowService: OneGridRowService, cellService: OneGridCellService, eventService: OneGridEventService, selectionService: OneGridSelectionService, expansionService: OneGridExpansionService);
48
- init(gridApiType: OneGridType, rowSelection: RowSelectionMode, columnDefs: OneColumnDef<T>[], defaultColumnDef: OneColumnDef<T>, context: any, masterDetail: boolean, detailCellRendererParams: OneDetailCellRendererParams, detailRendererComponent: Type<OneCellRendererComponent>, treeData: boolean, groupColumnDefs: OneGroupColumnDef[]): void;
49
64
  /**
50
- * Create Row Node & Clear All State IDS
65
+ * Stand the grid up. Called by `OneGridComponent` from `ngOnInit`.
66
+ *
67
+ * Takes a single `OneGridInitOptions` rather than the ten positional
68
+ * arguments it used to, so a call site reads as the configuration it is and
69
+ * a new option no longer means editing every caller.
70
+ *
71
+ * @internal Applications obtain a ready-made API from `(onGridReady)`; they
72
+ * should never call this themselves.
73
+ */
74
+ init(options: OneGridInitOptions<T>): void;
75
+ /**
76
+ * Replace every row, discarding selection and expansion.
77
+ *
78
+ * Use this when the rows represent something new. To swap the data while
79
+ * keeping what the user has selected and opened, use `updateRowData`.
51
80
  */
52
81
  setRowData(rowData: T[]): void;
53
82
  /**
54
- * Create Row Nodes & Not Clear State IDS
83
+ * Replace every row, keeping selection and expansion.
84
+ *
85
+ * State is keyed by row id, so this only preserves anything if the grid has a
86
+ * `context.componentParent.getRowId` — otherwise each rebuild mints new ids
87
+ * and there is nothing left to match against.
55
88
  */
56
89
  updateRowData(rowData: T[]): void;
90
+ /**
91
+ * The one row-loading path. `setRowData` and `updateRowData` differed only in
92
+ * whether they cleared the state services first, so everything else — build,
93
+ * filter, prune — lives here once.
94
+ */
95
+ private rebuildRows;
57
96
  /**
58
97
  * Recursive Build Row Nodes (Optimized)
59
98
  */
@@ -62,10 +101,77 @@ export declare class OneGridApi<T = any> {
62
101
  * Filter Feature
63
102
  */
64
103
  private applyFilters;
104
+ /**
105
+ * Which fields the quick filter searches: every column that has one.
106
+ *
107
+ * Empty while the columns are still being registered, in which case the
108
+ * helper falls back to searching the row — the same behaviour as before, and
109
+ * the only sensible answer when the grid does not yet know its columns.
110
+ */
111
+ private quickFilterFields;
65
112
  /**
66
113
  * Update Row Nodes Display
67
114
  */
68
115
  private refreshVisibleNodes;
116
+ /**
117
+ * Replace the rows anchored to one edge of the grid.
118
+ *
119
+ * Pinned rows are deliberately kept out of `rowNodes` and
120
+ * `_originalRowNodes`: they are not data. Sorting, filtering, selection,
121
+ * expansion, pagination and the visible row count all ignore them, which is
122
+ * the whole point of a summary row. They render with the same column
123
+ * definitions, so renderers and value getters work as they do everywhere
124
+ * else.
125
+ */
126
+ setPinnedRowData(side: OnePinnedRowSide, rowData: T[]): void;
127
+ /** The rows anchored to one edge. Read-only; change them with `setPinnedRowData`. */
128
+ getPinnedRowNodes(side: OnePinnedRowSide): readonly OneRowNode<T>[];
129
+ /**
130
+ * Row reordering
131
+ * --------------------------------------------------------------------------
132
+ *
133
+ * `_originalRowNodes` is the source of truth for row order: its insertion
134
+ * order is what `applySorting` falls back to when the sort model empties, and
135
+ * what a rebuild walks. `_rowNodes` is only the current display order. A move
136
+ * that touched one and not the other would either be undone by the next sort
137
+ * change or invisible until one happened, so both are rewritten together.
138
+ */
139
+ /**
140
+ * Whether the displayed order is the data order, and so whether a manual move
141
+ * would survive.
142
+ *
143
+ * @returns the reason reordering is unavailable, or `null` when it is fine.
144
+ */
145
+ getRowDragSuppressedReason(): OneRowDragSuppressedReason | null;
146
+ /** Convenience inverse of {@link getRowDragSuppressedReason}. */
147
+ canReorderRows(): boolean;
148
+ /**
149
+ * Move a row from one position to another.
150
+ *
151
+ * Indices are positions in the grid's row order, the same order
152
+ * `getAllRowNodes()` returns. `targetIndex` is where the row ends up *after*
153
+ * it has been lifted out of `sourceIndex` — dragging row 0 to the bottom of a
154
+ * 5-row grid is `moveRow(0, 4)`, not `moveRow(0, 5)`.
155
+ *
156
+ * @returns `true` if the rows moved. `false` when the move was rejected —
157
+ * out-of-range indices, a no-op, or an order the grid does not own
158
+ * (see {@link getRowDragSuppressedReason}) — so a caller can tell a
159
+ * refused move from an applied one.
160
+ */
161
+ moveRow(sourceIndex: number, targetIndex: number): boolean;
162
+ /**
163
+ * Move a row identified by id. Convenient when the caller holds a node rather
164
+ * than a position — the index it was built with goes stale after any move.
165
+ */
166
+ moveRowById(rowId: string, targetIndex: number): boolean;
167
+ /**
168
+ * Re-stamp `rowIndex` from the current order.
169
+ *
170
+ * Row index is denormalised onto every node, and half the grid reads it —
171
+ * cell params, the range selection, the detail lookup. Leaving it stale after
172
+ * a move puts every row below the drop point one out.
173
+ */
174
+ private reindexRows;
69
175
  getVisibleRowNodes(): OneRowNode<T>[];
70
176
  /**
71
177
  * Sorting Model Feature
@@ -101,16 +207,35 @@ export declare class OneGridApi<T = any> {
101
207
  */
102
208
  setQuickFilter(value: string): void;
103
209
  /**
104
- * Validation Feature
210
+ * Run the column validators over one row.
211
+ *
212
+ * Rules run in order and stop at the first failure, so a field appears at
213
+ * most once. Fields that passed are absent rather than mapped to `null`.
214
+ *
215
+ * The row type comes from the grid's own `T` — this used to declare its own
216
+ * `<T>`, which shadowed the class parameter and let an `OneGridApi<Employee>`
217
+ * happily validate an unrelated shape against employee columns.
218
+ */
219
+ validateRow(row: T, columns: OneColumnDef<T>[]): OneRowValidationErrors<T>;
220
+ /**
221
+ * Run the column validators over a whole dataset.
222
+ *
223
+ * Delegates to `validateRow` so the two can never disagree about what counts
224
+ * as invalid — they previously carried separate copies of the same loop.
105
225
  */
106
- validateRow<T>(row: T, columns: OneColumnDef<T>[]): Record<string, string>;
226
+ validateAllRows(rowData: T[], columns: OneColumnDef<T>[]): OneValidationResult<T>;
107
227
  /**
108
- * Validate all rows and return both errors and a flag indicating if there are any errors
228
+ * Traverse every node, depth-first, once each.
229
+ *
230
+ * `rowNodes` is already the flattened tree — `buildRowNodes` pushes every
231
+ * node into it as it descends — so walking it is the whole traversal. The
232
+ * previous implementation walked that flat list *and* recursed into
233
+ * `children`, visiting every nested node twice and every depth-3 node three
234
+ * times. `index` is the node's position in the flattened order, matching
235
+ * `node.rowIndex`, rather than its position among its siblings.
109
236
  */
110
- validateAllRows<T>(rowData: T[], columns: OneColumnDef<T>[]): OneValidationResult<T>;
111
- /** Traverse all nodes */
112
237
  forEachNode(callback: (node: OneRowNode<T>, index: number) => void): void;
113
- /** Traverse only leaf nodes */
238
+ /** Traverse only leaf nodes, once each, in flattened order. */
114
239
  forEachLeafNode(callback: (node: OneRowNode<T>, index: number) => void): void;
115
240
  getRowNodeById(rowId: string): OneRowNode<T>;
116
241
  /**
@@ -118,9 +243,32 @@ export declare class OneGridApi<T = any> {
118
243
  */
119
244
  setTreeDataChildrenField(field: string): void;
120
245
  setGroupDefaultExpanded(defaultExpanded: number): void;
246
+ /**
247
+ * Expansion state lives in two places, and they answer different questions.
248
+ *
249
+ * `OneGridExpansionService` records only *deliberate* changes — a click, or
250
+ * one of the methods below. It is an override layer: `buildRowNodes` consults
251
+ * it first and falls back to `groupDefaultExpanded` for every row the user
252
+ * has not touched. That is what lets a later `groupDefaultExpanded` change
253
+ * take effect, and what lets a collapse survive a rebuild.
254
+ *
255
+ * `node.expanded` is the resolved truth for a row, defaults included. Public
256
+ * reads report that; the override sets stay internal.
257
+ *
258
+ * The invariant the setters below maintain: `expanded` is only ever true for
259
+ * a node that can expand.
260
+ */
121
261
  toggleExpandAll(expanded: boolean): void;
122
262
  setExpandedById(rowId: string, expanded: boolean): void;
123
263
  setExpandedByIds(rowIds: string[], expanded: boolean): void;
264
+ /**
265
+ * Every currently expanded row, in tree order.
266
+ *
267
+ * Derived from the nodes rather than read off the override record, so rows
268
+ * opened by `groupDefaultExpanded` are included — previously this returned
269
+ * only rows someone had explicitly toggled, and came back empty on first load
270
+ * while the first level was visibly open.
271
+ */
124
272
  getExpandedByIds(): string[];
125
273
  /**
126
274
  * Master Detail Feature
@@ -138,24 +286,62 @@ export declare class OneGridApi<T = any> {
138
286
  * Update checkbox selection features
139
287
  */
140
288
  setNodeAndChildrenSelected(node: OneRowNode, selected: boolean): void;
289
+ /**
290
+ * @deprecated Identical to `updateCellStates`. Kept as an alias so existing
291
+ * callers keep working; prefer `updateCellStates`, which says what it does.
292
+ */
141
293
  updateNodeStates(node: OneRowNode): void;
142
294
  updateCellState(node: OneRowNode, column: OneColumnDef): void;
295
+ /**
296
+ * Recompute every cell of one row and repaint it.
297
+ *
298
+ * The repaint is the point: this is what a caller reaches for after mutating
299
+ * a row in place, and it used to regenerate the state and stop there. The
300
+ * body renders with OnPush, so nothing marked it dirty and the new state sat
301
+ * unread until some unrelated event happened to trigger change detection —
302
+ * which is why callers ended up nudging the grid with a synthetic DOM event.
303
+ */
143
304
  updateCellStates(node: OneRowNode): void;
144
305
  /**
145
306
  * Handler that Reacts to Detail Changes
146
307
  */
308
+ /**
309
+ * Keep a master row's reserved height in step with its detail rows.
310
+ *
311
+ * Two listeners used to be registered here and thrown away: an empty
312
+ * `rowDataChanged` handler whose unsubscribe was never kept, and an
313
+ * `expandedChanged` handler whose body was entirely commented out. Both are
314
+ * gone — a listener with no behaviour is a leak with no upside.
315
+ */
147
316
  private subscribeToDetailChanges;
148
317
  private registerNodeCleanup;
149
318
  private cleanupNode;
319
+ /**
320
+ * Drop nodes that are no longer in the data, releasing what they hold.
321
+ *
322
+ * This existed but was never called: `setRowData` and `updateRowData` each
323
+ * deleted straight out of `_originalRowNodes`, so a removed node kept its
324
+ * listeners and its entry in `_nodeCleanupMap` for the lifetime of the grid.
325
+ * Both now come through here, which unsubscribes and clears the node first.
326
+ */
150
327
  private pruneRemovedNodes;
151
328
  /**
152
- * Resolve Detail Row Height
329
+ * Height a master row must reserve for its detail grid:
330
+ * rowHeight x clamp(rows, minRows, maxRows) + headerHeight.
153
331
  */
154
- private _resolvedDetailRowHeight;
332
+ private resolveDetailRowHeight;
155
333
  /**
156
- * On Destroy
334
+ * Release everything the grid holds. Called by `OneGridComponent.ngOnDestroy`.
335
+ *
336
+ * The services are deliberately *not* nulled out any more. They are injected,
337
+ * Angular owns their lifetime, and nulling them only guaranteed a
338
+ * `TypeError` for any callback that arrived after teardown — a detail-row
339
+ * fetch resolving late, or the body's deferred update. `_destroyed` makes
340
+ * those calls no-ops instead, which is what a torn-down object should do.
157
341
  */
158
342
  destroy(): void;
343
+ /** Whether `destroy` has run. Late callbacks check this before doing work. */
344
+ get destroyed(): boolean;
159
345
  static ɵfac: i0.ɵɵFactoryDeclaration<OneGridApi<any>, never>;
160
346
  static ɵprov: i0.ɵɵInjectableDeclaration<OneGridApi<any>>;
161
347
  }
@@ -2,48 +2,101 @@ import { Type } from "@angular/core";
2
2
  import { OneCellOptions, OneCellStates } from "../models/one-column-def-types.model";
3
3
  import { OneRowNodeEventMap, OneRowNodeListener } from "../models/one-row.model";
4
4
  import { OneCellRendererComponent } from "../models/one-tree-data.model";
5
+ /**
6
+ * The grid's wrapper around one row of your data.
7
+ *
8
+ * A node owns three kinds of state: its identity and position, the structural
9
+ * facts the grid derived while building the tree, and the per-cell UI state.
10
+ * `data` is your object, held by reference and mutated in place when a cell is
11
+ * committed — the node never copies it.
12
+ *
13
+ * @typeParam T - the row type
14
+ * @typeParam D - the detail row type, for master/detail grids
15
+ */
5
16
  export declare class OneRowNode<T = any, D = any> {
6
- rowId: string;
17
+ /**
18
+ * Stable key for this row, from `context.componentParent.getRowId` or a
19
+ * generated uuid. Selection, expansion and cell state are all keyed by it,
20
+ * which is why it never changes for the life of the node.
21
+ */
22
+ readonly rowId: string;
23
+ /** Position in the flattened row list. Reassigned whenever rows are rebuilt. */
7
24
  rowIndex: number;
25
+ /** Your row object, by reference. */
8
26
  data: T;
27
+ /** Depth in the tree. 0 at the root; always 0 outside tree data. */
9
28
  level: number;
29
+ /** Has no children of its own. */
10
30
  leaf: boolean;
31
+ /** Is a group, but an empty one. */
11
32
  leafGroup: boolean;
33
+ /** Has children. */
34
+ group: boolean;
35
+ /** Can be opened — a non-empty group, or any row in a master/detail grid. */
36
+ expandable: boolean;
37
+ /** Survives the active filters. Recomputed on every filter pass. */
12
38
  visible: boolean;
13
39
  selected: boolean;
14
- expandable: boolean;
15
40
  expanded: boolean;
16
- group: boolean;
17
- submitted: boolean;
18
41
  parent: OneRowNode<T> | null;
19
42
  children: OneRowNode<T>[] | null;
43
+ /** Which cells currently have an open editor. */
20
44
  editing: {
21
45
  [field: string]: boolean;
22
46
  };
47
+ /** Rendered value and kind for each cell, computed when the row is built. */
23
48
  cellStates: OneCellStates;
24
49
  cellOptions: OneCellOptions;
25
- detailRowData: D[];
50
+ /** Detail rows for this master row. `null` until they have been supplied. */
51
+ detailRowData: D[] | null;
52
+ /** Whether the custom detail renderer is showing. Toggled by the row action. */
26
53
  detailActive: boolean;
27
- detailRowHeight: number;
54
+ /** Height reserved for the detail area, computed from the detail row count. */
55
+ detailRowHeight: number | null;
28
56
  detailRendererComponent?: Type<OneCellRendererComponent>;
29
- private listeners;
57
+ /**
58
+ * Listeners per event. Typed as a payload-agnostic callback because the map
59
+ * is heterogeneous; `on` and `emit` restore the per-event type at the edges.
60
+ */
61
+ private readonly listeners;
30
62
  constructor(rowId: string, data: T, rowIndex: number);
31
- setDataValue(field: string, value: any): void;
63
+ /**
64
+ * Write one field of the row and announce it.
65
+ *
66
+ * `null` is allowed because that is what the grid itself stores for a cleared
67
+ * cell; anything else must match the field's declared type.
68
+ */
69
+ setDataValue<K extends keyof T & string>(field: K, value: T[K] | null): void;
32
70
  setSelected(selected: boolean): void;
33
71
  setRowIndex(index: number): void;
34
72
  setCellStates(cellStates: OneCellStates): void;
73
+ /** @deprecated Read `node.selected`. */
35
74
  isSelected(): boolean;
75
+ /** @deprecated Read `node.expanded`. */
36
76
  isExpanded(): boolean;
77
+ /** Supply or replace this master row's detail rows. */
78
+ setDetailRowData(detailRowData: D[]): void;
79
+ setExpanded(expanded: boolean): void;
37
80
  /**
38
- * Event System
81
+ * Subscribe to one of this node's events.
82
+ *
83
+ * @returns an unsubscribe function. Call it, or `destroy()`, to release the
84
+ * listener — a node outlives any single render.
39
85
  */
40
86
  on<K extends keyof OneRowNodeEventMap<T>>(event: K, listener: OneRowNodeListener<T, K>): () => void;
41
87
  off<K extends keyof OneRowNodeEventMap<T>>(event: K, listener: OneRowNodeListener<T, K>): void;
42
- emit<K extends keyof OneRowNodeEventMap<T>>(event: K, payload: OneRowNodeEventMap<T>[K]): void;
43
88
  /**
44
- * Mutators that fire events
45
- */
46
- setDetailRowData(detailRowData: D[]): void;
47
- setExpanded(expanded: boolean): void;
89
+ * Notify listeners. Private on purpose: every event this class publishes is
90
+ * raised by the mutator that caused it, and a forged `expandedChanged` would
91
+ * leave the node's flag and the grid's view of it disagreeing.
92
+ */
93
+ private emit;
94
+ /**
95
+ * Release everything this node holds. Called by the grid when the row leaves
96
+ * the data or the grid is torn down.
97
+ *
98
+ * The tree links matter as much as the listeners: a parent holding children
99
+ * that hold the parent keeps the whole subtree — and its data — reachable.
100
+ */
48
101
  destroy(): void;
49
102
  }
@@ -7,8 +7,10 @@ import type { OneCellRendererComponent } from "./one-tree-data.model";
7
7
  export interface OneValueGetterParams<T = any> {
8
8
  data: T;
9
9
  rowIndex?: number;
10
+ /** @deprecated Never populated. Use {@link node}. */
10
11
  rowNode?: OneRowNode;
11
12
  node?: OneRowNode;
13
+ /** @deprecated Never populated — the cell service has no api reference. */
12
14
  api?: OneGridApi;
13
15
  context?: any;
14
16
  }
@@ -25,6 +27,35 @@ export interface OneCellOptions {
25
27
  export type OneCellStatus = 0 | 1;
26
28
  export type OneCellButtonIconType = 'add' | 'option' | 'language';
27
29
  export type OneCellInputType = 'text' | 'number' | 'email' | 'date' | 'time' | 'datetime' | 'datetime-local';
30
+ /**
31
+ * What a per-cell presentation callback is handed.
32
+ *
33
+ * `OneCellRendererParams` has every field optional, because one type serves
34
+ * renderers, action buttons and headers alike. For `cellClass` and `cellStyle`
35
+ * the grid guarantees all of these, so they are required here — otherwise a
36
+ * consumer under `strict` has to write `params?.data?.x` for a value that is
37
+ * always present.
38
+ */
39
+ export interface OneCellPresentationParams<T = any> extends OneCellRendererParams<T> {
40
+ value: any;
41
+ data: T;
42
+ node: OneRowNode<T>;
43
+ rowIndex: number;
44
+ field: string;
45
+ columnDef: OneColumnDef<T>;
46
+ }
47
+ /**
48
+ * What a header presentation callback is handed.
49
+ *
50
+ * Deliberately not the cell params: a header is one cell for the whole column,
51
+ * resolved once when the columns are registered. There is no row, so offering
52
+ * `data` or `node` here would be offering something that is always undefined.
53
+ */
54
+ export interface OneHeaderPresentationParams<T = any> {
55
+ field: string;
56
+ columnDef: OneColumnDef<T>;
57
+ context?: any;
58
+ }
28
59
  export interface OneCellRendererParams<T = any> {
29
60
  value?: any;
30
61
  rowIndex?: number;
@@ -91,6 +122,14 @@ export interface OneColumnDef<T = any> {
91
122
  rowActionLevels?: number[];
92
123
  headerName?: string;
93
124
  checkboxSelection?: boolean;
125
+ /**
126
+ * Put a row drag handle in this column's cells. One column carries it.
127
+ *
128
+ * A handle rather than the whole row: the body already claims `mousedown`
129
+ * on a cell to start a range selection, so a row-wide drag would have to
130
+ * fight it for every press.
131
+ */
132
+ rowDrag?: boolean | ((params: OneCellPresentationParams<T>) => boolean);
94
133
  headerCheckboxSelection?: boolean;
95
134
  flex?: number;
96
135
  width?: number;
@@ -99,16 +138,20 @@ export interface OneColumnDef<T = any> {
99
138
  validationRules?: OneValidatorFn[];
100
139
  headerStyle?: {
101
140
  [key: string]: string;
102
- } | ((params: OneCellRendererParams<T>) => {
141
+ } | ((params: OneHeaderPresentationParams<T>) => {
103
142
  [key: string]: string;
104
143
  });
105
144
  cellStyle?: {
106
145
  [key: string]: string;
107
- } | ((params: OneCellRendererParams<T>) => {
146
+ } | ((params: OneCellPresentationParams<T>) => {
108
147
  [key: string]: string;
109
148
  });
110
- headerClass?: string | string[] | ((params: OneCellRendererParams<T>) => string | string[]);
111
- cellClass?: string | string[] | ((params: OneCellRendererParams<T>) => string | string[]);
149
+ headerClass?: string | string[] | ((params: OneHeaderPresentationParams<T>) => string | string[]);
150
+ cellClass?: string | string[] | ((params: OneCellPresentationParams<T>) => string | string[]);
151
+ _resolvedSortable?: boolean;
152
+ _resolvedResizable?: boolean;
153
+ _resolvedDragable?: boolean;
154
+ _resolvedSuppressHeaderMenuButton?: boolean;
112
155
  _resolvedHeaderClass?: string | string[];
113
156
  _resolvedCellClass?: string | string[];
114
157
  _resolvedHeaderStyle?: Record<string, string>;
@@ -116,21 +159,52 @@ export interface OneColumnDef<T = any> {
116
159
  cellRendererParams?: OneCellRendererParams<T>;
117
160
  cellOptionMenu?: OneCellOptionMenu[];
118
161
  alignContent?: 'left' | 'center' | 'right';
162
+ /**
163
+ * Freeze this column against the left or right edge while the rest scroll.
164
+ *
165
+ * Pinned columns are moved to their edge in display order — left-pinned to
166
+ * the front, right-pinned to the back — each keeping its declared order
167
+ * within its own group. Unpinned columns are untouched, so a grid with
168
+ * nothing pinned renders exactly as before.
169
+ */
119
170
  pinned?: 'left' | 'right';
120
- sortable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
121
- resizable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
122
- filterable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
123
- editable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
124
- updatable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
125
- disable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
126
- dragable?: boolean | ((params: OneCellRendererParams<T>) => boolean);
127
- hideActionButton?: boolean | ((params: OneCellRendererParams<T>) => boolean);
128
- suppressHeaderMenuButton?: boolean | ((params: OneCellRendererParams<T>) => boolean);
171
+ /** Distance in px from the pinned edge. Computed by the grid; do not set. */
172
+ _pinnedOffset?: number | null;
173
+ /** True on the innermost pinned column of each side, which carries the divider. */
174
+ _pinnedEdge?: boolean;
175
+ sortable?: boolean | ((params: OneHeaderPresentationParams<T>) => boolean);
176
+ resizable?: boolean | ((params: OneHeaderPresentationParams<T>) => boolean);
177
+ dragable?: boolean | ((params: OneHeaderPresentationParams<T>) => boolean);
178
+ suppressHeaderMenuButton?: boolean | ((params: OneHeaderPresentationParams<T>) => boolean);
179
+ editable?: boolean | ((params: OneCellPresentationParams<T>) => boolean);
180
+ updatable?: boolean | ((params: OneCellPresentationParams<T>) => boolean);
181
+ disable?: boolean | ((params: OneCellPresentationParams<T>) => boolean);
182
+ hideActionButton?: boolean | ((params: OneCellPresentationParams<T>) => boolean);
183
+ /** @deprecated Not implemented — nothing in the grid reads this. */
184
+ filterable?: boolean | ((params: OneCellPresentationParams<T>) => boolean);
129
185
  cellRendererComponent?: Type<OneCellRendererComponent>;
130
- cellRenderer?: (params: OneCellRendererParams<T>) => string;
186
+ cellRenderer?: (params: OneCellPresentationParams<T>) => string;
187
+ /**
188
+ * Derive this cell's value from the whole row.
189
+ *
190
+ * The value, not the display text — sorting and filtering read the raw row
191
+ * data, so formatting done here is invisible to both. Put presentation in
192
+ * `valueFormatter` instead and this stays sortable.
193
+ */
131
194
  valueGetter?: (params: OneValueGetterParams<T>) => any;
195
+ /**
196
+ * Format the value for display. Runs after `valueGetter`, on text cells
197
+ * only — an empty cell falls to `cellRendererParams.placeholder` instead.
198
+ */
199
+ valueFormatter?: (params: OneCellPresentationParams<T>) => string;
200
+ /**
201
+ * @deprecated Not implemented — nothing in the grid calls this, and the
202
+ * signature could not work if it did: it receives neither the node nor the
203
+ * field, so it cannot tell which cell it is meant to write. Commit an edit
204
+ * through `node.setDataValue(field, value)` and refresh with
205
+ * `api.updateCellStates(node)`.
206
+ */
132
207
  valueSetter?: (value: any, rowIndex: number) => void;
133
- valueFormatter?: (params: OneCellRendererParams<T>) => string;
134
208
  }
135
209
  export type OneCellValidationType = 'disabled' | 'integer' | 'number' | 'code' | 'title' | 'phone' | 'email' | 'description' | 'regex' | 'none';
136
210
  export interface CellSelection {
@@ -17,6 +17,12 @@ export interface ColumnMovedEvent {
17
17
  export interface RowDataChangedEvent<T> {
18
18
  nodes: OneRowNode<T>[];
19
19
  }
20
+ /** Which edge a set of pinned rows is anchored to. */
21
+ export type OnePinnedRowSide = 'top' | 'bottom';
22
+ export interface PinnedRowDataChangedEvent<T = any> {
23
+ side: OnePinnedRowSide;
24
+ nodes: OneRowNode<T>[];
25
+ }
20
26
  export interface OneCellOptionMenu {
21
27
  text: string;
22
28
  value: any;
@@ -60,7 +66,22 @@ export interface ColumnChangedEvent {
60
66
  export interface CellStateChangedEvent<T> {
61
67
  data: T;
62
68
  node: OneRowNode<T>;
63
- column: OneColumnDef<T>;
69
+ /**
70
+ * The column whose cell changed. Absent when the whole row was refreshed
71
+ * through `api.updateCellStates(node)`, which regenerates every cell and so
72
+ * has no single column to name.
73
+ */
74
+ column?: OneColumnDef<T>;
75
+ }
76
+ /**
77
+ * Rows were reordered. Carries the whole new order, because the display order
78
+ * is what the body renders, plus which row moved for anyone tracking the edit.
79
+ */
80
+ export interface RowOrderChangedEvent<T = any> {
81
+ nodes: OneRowNode<T>[];
82
+ node: OneRowNode<T>;
83
+ fromIndex: number;
84
+ toIndex: number;
64
85
  }
65
86
  export interface EventPayloadMap<T = any> {
66
87
  rowSelected: RowSelectedEvent;
@@ -69,8 +90,10 @@ export interface EventPayloadMap<T = any> {
69
90
  columnResized: ColumnResizedEvent;
70
91
  columnChanged: ColumnChangedEvent;
71
92
  rowDataChanged: RowDataChangedEvent<T>;
93
+ pinnedRowDataChanged: PinnedRowDataChangedEvent<T>;
72
94
  selectionChanged: SelectionChangedEvent<T>;
73
95
  sortChanged: SortChangedEvent<T>;
96
+ rowOrderChanged: RowOrderChangedEvent<T>;
74
97
  cellStateChanged: CellStateChangedEvent<T>;
75
98
  }
76
99
  export type OneCheckboxState = 'checked' | 'unchecked' | 'indeterminate';