@kanunilabs/datagrid-react 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/index.cjs +3 -3
  2. package/dist/index.d.cts +257 -25
  3. package/dist/index.d.ts +257 -25
  4. package/dist/index.js +3 -3
  5. package/dist/styles.css +541 -1
  6. package/dist/themes/all.css +108 -0
  7. package/dist/themes/amber.css +3 -0
  8. package/dist/themes/aubergine.css +3 -0
  9. package/dist/themes/azure.css +3 -0
  10. package/dist/themes/burgundy.css +3 -0
  11. package/dist/themes/charcoal.css +3 -0
  12. package/dist/themes/contrast-dark.css +3 -0
  13. package/dist/themes/contrast-light.css +3 -0
  14. package/dist/themes/coral.css +3 -0
  15. package/dist/themes/corporate.css +3 -0
  16. package/dist/themes/deep-sea.css +3 -0
  17. package/dist/themes/editorial.css +3 -0
  18. package/dist/themes/ember.css +3 -0
  19. package/dist/themes/emerald.css +3 -0
  20. package/dist/themes/forest.css +3 -0
  21. package/dist/themes/glacier.css +3 -0
  22. package/dist/themes/graphite.css +3 -0
  23. package/dist/themes/indigo-night.css +3 -0
  24. package/dist/themes/indigo.css +3 -0
  25. package/dist/themes/ivory.css +3 -0
  26. package/dist/themes/lagoon.css +3 -0
  27. package/dist/themes/linen.css +3 -0
  28. package/dist/themes/midnight.css +3 -0
  29. package/dist/themes/mist.css +3 -0
  30. package/dist/themes/monochrome.css +3 -0
  31. package/dist/themes/onyx.css +3 -0
  32. package/dist/themes/orchid.css +3 -0
  33. package/dist/themes/porcelain.css +3 -0
  34. package/dist/themes/rose.css +3 -0
  35. package/dist/themes/sandstone.css +3 -0
  36. package/dist/themes/slate-night.css +3 -0
  37. package/dist/themes/slate.css +3 -0
  38. package/dist/themes/steel.css +3 -0
  39. package/dist/themes/stone.css +3 -0
  40. package/dist/themes/taupe.css +3 -0
  41. package/dist/themes/teal.css +3 -0
  42. package/dist/themes/terminal.css +3 -0
  43. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, RefObject } from 'react';
3
- import { GridRowData, DataGridController, StateStoringConfig, RowKey, RowNode, GridColumnDef, DataGridCoreConfig, FilterRenderContextBase, FilterNode, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, CardViewOptions, RowChange, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnModel, DataRowNode, ColSpanPlan, SummaryDef, ToolbarIconName, ColumnState, BusyPhase, GridDictionary, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel, CellRange, RangeSelectionEngine, ColumnSelectMode, EditMode, ValidationRule, CrudHandlers, EditingPermissions, NewRowPosition, EditingEngine, GridDataType, LookupItem, LookupMatchMode } from '@kanunilabs/datagrid-core';
3
+ import { GridRowData, DataGridController, GridDataType, RowKey, LookupItem, GridDictionary, StateStoringConfig, RowNode, GridColumnDef, DataGridCoreConfig, FilterRenderContextBase, FilterNode, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, CardViewOptions, EditMode, RowChange, RowStatusSource, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnModel, RowSaveStatus, DataRowNode, ColSpanPlan, SummaryDef, ToolbarIconName, ColumnState, BusyPhase, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel, CellRange, RangeSelectionEngine, ColumnSelectMode, EditingEngine, ValidationRule, CrudHandlers, EditingPermissions, NewRowPosition, RowEditSession, LookupMatchMode } from '@kanunilabs/datagrid-core';
4
4
  export { BusyChangedEvent, BusyPhase, ClientRowModel, ColumnLayout, ColumnLookup, ColumnModel, ColumnPin, ColumnRuntime, ColumnState, ColumnStateChangedEvent, ContentReadyEvent, CustomFilterOperator, CustomFilterOperatorId, DEFAULT_ROW_HEIGHT, DENSITY_ROW_HEIGHT, DataGridController, DataGridCoreConfig, DataRowNode, DataSource, FilterChangedEvent, FilterCondition, FilterGroupNode, FilterNode, FilterOperator, FocusedRowChangedEvent, GRID_COLOR_SCHEMES, GRID_PALETTES, GRID_THEMES, GridColorScheme, GridColumnDef, GridDataType, GridDensity, GridEventMap, GridPalette, GridPaletteName, GridRowData, GridStateStore, GridTheme, GridThemeName, GridViewState, GroupRowNode, GroupingConfig, HeaderBandCell, InferColumnsOptions, LoadOptions, LoadResult, LookupItem, NewRowPosition, RowDropPosition, RowKey, RowNode, SUMMARY_TYPE_LABEL, ScrollingConfig, SelectionDescriptor, SortChangedEvent, SortDescriptor, SortDirection, StateStoringConfig, SummaryDef, SummaryType, THEME_ROW_HEIGHT, ViewportChangedEvent, VirtualWindow, VirtualWindowEngine, allowedSummaryTypes, andFilters, attachStateStoring, bandDepth, bandPath, computeColumnLayout, computeHeaderBands, createRestDataSource, describeFilter, downloadBlob, fillText, filterInputFromNode, formatSummaryValue, humanizeField, importCsv, inferColumns, isDataRow, isDataSource, isFilterGroup, isGroupRow, isPackagedTheme, lookupLabel, moveRowInArray, parseCsv, parseFilterInput, sniffDelimiter, summaryKey, summaryLabel, summaryTypeLabels, themeClassName } from '@kanunilabs/datagrid-core';
