infi-grid 1.0.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 (51) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/README.md +654 -0
  3. package/fesm2022/infi-grid.mjs +10314 -0
  4. package/fesm2022/infi-grid.mjs.map +1 -0
  5. package/index.d.ts +5 -0
  6. package/lib/components/cell-editor.component.d.ts +42 -0
  7. package/lib/components/filter-popup.component.d.ts +89 -0
  8. package/lib/components/filter-row.component.d.ts +104 -0
  9. package/lib/components/grid.component.d.ts +155 -0
  10. package/lib/components/header-row.component.d.ts +76 -0
  11. package/lib/components/row.component.d.ts +106 -0
  12. package/lib/components/summary-row.component.d.ts +40 -0
  13. package/lib/components/tooltip-controller.d.ts +43 -0
  14. package/lib/components/viewport.component.d.ts +217 -0
  15. package/lib/core/accessor.d.ts +6 -0
  16. package/lib/core/config-resolver.d.ts +16 -0
  17. package/lib/core/defaults.d.ts +7 -0
  18. package/lib/core/filter-engine.d.ts +44 -0
  19. package/lib/core/format.d.ts +11 -0
  20. package/lib/core/keys.d.ts +24 -0
  21. package/lib/core/row-ops.d.ts +20 -0
  22. package/lib/core/sort-engine.d.ts +11 -0
  23. package/lib/core/summary-engine.d.ts +35 -0
  24. package/lib/core/template-registry.d.ts +27 -0
  25. package/lib/core/theme.d.ts +2 -0
  26. package/lib/core/tooltip-position.d.ts +24 -0
  27. package/lib/core/values.d.ts +21 -0
  28. package/lib/core/virtual-math.d.ts +57 -0
  29. package/lib/directives/grid-template-component.d.ts +16 -0
  30. package/lib/directives/outlet.directive.d.ts +25 -0
  31. package/lib/directives/template.directives.d.ts +98 -0
  32. package/lib/grid.module.d.ts +15 -0
  33. package/lib/models/api.types.d.ts +249 -0
  34. package/lib/models/column.types.d.ts +184 -0
  35. package/lib/models/config.types.d.ts +390 -0
  36. package/lib/models/crud.types.d.ts +179 -0
  37. package/lib/models/data.types.d.ts +41 -0
  38. package/lib/models/events.types.d.ts +98 -0
  39. package/lib/models/filter.types.d.ts +78 -0
  40. package/lib/models/index.d.ts +12 -0
  41. package/lib/models/selection.types.d.ts +173 -0
  42. package/lib/models/sort.types.d.ts +22 -0
  43. package/lib/models/summary.types.d.ts +78 -0
  44. package/lib/models/template.types.d.ts +126 -0
  45. package/lib/models/tooltip.types.d.ts +48 -0
  46. package/lib/state/filter-popup.service.d.ts +30 -0
  47. package/lib/state/grid-api.d.ts +4 -0
  48. package/lib/state/grid-store.d.ts +584 -0
  49. package/lib/state/tooltip.service.d.ts +38 -0
  50. package/package.json +41 -0
  51. package/public-api.d.ts +8 -0