5
5
 
6
6
  /** Formats an export menu can offer. */
@@ -20,6 +20,86 @@ interface ExportOutcome {
20
20
  */
21
21
  declare function runGridExport<TRow = GridRowData>(controller: DataGridController<TRow>, kind: ExportKind): Promise<ExportOutcome>;
22
22
 
23
+ /**
24
+ * Lookup items per column of the open row.
25
+ * `undefined` = not a lookup column · `null` = loading · array = ready.
26
+ */
27
+ type RowLookupMap = Record<string, readonly LookupItem[] | null | undefined>;
28
+ interface EditFormField<TRow = GridRowData> {
29
+ columnId: string;
30
+ label: string;
31
+ dataType: GridDataType | undefined;
32
+ def: ReactGridColumnDef<TRow> | undefined;
33
+ /** False for a column the permissions do not allow on this row. */
34
+ editable: boolean;
35
+ }
36
+ interface GridEditFormProps<TRow = GridRowData> {
37
+ rowKey: RowKey;
38
+ fields: readonly EditFormField<TRow>[];
39
+ /** Current (pending) value per column. */
40
+ getValue: (columnId: string) => unknown;
41
+ /** Validation message per column id; only invalid columns appear. */
42
+ errors: Record<string, string>;
43
+ /**
44
+ * Lookup combos per column (Enterprise). A column absent from the map gets
45
+ * no list; omitted entirely, no field is a combo.
46
+ */
47
+ lookups?: RowLookupMap;
48
+ /**
49
+ * Let a column's `renderEditor` draw its field (Enterprise). Default false:
50
+ * the field shows the value read-only instead.
51
+ */
52
+ customEditors?: boolean;
53
+ /** The row with pending edits applied — what a custom editor should read. */
54
+ row: TRow | undefined;
55
+ /** True while the save is in flight; the form goes read-only. */
56
+ saving: boolean;
57
+ /** Shown above the fields when the last save was rejected. */
58
+ saveError?: string | null;
59
+ isNew: boolean;
60
+ dark?: boolean;
61
+ /** Rendered as a modal dialog rather than inline. */
62
+ popup?: boolean;
63
+ /**
64
+ * Drawn INSIDE the grid, in the row flow (`mode: 'form'`, gap D5a).
65
+ *
66
+ * Only changes the chrome: a panel that already sits in a row slot needs no
67
+ * outer margin, drop shadow or rounded corners — those exist to lift a
68
+ * floating panel off the page, and here they would draw a second card
69
+ * inside the one the row already is.
70
+ */
71
+ inline?: boolean;
72
+ /**
73
+ * Reports the height the form WANTS, in px, once it is in the DOM.
74
+ *
75
+ * The in-grid form is given a slot measured in whole rows, so somebody has
76
+ * to decide how many. Measured here because this is where the DOM is, and
77
+ * measured through the scrolling field area — `scrollHeight` is the content,
78
+ * `clientHeight` the space it was given — so the answer does not depend on
79
+ * the slot already assigned. Reading the panel's own height instead would
80
+ * feed the current slot straight back in and never converge.
81
+ */
82
+ onNaturalHeight?: (px: number) => void;
83
+ labels?: Partial<EditFormLabels>;
84
+ onChange: (columnId: string, value: unknown) => void;
85
+ onSave: () => void;
86
+ onCancel: () => void;
87
+ }
88
+ interface EditFormLabels {
89
+ save: string;
90
+ cancel: string;
91
+ editTitle: string;
92
+ addTitle: string;
93
+ saving: string;
94
+ /** Hint under the buttons. `{key}` is replaced with Ctrl or ⌘. */
95
+ shortcut: string;
96
+ }
97
+ /** The captions in one language. */
98
+ declare function editFormLabels(t: GridDictionary): EditFormLabels;
99
+ /** English, kept as the constant this package already exported. */
100
+ declare const DEFAULT_EDIT_FORM_LABELS: EditFormLabels;
101
+ declare function GridEditForm<TRow = GridRowData>({ rowKey, fields, getValue, errors, lookups, customEditors, row, saving, saveError, isNew, dark, popup, inline, onNaturalHeight, labels: labelOverrides, onChange, onSave, onCancel, }: GridEditFormProps<TRow>): react.JSX.Element;
102
+
23
103
  declare function useStateStoring<TRow = GridRowData>(controller: DataGridController<TRow>, config: StateStoringConfig | undefined): void;
24
104
 
25
105
  interface PrintLayoutOptions {
@@ -407,20 +487,43 @@ interface RowMenuContext<TRow = GridRowData> {
407
487
  /** Selected row keys at the moment the menu opened. */
408
488
  selectedKeys: RowKey[];
409
489
  }
410
- /** Single-cell editing in the Community grid — see `DataGridProps.editing`. */
490
+ /** Editing in the Community grid — see `DataGridProps.editing`. */
411
491
  interface DataGridEditingOptions<TRow = GridRowData> {
412
492
  /** Default true once `editing` is given. */
413
493
  enabled?: boolean;
414
494
  /**
415
- * Always `'cell'` here — accepted so the same object works in both editions
416
- * (`EnterpriseDataGrid` defaults to `'batch'` and adds the other modes).
495
+ * How edits are made and saved. Default `'cell'` here (`EnterpriseDataGrid`
496
+ * defaults to `'batch'`); all five are free since 2026-10-16.
497
+ *
498
+ * - `'cell'` — one cell at a time, saved on commit.
499
+ * - `'batch'` — edits collect (marked with a corner triangle) and are saved
500
+ * together from the Save button above the grid, or dropped with Cancel.
501
+ * - `'row'` — double-click (or "Edit row…" in the row menu) opens the whole
502
+ * row in place; Enter or Save saves it, Escape or Cancel drops it.
503
+ * - `'form'` — the row opens as a form under it, in the grid.
504
+ * - `'popup'` — the row opens as a form in a dialog over the grid.
505
+ *
506
+ * In every mode but `'cell'` the grid does not change your data itself:
507
+ * `onSave` receives the changes and the app writes them (then updates
508
+ * `dataSource`).
417
509
  */
418
- mode?: 'cell';
510
+ mode?: EditMode;
419
511
  /**
420
- * Persist one committed cell. Called after the value is written to the row;
421
- * a rejected promise is reported in the grid and the edit stays visible.
512
+ * Persist changes: one committed cell in `'cell'` mode, every pending row in
513
+ * `'batch'`, the open row in `'row'`/`'form'`/`'popup'`. A rejected promise is
514
+ * reported in the grid and the edits stay.
422
515
  */
423
516
  onSave?: (changes: RowChange<TRow>[]) => Promise<void> | void;
517
+ /**
518
+ * Wording for the form/popup editor (`mode: 'form' | 'popup'`) — the buttons,
519
+ * the title and the shortcut hint.
520
+ */
521
+ formLabels?: Partial<EditFormLabels>;
522
+ /**
523
+ * Starting height in px for the in-grid form (`mode: 'form'`), before it has
524
+ * been measured. Only worth setting to stop the one-frame resize on open.
525
+ */
526
+ formHeight?: number;
424
527
  /** Typing a printable character on a focused cell opens its editor. Default true. */
425
528
  editOnKeyPress?: boolean;
426
529
  /** Tab moves between cells inside the grid instead of leaving it. Default true. */
@@ -823,25 +926,36 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
823
926
  */
824
927
  onReady?: (controller: DataGridController<TRow>) => void;
825
928
  /**
826
- * Edit a cell in place — free in Community since 2026-10-12.
929
+ * Edit data in the grid — single cells free since 2026-10-12, batch, row,
930
+ * form and popup editing free since 2026-10-16 (owner decision).
827
931
  *
828
932
  * Off unless this object is given (`editing={{ onSave }}`); `enabled: false`
829
- * turns it off again. Double-click, F2 or typing opens the editor on
830
- * an editable column; Enter commits and moves down, Tab moves to the next
831
- * editable cell, Esc cancels. Each committed cell is written to its row and
832
- * passed to `onSave` — one call per edit — and `cellValueChanged` fires.
933
+ * turns it off again. In the default `'cell'` mode double-click, F2 or
934
+ * typing opens the editor on an editable column; Enter commits and moves
935
+ * down, Tab moves to the next editable cell, Esc cancels. Each committed cell
936
+ * is written to its row and passed to `onSave` — one call per edit — and
937
+ * `cellValueChanged` fires. `mode` switches to collecting edits (`'batch'`,
938
+ * with a Save / Cancel strip above the grid) or to editing a whole row at a
939
+ * time (`'row'`, `'form'`, `'popup'` — opened by double-click or "Edit row…"
940
+ * in the row menu); see `DataGridEditingOptions.mode`.
833
941
  * A column with `editable: false`, a `lookup` or a `renderEditor` stays
834
- * read-only here.
942
+ * read-only here, in every mode.
835
943
  *
836
- * Batch, row, form and popup modes, validation rules, add/delete,
837
- * per-row permissions, lookup and custom editors, undo/redo, range
838
- * selection, fill and paste are `EnterpriseDataGrid`.
944
+ * Validation rules, `crud` handlers, adding and deleting rows, per-row
945
+ * permissions, lookup and custom editors, the command column, undo/redo,
946
+ * range selection, fill and paste are `EnterpriseDataGrid`.
839
947
  */
840
948
  editing?: DataGridEditingOptions<TRow>;
841
949
  /** Replace a cell's content (e.g. with an editor). Return undefined for default. */
842
950
  renderCellContent?: (ctx: CellSlotContext<TRow>) => ReactNode | undefined;
843
951
  /** Extra class names per cell (dirty marker, range highlight, invalid). */
844
952
  getCellClassName?: (ctx: CellSlotContext<TRow>) => string | undefined;
953
+ /**
954
+ * Where `rowStatus` reads each row's save state — `EnterpriseDataGrid`'s
955
+ * editing engine. With this grid's own `editing` on, its engine answers and
956
+ * this is not asked.
957
+ */
958
+ rowStatusSource?: RowStatusSource | null;
845
959
  /** Absolutely-positioned layer over the viewport (fill handle, watermark). */
846
960
  renderOverlay?: () => ReactNode;
847
961
  /** Pointer down on a cell, with the view coordinates the range engine needs. */
@@ -888,8 +1002,9 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
888
1002
  renderDetail?: (row: TRow) => ReactNode;
889
1003
  /**
890
1004
  * Body of the in-grid edit form (`mode: 'form'`), rendered in the row flow
891
- * under the record it edits. Set by `EnterpriseDataGrid`; the form's position
892
- * and height come from `controller.setEditFormRow`.
1005
+ * under the record it edits. Set by `EnterpriseDataGrid`; the free grid's own
1006
+ * `editing.mode: 'form'` fills it when this is left empty. The form's
1007
+ * position and height come from `controller.setEditFormRow`.
893
1008
  */
894
1009
  renderEditForm?: (rowKey: RowKey, row: TRow | undefined) => ReactNode;
895
1010
  }
@@ -928,6 +1043,8 @@ interface GridHeaderProps<TRow = GridRowData> {
928
1043
  /** Leading expander column for master-detail (Enterprise). */
929
1044
  detailColumn?: boolean;
930
1045
  /** Leading row-number column (gap analysis P3.5). */
1046
+ /** `rowStatus.icons`: the leading status column is showing. */
1047
+ statusColumn?: boolean;
931
1048
  rowNumberColumn?: boolean;
932
1049
  /** What the row-number column's header shows. Defaults to `#`. */
933
1050
  rowNumberHeader?: React.ReactNode;
@@ -975,7 +1092,7 @@ interface GridHeaderProps<TRow = GridRowData> {
975
1092
  /** Replace a header's label (the Enterprise rename box, G-CORE-06). Undefined = the label. */
976
1093
  renderHeaderLabel?: (columnId: string) => React.ReactNode | undefined;
977
1094
  }
978
- declare function GridHeaderImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, sort, sortable, onSort, headerFilter, filteredColumns, onOpenFilter, filterIconMode, checkboxColumn, detailColumn, rowNumberColumn, rowNumberHeader, selectAllState, selectAllDisabled, onToggleSelectAll, draggable, reorderable, onReorder, resizable, onResize, onAutoFit, onHeaderContextMenu, groupLevels, onHeaderClick, getHeaderClassName, renderHeaderLabel, }: GridHeaderProps<TRow>): react.JSX.Element;
1095
+ declare function GridHeaderImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, sort, sortable, onSort, headerFilter, filteredColumns, onOpenFilter, filterIconMode, checkboxColumn, detailColumn, statusColumn, rowNumberColumn, rowNumberHeader, selectAllState, selectAllDisabled, onToggleSelectAll, draggable, reorderable, onReorder, resizable, onResize, onAutoFit, onHeaderContextMenu, groupLevels, onHeaderClick, getHeaderClassName, renderHeaderLabel, }: GridHeaderProps<TRow>): react.JSX.Element;
979
1096
  declare const GridHeader: typeof GridHeaderImpl;
980
1097
 
981
1098
  /**
@@ -995,6 +1112,8 @@ interface GridHeaderBandsProps<TRow = GridRowData> {
995
1112
  checkboxColumn?: boolean;
996
1113
  detailColumn?: boolean;
997
1114
  /** Leading row-number column (gap analysis P3.5). */
1115
+ /** `rowStatus.icons`: the leading status column is showing. */
1116
+ statusColumn?: boolean;
998
1117
  rowNumberColumn?: boolean;
999
1118
  /** Height of one band row, in px. Defaults to `BAND_ROW_HEIGHT`. */
1000
1119
  rowHeight?: number;
@@ -1014,7 +1133,7 @@ interface GridHeaderBandsProps<TRow = GridRowData> {
1014
1133
  };
1015
1134
  };
1016
1135
  }
1017
- declare function GridHeaderBandsImpl<TRow = GridRowData>({ layout, centerColumns, leadingSpacer, trailingSpacer, depth, checkboxColumn, detailColumn, rowNumberColumn, rowHeight, bandFold, }: GridHeaderBandsProps<TRow>): react.JSX.Element | null;
1136
+ declare function GridHeaderBandsImpl<TRow = GridRowData>({ layout, centerColumns, leadingSpacer, trailingSpacer, depth, checkboxColumn, detailColumn, statusColumn, rowNumberColumn, rowHeight, bandFold, }: GridHeaderBandsProps<TRow>): react.JSX.Element | null;
1018
1137
  declare const GridHeaderBands: typeof GridHeaderBandsImpl;