@@ -0,0 +1,390 @@
1
+ import type { ColumnConfig, GridDataType, GridStyleValue, GridClassValue } from './column.types';
2
+ import type { ActionColumnConfig, GridChangeSet, GridRowValidationResult } from './crud.types';
3
+ import type { DataRefreshConfig, GridRowKey } from './data.types';
4
+ import type { CellSelectionConfig, SelectionConfig } from './selection.types';
5
+ import type { TooltipConfig } from './tooltip.types';
6
+ import type { FilterIconVisibility, FilterModel } from './filter.types';
7
+ import type { SortDirection, SortIconVisibility, SortModelItem } from './sort.types';
8
+ import type { GridSummaryScope, GridSummaryType } from './summary.types';
9
+ import type { GridCellContext, GridEditContext, GridEmptyContext, GridErrorContext, GridHeaderContext, GridLoadingContext, GridSummaryCellContext, GridTemplate } from './template.types';
10
+ /** Virtualization settings. */
11
+ export interface VirtualizationConfig {
12
+ /** Render only the rows in (and near) the viewport. Default `true`. */
13
+ rows?: boolean;
14
+ /** Render only the columns in (and near) the viewport. Default `true`. */
15
+ columns?: boolean;
16
+ /** Extra rows rendered above and below the viewport. Default 6. */
17
+ rowBuffer?: number;
18
+ /** Extra columns rendered left and right of the viewport. Default 2. */
19
+ columnBuffer?: number;
20
+ /**
21
+ * Keep the drawn rows and columns in place while the browser scrolls, and move them in the same frame the grid
22
+ * draws the new ones. Browsers scroll on their own thread, ahead of the page's code: without this, fast scrolling
23
+ * (a flick, a scrollbar drag) shows areas that aren't drawn yet as blank rows or columns until the grid catches
24
+ * up. With it, the content follows the scrollbar a frame later instead, and is never blank. Default `true`.
25
+ */
26
+ syncScroll?: boolean;
27
+ }
28
+ /** Global sorting settings. */
29
+ export interface SortConfig {
30
+ /** Global sorting flag, the default for every column's `sortable`. Default `true`. */
31
+ enabled?: boolean;
32
+ /** Allow sorting by several columns (Shift/Ctrl/Cmd + click adds a column). Default `true`. */
33
+ multiSort?: boolean;
34
+ /** Key that adds a column to the sort. `'always'` makes every click add a column. Default `'shift'`. */
35
+ multiSortKey?: 'shift' | 'ctrl' | 'always';
36
+ /** Maximum number of sorted columns. Default unlimited. */
37
+ maxSortColumns?: number;
38
+ /** Show the sort icon in headers. Default `true`. */
39
+ showSortIcon?: boolean;
40
+ /** When the sort icon is visible. Default `'hover'`. */
41
+ sortIconVisibility?: SortIconVisibility;
42
+ /** Show the 1, 2, 3… sort order next to the icon when several columns are sorted. Default `true`. */
43
+ showSortIndex?: boolean;
44
+ /** Order of states when a header is clicked. Default `['asc', 'desc', null]`. */
45
+ cycle?: readonly (SortDirection | null)[];
46
+ /** Where empty values go. Default `'last'` (for both directions, like Excel). */
47
+ nulls?: 'first' | 'last';
48
+ /** Sort applied when the grid is created. */
49
+ initialSort?: readonly SortModelItem[];
50
+ }
51
+ /** Global filtering settings. */
52
+ export interface FilterConfig {
53
+ /** Global filtering flag, the default for every column's `filterable`. Default `true`. */
54
+ enabled?: boolean;
55
+ /** Show the filter icon in headers. Default `true`. */
56
+ showFilterIcon?: boolean;
57
+ /** When the filter icon is visible. Default `'always'`. */
58
+ filterIconVisibility?: FilterIconVisibility;
59
+ /** Show the Excel-style checkbox list of values. Default `true`. */
60
+ valueList?: boolean;
61
+ /** Show the condition (operator + value) section. Default `true`. */
62
+ conditions?: boolean;
63
+ /** Conditions available in the popup (1 to 5, combined with AND or OR). Default 2. */
64
+ maxConditions?: 1 | 2 | 3 | 4 | 5;
65
+ /** Case-sensitive text matching. Default `false`. */
66
+ caseSensitive?: boolean;
67
+ /** Show "Sort ascending/descending" buttons at the top of the popup. Default `true`. */
68
+ showSortButtons?: boolean;
69
+ /** Maximum distinct values listed in the checkbox list. Default 100 000. */
70
+ valueListLimit?: number;
71
+ /** Filter applied when the grid is created. */
72
+ initialFilter?: FilterModel;
73
+ /**
74
+ * Filter UI: the Excel-style popup of the header's filter button (`'menu'`), a filter row under the header
75
+ * with an input per column (`'row'`), or both. The filter row is shown while at least one displayed column is
76
+ * filterable (`enabled` or the column's `filterable`). Default `'menu'`.
77
+ */
78
+ mode?: 'menu' | 'row' | 'both';
79
+ /** Filter row: typing applies after this many ms (Enter applies at once). Default 300. */
80
+ rowDebounce?: number;
81
+ /** Filter row height in px. Default: `rowHeight`. */
82
+ rowHeight?: number;
83
+ }
84
+ /** Global editing settings, including adding and deleting rows. */
85
+ export interface EditConfig<TRow = any> {
86
+ /** Global editing flag, the default for every column's `editable`. Default `false`. */
87
+ enabled?: boolean;
88
+ /** `'cell'` edits one cell at a time; `'row'` edits all editable cells of a row together. Default `'cell'`. */
89
+ mode?: 'cell' | 'row';
90
+ /** What starts editing with the mouse. Enter/F2 always work on the focused cell. Default `'dblclick'`. */
91
+ trigger?: 'click' | 'dblclick' | 'manual';
92
+ /** Save when focus leaves the editor (not for the inline add row). Default `true`. */
93
+ commitOnBlur?: boolean;
94
+ /** Start in grid edit mode (every editable cell shows its editor). Default `false`. */
95
+ gridEditMode?: boolean;
96
+ /**
97
+ * Let users add rows: the + button of the action column. `addRow()` and `beginAddRow()` always work.
98
+ * Default `false`.
99
+ */
100
+ allowAdd?: boolean;
101
+ /**
102
+ * Let users delete rows: the delete button of the action column and the Delete key (selected rows, or the
103
+ * focused row). `deleteRow()` and the other delete methods always work. Default `false`.
104
+ */
105
+ allowDelete?: boolean;
106
+ /** Where the inline add row is shown and new rows are added: first or last in the data. Default `'top'`. */
107
+ addPosition?: 'top' | 'bottom';
108
+ /** Creates the initial object of every new row (for example with a generated key). Given values are applied on top. */
109
+ newRow?: () => Partial<TRow>;
110
+ /**
111
+ * Validates a whole row before it is added or updated (after the column validators), for rules that
112
+ * involve several fields. Return a message, messages by field, or nothing when the row is valid.
113
+ * For updates it receives a copy of the row with the changes applied.
114
+ */
115
+ rowValidator?: (row: TRow) => GridRowValidationResult;
116
+ /** Ask for confirmation before deleting from the UI or `requestDeleteRows()`. Default `true`. */
117
+ confirmDelete?: boolean;
118
+ /** A column pinned at the right with edit, delete and (in the header) add buttons. Default `false`. */
119
+ actionColumn?: boolean | ActionColumnConfig;
120
+ /**
121
+ * Batch editing: adds, updates and deletes are kept as pending changes (shown as new, modified and deleted
122
+ * rows) and the data is only changed by `saveChanges()`; `cancelChanges()` discards them. Default `false`.
123
+ */
124
+ batch?: boolean;
125
+ /** Batch mode: steps kept for undo (Ctrl/Cmd+Z) and redo (Ctrl/Cmd+Shift+Z, Ctrl+Y). Default 100. */
126
+ undoLimit?: number;
127
+ /** Batch mode: show the loading state while a save handler runs. Default `true`. */
128
+ loadingWhileSaving?: boolean;
129
+ /** Batch mode: a bar under the rows with the number of changes, undo, redo, discard and save. Default `true`. */
130
+ batchToolbar?: boolean;
131
+ /**
132
+ * Batch mode: persists the changes for the toolbar's Save button and `saveChanges()` without a handler
133
+ * (for example an HTTP call). Return a Promise or an Observable; throw or reject to keep the changes pending.
134
+ */
135
+ saveHandler?: (changes: GridChangeSet<TRow>) => unknown;
136
+ }
137
+ /** Global summary-row settings. */
138
+ export interface SummaryConfig {
139
+ /** Show the summary row. Default: shown when at least one column has a summary. */
140
+ enabled?: boolean;
141
+ /** `true` pins the summary row to the bottom of the grid; `false` shows it as a normal last row. Default `true`. */
142
+ sticky?: boolean;
143
+ /** Calculate over filtered rows or all rows. Default `'filtered'`. */
144
+ scope?: GridSummaryScope;
145
+ /** Show labels such as "Sum:" before values. Default `true`. */
146
+ showLabels?: boolean;
147
+ }
148
+ /** Loading-state settings. */
149
+ export interface LoadingConfig {
150
+ /** Enable the loading state. Default `true`. */
151
+ enabled?: boolean;
152
+ /** Use the custom loading template when one is provided. Default `true`. */
153
+ useCustomTemplate?: boolean;
154
+ /** Block interaction with the grid (only the grid) while loading. Default `true`. */
155
+ blockGrid?: boolean;
156
+ /** Message of the built-in loader. */
157
+ message?: string;
158
+ }
159
+ /** Empty-data ("No Data Found") settings. */
160
+ export interface EmptyStateConfig {
161
+ /** Enable the empty-data state. Default `true`. */
162
+ enabled?: boolean;
163
+ /** Show the custom empty template when one is provided; `false` uses the built-in one. Default `true`. */
164
+ useCustomTemplate?: boolean;
165
+ /** Also show the empty state when filters remove every row. Default `true`. */
166
+ showWhenFiltered?: boolean;
167
+ /** Message when the data array is empty. */
168
+ message?: string;
169
+ /** Message when filters removed every row. */
170
+ filteredMessage?: string;
171
+ }
172
+ /** Error-state settings. */
173
+ export interface ErrorStateConfig {
174
+ /** Enable the error state (shown when the `error` input or `api.setError()` is set). Default `true`. */
175
+ enabled?: boolean;
176
+ /** Show the custom error template when one is provided; `false` uses the built-in one. Default `true`. */
177
+ useCustomTemplate?: boolean;
178
+ /** Message used when the error has no message. */
179
+ message?: string;
180
+ }
181
+ /** Click and pointer event settings. */
182
+ export interface GridEventsConfig {
183
+ /**
184
+ * `'immediate'` (default): a click emits `cellClick`/`rowClick` at once; the second click of a double click
185
+ * emits nothing, so a double click is one click plus one double click.
186
+ * `'waitForDoubleClick'`: click events wait `doubleClickDelay` ms and are dropped when a double click follows.
187
+ * In that mode a click event can't cancel the built-in behaviour (it has already happened).
188
+ */
189
+ clickMode?: 'immediate' | 'waitForDoubleClick';
190
+ /** Wait time of `'waitForDoubleClick'`. Default 250 ms. */
191
+ doubleClickDelay?: number;
192
+ /** Suppress the browser's context menu on cells (`cellContextMenu` still fires). Default `false`. */
193
+ preventContextMenu?: boolean;
194
+ }
195
+ /** Templates set through configuration instead of `<ng-template>` directives. */
196
+ export interface TemplateConfig<TRow = any> {
197
+ /** Display templates per data type (used when a column has no own template). */
198
+ displayByType?: Partial<Record<GridDataType, GridTemplate<GridCellContext<TRow>>>>;
199
+ /** Edit templates per data type (used when a column has no own edit template). */
200
+ editByType?: Partial<Record<GridDataType, GridTemplate<GridEditContext<TRow>>>>;
201
+ /** Header template for every column without its own. */
202
+ header?: GridTemplate<GridHeaderContext<TRow>>;
203
+ /** Summary cell template for every column without its own. */
204
+ summary?: GridTemplate<GridSummaryCellContext<TRow>>;
205
+ loading?: GridTemplate<GridLoadingContext<TRow>>;
206
+ empty?: GridTemplate<GridEmptyContext<TRow>>;
207
+ error?: GridTemplate<GridErrorContext<TRow>>;
208
+ }
209
+ /** All user-facing text, for translation. */
210
+ export interface GridText {
211
+ loading: string;
212
+ noData: string;
213
+ noResults: string;
214
+ error: string;
215
+ apply: string;
216
+ cancel: string;
217
+ clear: string;
218
+ selectAll: string;
219
+ blanks: string;
220
+ search: string;
221
+ and: string;
222
+ or: string;
223
+ sortAscending: string;
224
+ sortDescending: string;
225
+ valuePlaceholder: string;
226
+ valueToPlaceholder: string;
227
+ valueListTruncated: string;
228
+ noMatchingValues: string;
229
+ booleanTrue: string;
230
+ booleanFalse: string;
231
+ /** Label of a row checkbox. */
232
+ selectRow: string;
233
+ /** Label of the header checkbox. */
234
+ selectAllRows: string;
235
+ /** Message of an empty `required` field. */
236
+ required: string;
237
+ /** Message when a new row has no primary-key value. */
238
+ keyRequired: string;
239
+ /** Message when a new row's primary key is already used. */
240
+ duplicateKey: string;
241
+ /** Delete confirmation for one row. */
242
+ deleteRowConfirm: string;
243
+ /** Delete confirmation for several rows; `{count}` is replaced by the number of rows. */
244
+ deleteRowsConfirm: string;
245
+ /** Confirm button of the delete confirmation. */
246
+ delete: string;
247
+ /** Labels of the action-column buttons. */
248
+ editRow: string;
249
+ deleteRow: string;
250
+ saveRow: string;
251
+ cancelRowEdit: string;
252
+ addRow: string;
253
+ /** Accessible name of the action column. */
254
+ actions: string;
255
+ /** Filter popup: clears this column's filter. */
256
+ clearFilter: string;
257
+ /** Filter popup: clears every column's filter. */
258
+ clearAllFilters: string;
259
+ addCondition: string;
260
+ removeCondition: string;
261
+ /** Header filter button; `{column}` is replaced by the header. */
262
+ filterColumn: string;
263
+ /** Header filter button of a filtered column. */
264
+ filteredColumn: string;
265
+ /** Filter row: placeholder of the inputs. */
266
+ filterPlaceholder: string;
267
+ /** Filter row: label of the operator button; `{operator}` is replaced by the operator. */
268
+ filterOperator: string;
269
+ /** Filter row: the "no filter" choice of boolean columns. */
270
+ allValues: string;
271
+ /** Action-column button of a deleted row (batch mode). */
272
+ restoreRow: string;
273
+ /** Batch toolbar: `{count}` is replaced by the number of changed rows. */
274
+ pendingChanges: string;
275
+ undo: string;
276
+ redo: string;
277
+ discardChanges: string;
278
+ saveChanges: string;
279
+ saving: string;
280
+ /** Batch toolbar after a failed save. */
281
+ saveFailed: string;
282
+ operators: Readonly<Record<string, string>>;
283
+ summaryLabels: Readonly<Record<GridSummaryType, string>>;
284
+ }
285
+ /** Grid configuration. Every section is optional; defaults are documented on each property. */
286
+ export interface GridConfig<TRow = any> {
287
+ /**
288
+ * Field (or dot path) whose value uniquely identifies each row, or a function returning the key.
289
+ * Selection, data refresh and add/update/delete use it. Without it, the row object is its identity.
290
+ */
291
+ primaryKey?: string | ((row: TRow) => GridRowKey);
292
+ /** What a data refresh keeps (filters, sort, selection, scroll position). */
293
+ dataRefresh?: DataRefreshConfig;
294
+ /** Row selection (single or multiple, click, checkbox and keyboard). */
295
+ selection?: SelectionConfig<TRow>;
296
+ /** Cell selection: a click or the arrow keys select one cell. Independent of `selection`. */
297
+ cellSelection?: CellSelectionConfig;
298
+ /** Click and pointer event behaviour. */
299
+ events?: GridEventsConfig;
300
+ /** Tooltips of cells, headers and summary cells (by default only for text that is cut off). */
301
+ tooltips?: TooltipConfig;
302
+ /** Row height in px (fixed, used by row virtualization). Default 36. */
303
+ rowHeight?: number;
304
+ /** Header height in px. Default 40. */
305
+ headerHeight?: number;
306
+ /** Summary row height in px. Default: `rowHeight`. */
307
+ summaryRowHeight?: number;
308
+ /** Defaults applied to every column (a column's own settings win). */
309
+ defaultColumn?: Partial<Omit<ColumnConfig<TRow>, 'field'>>;
310
+ /** Extra CSS class(es) per row. */
311
+ rowClass?: GridClassValue | ((row: TRow, rowIndex: number) => GridClassValue);
312
+ /** Inline styles per row. */
313
+ rowStyle?: (row: TRow, rowIndex: number) => GridStyleValue | null | undefined;
314
+ /** Alternate row background. Default `true`. */
315
+ stripedRows?: boolean;
316
+ /** Allow drag-resizing of columns (column `resizable` overrides). Default `true`. */
317
+ resizableColumns?: boolean;
318
+ /** Arrow-key cell navigation, Enter/F2 to edit, Escape to cancel. Default `true`. */
319
+ keyboardNavigation?: boolean;
320
+ /** Locale for number/date formatting and text sorting. Default: the browser locale. */
321
+ locale?: string;
322
+ /** Theme class suffix: `'light'` (default), `'dark'`, or your own (`infi-grid-theme-<name>`). */
323
+ theme?: string;
324
+ /** Accessible label of the grid. */
325
+ ariaLabel?: string;
326
+ virtualization?: VirtualizationConfig;
327
+ sorting?: SortConfig;
328
+ filtering?: FilterConfig;
329
+ editing?: EditConfig<TRow>;
330
+ summary?: SummaryConfig;
331
+ loading?: LoadingConfig;
332
+ emptyState?: EmptyStateConfig;
333
+ errorState?: ErrorStateConfig;
334
+ templates?: TemplateConfig<TRow>;
335
+ /** Override any user-facing text (translation). */
336
+ text?: Partial<Omit<GridText, 'operators' | 'summaryLabels'>> & {
337
+ operators?: Readonly<Record<string, string>>;
338
+ summaryLabels?: Partial<Record<GridSummaryType, string>>;
339
+ };
340
+ }
341
+ type Resolved<T> = {
342
+ readonly [K in keyof T]-?: Exclude<T[K], undefined>;
343
+ };
344
+ /** Grid configuration with every default filled in. Returned by `api.getConfig()`. */
345
+ export interface ResolvedGridConfig<TRow = any> {
346
+ readonly primaryKey: string | ((row: TRow) => GridRowKey) | null;
347
+ readonly dataRefresh: Resolved<DataRefreshConfig>;
348
+ readonly selection: Resolved<Omit<SelectionConfig<TRow>, 'rowSelectable'>> & {
349
+ readonly rowSelectable: ((row: TRow) => boolean) | null;
350
+ };
351
+ /** `activeRow` is false unless `enabled` is on. */
352
+ readonly cellSelection: Resolved<CellSelectionConfig>;
353
+ readonly events: Resolved<GridEventsConfig>;
354
+ readonly tooltips: Resolved<TooltipConfig>;
355
+ readonly rowHeight: number;
356
+ readonly headerHeight: number;
357
+ readonly summaryRowHeight: number;
358
+ readonly defaultColumn: Partial<Omit<ColumnConfig<TRow>, 'field'>>;
359
+ readonly rowClass: GridConfig<TRow>['rowClass'] | null;
360
+ readonly rowStyle: GridConfig<TRow>['rowStyle'] | null;
361
+ readonly stripedRows: boolean;
362
+ readonly resizableColumns: boolean;
363
+ readonly keyboardNavigation: boolean;
364
+ readonly locale: string | undefined;
365
+ readonly theme: string;
366
+ readonly ariaLabel: string;
367
+ readonly virtualization: Resolved<VirtualizationConfig>;
368
+ readonly sorting: Resolved<Omit<SortConfig, 'maxSortColumns'>> & {
369
+ readonly maxSortColumns: number;
370
+ };
371
+ readonly filtering: Resolved<Omit<FilterConfig, 'maxConditions'>> & {
372
+ readonly maxConditions: number;
373
+ };
374
+ readonly editing: Resolved<Omit<EditConfig<TRow>, 'newRow' | 'rowValidator' | 'actionColumn' | 'saveHandler'>> & {
375
+ readonly newRow: (() => Partial<TRow>) | null;
376
+ readonly rowValidator: ((row: TRow) => GridRowValidationResult) | null;
377
+ readonly saveHandler: ((changes: GridChangeSet<TRow>) => unknown) | null;
378
+ /** Null when there is no action column. */
379
+ readonly actionColumn: Resolved<ActionColumnConfig> | null;
380
+ };
381
+ readonly summary: Resolved<Omit<SummaryConfig, 'enabled'>> & {
382
+ readonly enabled: boolean | null;
383
+ };
384
+ readonly loading: Resolved<LoadingConfig>;
385
+ readonly emptyState: Resolved<EmptyStateConfig>;
386
+ readonly errorState: Resolved<ErrorStateConfig>;
387
+ readonly templates: TemplateConfig<TRow>;
388
+ readonly text: GridText;
389
+ }
390
+ export {};
@@ -0,0 +1,179 @@
1
+ import type { GridRowKey } from './data.types';
2
+ /** Where a new row goes in the data: first, last, or at a data index. */
3
+ export type GridAddPosition = 'top' | 'bottom' | number;
4
+ /** Options of `addRow()`. */
5
+ export interface GridAddRowOptions {
6
+ /** Default `editing.addPosition` (`'top'`). A number is an index in the data array. */
7
+ position?: GridAddPosition;
8
+ /** Scroll the new row into view. Default `true`. */
9
+ scroll?: boolean;
10
+ }
11
+ /** Options of `beginAddRow()`. */
12
+ export interface GridBeginAddRowOptions<TRow = any> {
13
+ /** Where the add row is shown and the row is added. Default `editing.addPosition`. */
14
+ position?: 'top' | 'bottom';
15
+ /** Initial values of the new row (applied after `editing.newRow` and before column defaults). */
16
+ values?: Partial<TRow>;
17
+ }
18
+ /**
19
+ * Why an add, update or delete was refused:
20
+ * - `'cancelled'`: a `rowAdding` / `rowUpdating` / `rowDeleting` handler, or the delete confirmation, cancelled it;
21
+ * - `'invalid'`: validation failed (`required`, a column `validator` or `editing.rowValidator`), see `errors`;
22
+ * - `'duplicateKey'`: another row already has this primary-key value;
23
+ * - `'missingKey'`: the new row has no primary-key value;
24
+ * - `'notFound'`: no row has this key;
25
+ * - `'readOnly'`: a changed field can't be written (a computed column without `valueSetter`);
26
+ * - `'primaryKeyChange'`: the update would change the row's primary key (keys are immutable);
27
+ * - `'busy'`: another delete confirmation is open.
28
+ */
29
+ export type GridCrudFailure = 'cancelled' | 'invalid' | 'duplicateKey' | 'missingKey' | 'notFound' | 'readOnly' | 'primaryKeyChange' | 'busy';
30
+ /** Result of `addRow()`, `updateRow()`, `deleteRow()` and the other CRUD methods. */
31
+ export interface GridCrudResult<TRow = any> {
32
+ ok: boolean;
33
+ /** Set when `ok` is false. */
34
+ reason?: GridCrudFailure;
35
+ /** Validation messages by field; `'$row'` holds row-level messages (`rowValidator`, function keys). */
36
+ errors?: Readonly<Record<string, string>>;
37
+ /** The added or updated row (the first deleted row for deletes). */
38
+ row?: TRow;
39
+ key?: GridRowKey;
40
+ /** Every deleted row. */
41
+ rows?: readonly TRow[];
42
+ keys?: readonly GridRowKey[];
43
+ }
44
+ /** What `editing.rowValidator` returns: a row-level message, messages by field, or nothing when valid. */
45
+ export type GridRowValidationResult = string | Readonly<Record<string, string | null | undefined>> | null | undefined;
46
+ /** Buttons of the action column (`editing.actionColumn`). */
47
+ export interface ActionColumnConfig {
48
+ /** ✎ edits the row (row mode); ✓ and ✕ save or cancel while editing. Default `true`. */
49
+ edit?: boolean;
50
+ /** 🗑 deletes the row (with the configured confirmation; in batch mode ↶ restores a deleted row). Default `editing.allowDelete`. */
51
+ delete?: boolean;
52
+ /** + in the header opens the inline add row. Default `editing.allowAdd`. */
53
+ add?: boolean;
54
+ /** Width in px. Default: fits the buttons. */
55
+ width?: number;
56
+ }
57
+ /** `(rowAdding)`: a row is about to be added. Set `cancel` to prevent it. */
58
+ export interface GridRowAddingEvent<TRow = any> {
59
+ /** The new row, with defaults applied. A handler may still change it (the key is checked again). */
60
+ row: TRow;
61
+ key: GridRowKey;
62
+ /** Index in the data array the row will get. */
63
+ position: number;
64
+ /** `'ui'`: the inline add row; `'api'`: `addRow()`. */
65
+ source: 'ui' | 'api';
66
+ cancel: boolean;
67
+ }
68
+ /** `(rowAdded)`: a row was added. */
69
+ export interface GridRowAddedEvent<TRow = any> {
70
+ row: TRow;
71
+ key: GridRowKey;
72
+ /** Index in the data array. */
73
+ position: number;
74
+ /** Batch mode: the add is pending until `saveChanges()`. */
75
+ pending: boolean;
76
+ source: 'ui' | 'api';
77
+ }
78
+ /** `(rowUpdating)`: a row is about to change. Set `cancel` to prevent it. */
79
+ export interface GridRowUpdatingEvent<TRow = any> {
80
+ /** The row, still unchanged. */
81
+ row: TRow;
82
+ key: GridRowKey;
83
+ /** Values before the change, by field. */
84
+ oldValues: Readonly<Record<string, unknown>>;
85
+ /** Values after the change, by field. */
86
+ newValues: Readonly<Record<string, unknown>>;
87
+ changedFields: readonly string[];
88
+ /** `'edit'`: an inline edit; `'api'`: `updateRow()`. */
89
+ source: 'edit' | 'api';
90
+ cancel: boolean;
91
+ }
92
+ /** `(rowUpdated)`: a row changed. */
93
+ export interface GridRowUpdatedEvent<TRow = any> {
94
+ /** The row (the same object, now changed). */
95
+ row: TRow;
96
+ /** A copy of the row as it was before the change (objects along the changed paths are copied too). */
97
+ oldRow: TRow;
98
+ key: GridRowKey;
99
+ oldValues: Readonly<Record<string, unknown>>;
100
+ newValues: Readonly<Record<string, unknown>>;
101
+ changedFields: readonly string[];
102
+ /** Batch mode: the change is pending until `saveChanges()`. */
103
+ pending: boolean;
104
+ source: 'edit' | 'api';
105
+ }
106
+ /** `(rowDeleting)`: rows are about to be deleted (after the confirmation, if any). Set `cancel` to prevent it. */
107
+ export interface GridRowDeletingEvent<TRow = any> {
108
+ rows: readonly TRow[];
109
+ keys: readonly GridRowKey[];
110
+ /** `'ui'`: the action column; `'keyboard'`: the Delete key; `'api'`: the API. */
111
+ source: 'ui' | 'api' | 'keyboard';
112
+ cancel: boolean;
113
+ }
114
+ /** `(rowDeleted)`: rows were deleted (once per operation). */
115
+ export interface GridRowDeletedEvent<TRow = any> {
116
+ /** The first deleted row (the only one for single deletes). */
117
+ row: TRow;
118
+ key: GridRowKey;
119
+ rows: readonly TRow[];
120
+ keys: readonly GridRowKey[];
121
+ /** Batch mode: the delete is pending until `saveChanges()`. */
122
+ pending: boolean;
123
+ source: 'ui' | 'api' | 'keyboard';
124
+ }
125
+ /** A row with pending changes (batch mode). */
126
+ export interface GridPendingUpdate<TRow = any> {
127
+ key: GridRowKey;
128
+ /** A copy of the row with the pending values applied (the data row is unchanged until saved). */
129
+ row: TRow;
130
+ /** The row in the data. */
131
+ original: TRow;
132
+ /** Pending values by field. */
133
+ changes: Readonly<Record<string, unknown>>;
134
+ /** Values in the data, by field. */
135
+ oldValues: Readonly<Record<string, unknown>>;
136
+ }
137
+ /** Pending changes of batch mode: what `saveChanges()` would apply. */
138
+ export interface GridChangeSet<TRow = any> {
139
+ /** New rows, in the order they were added. */
140
+ readonly added: readonly TRow[];
141
+ readonly addedKeys: readonly GridRowKey[];
142
+ /** Changed rows (rows that are also deleted are only in `deleted`). */
143
+ readonly updated: readonly GridPendingUpdate<TRow>[];
144
+ readonly updatedKeys: readonly GridRowKey[];
145
+ /** Rows to delete (as they are in the data). */
146
+ readonly deleted: readonly TRow[];
147
+ readonly deletedKeys: readonly GridRowKey[];
148
+ /** Number of rows with a change. */
149
+ readonly count: number;
150
+ }
151
+ /** Result of `saveChanges()`. The promise never rejects. */
152
+ export interface GridSaveResult<TRow = any> {
153
+ ok: boolean;
154
+ /**
155
+ * `'invalid'`: an open edit couldn't be committed; `'failed'`: the save handler threw or rejected (the
156
+ * changes stay pending); `'busy'`: a save is already running.
157
+ */
158
+ reason?: 'invalid' | 'failed' | 'busy';
159
+ /** What the save handler threw or rejected with. */
160
+ error?: unknown;
161
+ changes: GridChangeSet<TRow>;
162
+ }
163
+ /** `(changesSaveFailed)`: the save handler threw or rejected; nothing was applied. */
164
+ export interface GridSaveFailedEvent<TRow = any> {
165
+ error: unknown;
166
+ changes: GridChangeSet<TRow>;
167
+ }
168
+ /** `(pendingChange)`: the pending changes of batch mode changed (for Save / Undo buttons of your own). */
169
+ export interface GridPendingChangeEvent {
170
+ /** What changed them. */
171
+ action: 'add' | 'update' | 'delete' | 'restore' | 'undo' | 'redo' | 'save' | 'cancel' | 'refresh';
172
+ hasChanges: boolean;
173
+ /** Pending rows by kind. */
174
+ added: number;
175
+ updated: number;
176
+ deleted: number;
177
+ canUndo: boolean;
178
+ canRedo: boolean;
179
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Value that identifies a row: the result of the `primaryKey` field (or function).
3
+ * Keys are compared with `===` (SameValueZero); use a string for composite keys.
4
+ * Without a configured `primaryKey`, the row object itself is the key, so every key-based API
5
+ * also accepts row objects.
6
+ */
7
+ export type GridRowKey = string | number | bigint | object;
8
+ /** How a data refresh treats the current view state. */
9
+ export interface DataRefreshConfig {
10
+ /** Keep or clear the filters when the data is replaced or refreshed. Default `'keep'`. */
11
+ filter?: 'keep' | 'reset';
12
+ /** Keep or clear the sort. Default `'keep'`. */
13
+ sort?: 'keep' | 'reset';
14
+ /** Keep the selection (rows that still exist stay selected) or clear it. Default `'keep'`. */
15
+ selection?: 'keep' | 'reset';
16
+ /** Keep the scroll position or go back to the first row. Default `'keep'`. */
17
+ scroll?: 'keep' | 'top';
18
+ }
19
+ /** Per-call override of `config.dataRefresh`. */
20
+ export type GridRefreshOptions = DataRefreshConfig;
21
+ /** What a data refresh did. Returned by `setData()` / `refreshData()` and emitted by `(dataRefresh)`. */
22
+ export interface GridRefreshResult {
23
+ /** Rows in the data. */
24
+ rowCount: number;
25
+ /** Rows after filtering. */
26
+ displayedRowCount: number;
27
+ /** Selected keys removed because their rows no longer exist (or are now filtered out). */
28
+ removedSelectionKeys: readonly GridRowKey[];
29
+ filterReset: boolean;
30
+ sortReset: boolean;
31
+ }
32
+ /** Why the data was refreshed. */
33
+ export type GridDataRefreshReason = 'input' | 'setData' | 'refreshData' | 'crud' | 'save';
34
+ export interface GridDataRefreshEvent extends GridRefreshResult {
35
+ reason: GridDataRefreshReason;
36
+ }
37
+ export interface GridLoadingChangeEvent {
38
+ loading: boolean;
39
+ /** `'input'` for the `[loading]` binding, `'api'` for `setLoading()`. */
40
+ source: 'input' | 'api';
41
+ }