1019
1138
 
1020
1139
  interface GridRowProps<TRow = GridRowData> {
@@ -1090,6 +1209,19 @@ interface GridRowProps<TRow = GridRowData> {
1090
1209
  rowDrag?: RowDragHandlers;
1091
1210
  /** Which edge to draw the drop line on, or null. */
1092
1211
  dropSide?: 'before' | 'after' | null;
1212
+ /**
1213
+ * `rowStatus.messages`: the content of a message row (a refused save's
1214
+ * reason and its buttons), for the parent row's key.
1215
+ */
1216
+ renderRowMessage?: (rowKey: RowKey, row: TRow) => React.ReactNode;
1217
+ /** `rowStatus.icons`: the leading status column is showing. */
1218
+ statusColumn?: boolean;
1219
+ /** `rowStatus`: this row's save state, when it has one. */
1220
+ rowStatus?: RowSaveStatus;
1221
+ /** The words a screen reader hears for `rowStatus` (`aria-description`). */
1222
+ rowStatusText?: string;
1223
+ /** `rowStatus.tint`: wash the whole row, not only the marker. */
1224
+ rowStatusTint?: boolean;
1093
1225
  /** Renders the leading checkbox cell. */
1094
1226
  checkboxColumn: boolean;
1095
1227
  /** Renders the leading row-number cell (gap analysis P3.5). */
@@ -1217,7 +1349,7 @@ interface GridRowProps<TRow = GridRowData> {
1217
1349
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
1218
1350
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
1219
1351
  }
1220
- declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, ariaSelectable, selectable, groupSelection, onToggleGroupSelect, groupDisplay, focusedColumnId, rowFocused, renderRow, checkboxColumn, rowNumberColumn, rowNumber, getNote, getSpan, resolveColSpans, findKind, headerRowCount, onRowClick, onRowMouseDown, onRowDoubleClick, onToggleSelect, onCellMouseDown, onRowContextMenu, searchNeedle, onToggleGroup, summaryDefs, detailColumn, detailExpanded, onToggleDetail, onToggleTreeRow, renderDetail, renderEditForm, renderCellContent, getCellClassName, onCellPointerDown, onCellPointerEnter, onCellDoubleClick, rowDrag, dropSide, height, }: GridRowProps<TRow>): react.JSX.Element | null;
1352
+ declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, ariaSelectable, selectable, groupSelection, onToggleGroupSelect, groupDisplay, focusedColumnId, rowFocused, renderRow, checkboxColumn, statusColumn, rowNumberColumn, rowNumber, getNote, getSpan, resolveColSpans, findKind, headerRowCount, onRowClick, onRowMouseDown, onRowDoubleClick, onToggleSelect, onCellMouseDown, onRowContextMenu, searchNeedle, onToggleGroup, summaryDefs, detailColumn, detailExpanded, onToggleDetail, onToggleTreeRow, renderDetail, renderEditForm, renderRowMessage, renderCellContent, getCellClassName, onCellPointerDown, onCellPointerEnter, onCellDoubleClick, rowDrag, dropSide, rowStatus, rowStatusText, rowStatusTint, height, }: GridRowProps<TRow>): react.JSX.Element | null;
1221
1353
  declare const GridRow: typeof GridRowImpl;
1222
1354
 
1223
1355
  interface GridFilterRowProps<TRow = GridRowData> {
@@ -1244,6 +1376,8 @@ interface GridFilterRowProps<TRow = GridRowData> {
1244
1376
  checkboxColumn?: boolean;
1245
1377
  detailColumn?: boolean;
1246
1378
  /** Leading row-number column (gap analysis P3.5). */
1379
+ /** `rowStatus.icons`: the leading status column is showing. */
1380
+ statusColumn?: boolean;
1247
1381
  rowNumberColumn?: boolean;
1248
1382
  placeholder?: string;
1249
1383
  onChange: (columnId: string, raw: string) => void;
@@ -1308,7 +1442,7 @@ interface FilterInputSyncProbe {
1308
1442
  * re-render entirely.
1309
1443
  */
1310
1444
  declare function reconcileFilterInputs(prev: Record<string, string>, probe: FilterInputSyncProbe, columnIds?: readonly string[]): Record<string, string>;
1311
- declare function GridFilterRowImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, values, checkboxColumn, detailColumn, rowNumberColumn, placeholder, onChange, onCommit, periodSuggestions, periodListId, operators, onOperatorChange, renderCustom, }: GridFilterRowProps<TRow>): react.JSX.Element;
1445
+ declare function GridFilterRowImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, values, checkboxColumn, detailColumn, statusColumn, rowNumberColumn, placeholder, onChange, onCommit, periodSuggestions, periodListId, operators, onOperatorChange, renderCustom, }: GridFilterRowProps<TRow>): react.JSX.Element;
1312
1446
  declare const GridFilterRow: typeof GridFilterRowImpl;
1313
1447
 
1314
1448
  interface DistinctEntry {
@@ -1421,6 +1555,8 @@ interface GridFooterRowProps<TRow = GridRowData> {
1421
1555
  checkboxColumn?: boolean;
1422
1556
  detailColumn?: boolean;
1423
1557
  /** Leading row-number column (gap analysis P3.5). */
1558
+ /** `rowStatus.icons`: the leading status column is showing. */
1559
+ statusColumn?: boolean;
1424
1560
  rowNumberColumn?: boolean;
1425
1561
  /** Opens the aggregation menu for a column. */
1426
1562
  onPickSummary?: (columnId: string, event: React.MouseEvent) => void;
@@ -1437,7 +1573,7 @@ interface GridFooterRowProps<TRow = GridRowData> {
1437
1573
  /** Header-height rows between this row and its edge. See GridPinnedRows. */
1438
1574
  headerRowsBetween?: number;
1439
1575
  }
1440
- declare function GridFooterRowImpl<TRow = GridRowData>({ layout, centerColumns, leadingSpacer, trailingSpacer, defs, values, checkboxColumn, detailColumn, rowNumberColumn, onPickSummary, emptyHint, position, bandOffset, headerRowsBetween, }: GridFooterRowProps<TRow>): react.JSX.Element;
1576
+ declare function GridFooterRowImpl<TRow = GridRowData>({ layout, centerColumns, leadingSpacer, trailingSpacer, defs, values, checkboxColumn, detailColumn, statusColumn, rowNumberColumn, onPickSummary, emptyHint, position, bandOffset, headerRowsBetween, }: GridFooterRowProps<TRow>): react.JSX.Element;
1441
1577
  declare const GridFooterRow: typeof GridFooterRowImpl;
1442
1578
 
1443
1579
  interface GridFilterPanelProps<TRow = GridRowData> {
@@ -1775,6 +1911,8 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1775
1911
  checkboxColumn?: boolean;
1776
1912
  detailColumn?: boolean;
1777
1913
  /** Leading row-number column (gap analysis P3.5). */
1914
+ /** `rowStatus.icons`: the leading status column is showing. */
1915
+ statusColumn?: boolean;
1778
1916
  rowNumberColumn?: boolean;
1779
1917
  rowHeight: number;
1780
1918
  /** Pixels of BAND rows above. Zero on a grid without column bands. */
@@ -1799,7 +1937,7 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1799
1937
  */
1800
1938
  ariaRowBase: number;
1801
1939
  }
1802
- declare function GridPinnedRowsImpl<TRow = GridRowData>({ gridId, side, rows, rowKeys, onUserRowContextMenu, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, checkboxColumn, detailColumn, rowNumberColumn, rowHeight, bandOffset, headerRowsBetween, ariaRowBase, }: GridPinnedRowsProps<TRow>): react.JSX.Element | null;
1940
+ declare function GridPinnedRowsImpl<TRow = GridRowData>({ gridId, side, rows, rowKeys, onUserRowContextMenu, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, checkboxColumn, detailColumn, statusColumn, rowNumberColumn, rowHeight, bandOffset, headerRowsBetween, ariaRowBase, }: GridPinnedRowsProps<TRow>): react.JSX.Element | null;
1803
1941
  declare const GridPinnedRows: typeof GridPinnedRowsImpl;
1804
1942
 
1805
1943
  type UseDataGridOptions<TRow = GridRowData> = DataGridCoreConfig<TRow>;
@@ -1943,6 +2081,12 @@ interface UseGridEditingOptions<TRow = GridRowData> {
1943
2081
  confirmDeleteMessage?: string;
1944
2082
  /** Disables editing entirely (`editing={{ enabled: false }}`). */
1945
2083
  enabled?: boolean;
2084
+ /**
2085
+ * How long a row reads `'saved'` after its save (`engine.getRowStatus`),
2086
+ * in ms; 0 never shows it. Left out, the engine's default (1500) stays.
2087
+ * The grids pass `rowStatus.savedDuration`, or 0 when `rowStatus` is off.
2088
+ */
2089
+ savedDuration?: number;
1946
2090
  /**
1947
2091
  * `editing.range` — the rectangle, the fill handle and the clipboard
1948
2092
  * gestures (cut / paste). Default true. Off means Ctrl+X and Ctrl+V are left
@@ -2101,6 +2245,94 @@ interface UseGridEditingResult<TRow = GridRowData> {
2101
2245
  }
2102
2246
  declare function useGridEditing<TRow = GridRowData>(options: UseGridEditingOptions<TRow>): UseGridEditingResult<TRow>;
2103
2247
 
2248
+ interface UseEditModesOptions<TRow = GridRowData> {
2249
+ controller: DataGridController<TRow> | null;
2250
+ /** The editing layer the modes draw (`useGridEditing`'s result). */
2251
+ editing: UseGridEditingResult<TRow>;
2252
+ /** The mode in force. */
2253
+ mode: EditMode;
2254
+ /** Editing is on AND drawn (not paused behind cards). */
2255
+ active: boolean;
2256
+ /** The element the row editors are looked up in, to focus one on open. */
2257
+ rootRef: RefObject<HTMLElement | null>;
2258
+ /** The grid's row height in px — a form re-measure smaller than a row is noise. */
2259
+ rowHeight: number;
2260
+ /** Wording for the form/popup editor. */
2261
+ formLabels?: Partial<EditFormLabels>;
2262
+ /** Starting height in px for the in-grid form, before it is measured. */
2263
+ formHeight?: number;
2264
+ dark?: boolean;
2265
+ /** Lookup combos for the open row (Enterprise). */
2266
+ rowLookups?: RowLookupMap;
2267
+ /** A column's `renderEditor` draws its form field (Enterprise). */
2268
+ customEditors?: boolean;
2269
+ /** Columns that are not fields of the record (the command column). */
2270
+ isFormColumn?: (columnId: string) => boolean;
2271
+ /**
2272
+ * Offer the batch Save/Cancel pair in the strip. Default true. The
2273
+ * Enterprise grid shows it only for an explicit `mode: 'batch'` (its
2274
+ * default batch mode saves from the command column) and passes that here.
2275
+ */
2276
+ batchBar?: boolean;
2277
+ }
2278
+ interface EditModes<TRow = GridRowData> {
2279
+ /** A row mode (row / form / popup) is in force and drawn. */
2280
+ rowModeActive: boolean;
2281
+ /** The open row, in a row mode; null otherwise. */
2282
+ rowSession: RowEditSession | null;
2283
+ /** True for the row drawn as editors in `row` mode. */
2284
+ isRowEditing: (rowKey: RowKey) => boolean;
2285
+ /** A value drawn the way the grid draws it (renderCell → lookup → formatter → date). */
2286
+ defaultContent: (ctx: CellSlotContext<TRow>, value: unknown) => ReactNode;
2287
+ /** The open row's cell in `row` mode: its editor, or its value when read-only. Undefined otherwise. */
2288
+ renderRowCell: (ctx: CellSlotContext<TRow>) => ReactNode | undefined;
2289
+ /** A cell's PENDING value (batch), drawn; undefined when it has none. */
2290
+ renderPending: (ctx: CellSlotContext<TRow>) => ReactNode | undefined;
2291
+ /** The grid's `renderEditForm` slot in `form` mode; undefined otherwise. */
2292
+ renderEditForm: ((rowKey: RowKey) => ReactNode) | undefined;
2293
+ /** The popup form (`popup` mode, a row open), or null. Unportaled. */
2294
+ popup: ReactNode;
2295
+ /** The row strip (`row` mode) and the batch Save/Cancel, or null when there is nothing to show. */
2296
+ bar: ReactNode;
2297
+ /** What `data-row-session` on the grid's wrapper says, for the pointer lock. */
2298
+ rowSessionAttr: 'form' | 'popup' | undefined;
2299
+ /** "Edit row…" for the row menu, or null when no row can be opened now. */
2300
+ editRowMenuItem: <TContext>(rowKey: RowKey) => GridMenuItem<TContext> | null;
2301
+ /** Open a row (double-click in a row mode). False when not a row mode. */
2302
+ openRow: (rowKey: RowKey) => boolean;
2303
+ }
2304
+ /**
2305
+ * The columns a record's form offers, in the grid's own order.
2306
+ *
2307
+ * Derived from the LAYOUT rather than the raw column list, so a column the
2308
+ * user hid stays out of the form too — offering a field nobody chose to see,
2309
+ * and saving a value from it, is an invisible change. The grid's own columns
2310
+ * (selection, the group column, row numbers) are never fields: with grouping
2311
+ * shown as a column the form offered an empty, disabled "Region › Country"
2312
+ * (pre-release review, 2026-10-16; the plain-JavaScript form already left
2313
+ * them out).
2314
+ */
2315
+ declare function editFormColumnIds<TRow>(controller: DataGridController<TRow> | null, isFormColumn?: (columnId: string) => boolean): string[];
2316
+ declare function useEditModes<TRow = GridRowData>({ controller, editing, mode, active, rootRef, rowHeight, formLabels, formHeight: formHeightOption, dark, rowLookups, customEditors, isFormColumn, batchBar, }: UseEditModesOptions<TRow>): EditModes<TRow>;
2317
+
2318
+ interface GridRowEditorProps<TRow = GridRowData> {
2319
+ controller: DataGridController<TRow>;
2320
+ engine: EditingEngine<TRow>;
2321
+ columnId: string;
2322
+ /** This field's validation message, or null. */
2323
+ message: string | null;
2324
+ /** True while the row's save is in flight; the fields go read-only. */
2325
+ saving: boolean;
2326
+ /**
2327
+ * The column's lookup items (Enterprise) — `null` while loading. Undefined
2328
+ * draws the plain input.
2329
+ */
2330
+ lookupOptions?: readonly LookupItem[] | null;
2331
+ onSave: () => void;
2332
+ onCancel: () => void;
2333
+ }
2334
+ declare function GridRowEditor<TRow = GridRowData>({ controller, engine, columnId, message, saving, lookupOptions, onSave, onCancel, }: GridRowEditorProps<TRow>): react.JSX.Element;
2335
+
2104
2336
  interface GridCellEditorProps {
2105
2337
  value: unknown;
2106
2338
  dataType: GridDataType | undefined;
@@ -2214,4 +2446,4 @@ interface GridDialogProps {
2214
2446
  }
2215
2447
  declare function GridDialog({ open, title, message, cancelLabel, confirmLabel, danger, dark, onConfirm, onCancel, }: GridDialogProps): react.ReactPortal | null;
2216
2448
 
2217
- export { type AlignedGridsApi, BAND_ROW_HEIGHT, type BatchSaveError, type CellMenuOptions, type CellRenderContext, type CellSlotContext, type CellTooltipOptions, DEFAULT_HEADER_MENU_LABELS, DataGrid, type DataGridProps, type DistinctEntry, type EditorRenderContext, type ExportOutcome, type FilterRenderContext, GridCellEditor, type GridCellEditorProps, GridColumnChooser, type GridColumnChooserProps, GridContextMenu, type GridContextMenuProps, GridDateEditor, type GridDateEditorProps, GridDialog, type GridDialogProps, GridFilterPanel, type GridFilterPanelProps, GridFilterRow, type GridFilterRowProps, GridFooterRow, type GridFooterRowProps, GridGroupPanel, type GridGroupPanelProps, GridHeader, GridHeaderBands, type GridHeaderBandsProps, GridHeaderFilterPopup, type GridHeaderFilterPopupProps, type GridHeaderProps, GridLoadingOverlay, type GridLoadingOverlayProps, GridLookupEditor, type GridLookupEditorProps, type GridMenuItem, GridNoteEditor, type GridNotesConfig, GridPager, type GridPagerProps, GridPinnedRows, type GridPinnedRowsProps, GridPopupPanel, type GridPopupPanelProps, GridPortal, type GridPortalProps, GridRow, type GridRowProps, GridSummaryBar, type GridSummaryBarProps, GridSurfaceProvider, type GridSurfaceProviderProps, GridTextProvider, type GridTextProviderProps, GridToolbar, type GridToolbarProps, GridTooltip, type GridTooltipConfig, type GridTooltipProps, type HeaderMenuContext, type HeaderMenuDeps, type HeaderMenuLabels, type HeaderRenderContext, type NoteCellContext, PRINT_MAX_ROWS, type PendingDelete, type PrintLayoutOptions, type PrintLayoutState, ROW_DRAG_MIME, type RangeApi, type ReactColumnRuntime, type ReactGridColumnDef, type RowDragConfig, type RowDragHandlers, type RowDragPayload, type RowDropEvent, type RowMenuContext, type RowReorderEvent, type RowTemplateContext, SHORTCUT_COPY, SHORTCUT_CUT, SHORTCUT_PASTE, type SelectionStats, ToolbarIcon, type TooltipState, type UseDataGridOptions, type UseDataGridResult, type UseGridEditingOptions, type UseGridEditingResult, buildCellMenuItems, buildHeaderMenu, copyToClipboard, headerMenuLabels, matchOptions, measureBestFitWidth, reconcileFilterInputs, runGridExport, useAlignedGrids, useAnchoredPopup, useCellTooltip, useDataGrid, useGridChartBoxData, useGridChartData, useGridChartXYData, useGridEditing, useGridSurfaceClass, useGridText, usePrintLayout, useRowDrag, useStateStoring, writeClipboardText };
2449
+ export { type AlignedGridsApi, BAND_ROW_HEIGHT, type BatchSaveError, type CellMenuOptions, type CellRenderContext, type CellSlotContext, type CellTooltipOptions, DEFAULT_EDIT_FORM_LABELS, DEFAULT_HEADER_MENU_LABELS, DataGrid, type DataGridProps, type DistinctEntry, type EditFormField, type EditFormLabels, type EditModes, type EditorRenderContext, type ExportOutcome, type FilterRenderContext, GridCellEditor, type GridCellEditorProps, GridColumnChooser, type GridColumnChooserProps, GridContextMenu, type GridContextMenuProps, GridDateEditor, type GridDateEditorProps, GridDialog, type GridDialogProps, GridEditForm, type GridEditFormProps, GridFilterPanel, type GridFilterPanelProps, GridFilterRow, type GridFilterRowProps, GridFooterRow, type GridFooterRowProps, GridGroupPanel, type GridGroupPanelProps, GridHeader, GridHeaderBands, type GridHeaderBandsProps, GridHeaderFilterPopup, type GridHeaderFilterPopupProps, type GridHeaderProps, GridLoadingOverlay, type GridLoadingOverlayProps, GridLookupEditor, type GridLookupEditorProps, type GridMenuItem, GridNoteEditor, type GridNotesConfig, GridPager, type GridPagerProps, GridPinnedRows, type GridPinnedRowsProps, GridPopupPanel, type GridPopupPanelProps, GridPortal, type GridPortalProps, GridRow, GridRowEditor, type GridRowEditorProps, type GridRowProps, GridSummaryBar, type GridSummaryBarProps, GridSurfaceProvider, type GridSurfaceProviderProps, GridTextProvider, type GridTextProviderProps, GridToolbar, type GridToolbarProps, GridTooltip, type GridTooltipConfig, type GridTooltipProps, type HeaderMenuContext, type HeaderMenuDeps, type HeaderMenuLabels, type HeaderRenderContext, type NoteCellContext, PRINT_MAX_ROWS, type PendingDelete, type PrintLayoutOptions, type PrintLayoutState, ROW_DRAG_MIME, type RangeApi, type ReactColumnRuntime, type ReactGridColumnDef, type RowDragConfig, type RowDragHandlers, type RowDragPayload, type RowDropEvent, type RowLookupMap, type RowMenuContext, type RowReorderEvent, type RowTemplateContext, SHORTCUT_COPY, SHORTCUT_CUT, SHORTCUT_PASTE, type SelectionStats, ToolbarIcon, type TooltipState, type UseDataGridOptions, type UseDataGridResult, type UseEditModesOptions, type UseGridEditingOptions, type UseGridEditingResult, buildCellMenuItems, buildHeaderMenu, copyToClipboard, editFormColumnIds, editFormLabels, headerMenuLabels, matchOptions, measureBestFitWidth, reconcileFilterInputs, runGridExport, useAlignedGrids, useAnchoredPopup, useCellTooltip, useDataGrid, useEditModes, useGridChartBoxData, useGridChartData, useGridChartXYData, useGridEditing, useGridSurfaceClass, useGridText, usePrintLayout, useRowDrag, useStateStoring, writeClipboardText };