@kanunilabs/datagrid-react 1.5.0 → 1.7.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 (44) hide show
  1. package/README.md +12 -4
  2. package/dist/index.cjs +3 -2
  3. package/dist/index.d.cts +521 -13
  4. package/dist/index.d.ts +521 -13
  5. package/dist/index.js +3 -2
  6. package/dist/styles.css +699 -80
  7. package/dist/themes/all.css +1588 -0
  8. package/dist/themes/amber.css +41 -0
  9. package/dist/themes/aubergine.css +49 -0
  10. package/dist/themes/azure.css +41 -0
  11. package/dist/themes/burgundy.css +49 -0
  12. package/dist/themes/charcoal.css +49 -0
  13. package/dist/themes/contrast-dark.css +49 -0
  14. package/dist/themes/contrast-light.css +41 -0
  15. package/dist/themes/coral.css +41 -0
  16. package/dist/themes/corporate.css +41 -0
  17. package/dist/themes/deep-sea.css +49 -0
  18. package/dist/themes/editorial.css +41 -0
  19. package/dist/themes/ember.css +49 -0
  20. package/dist/themes/emerald.css +41 -0
  21. package/dist/themes/forest.css +49 -0
  22. package/dist/themes/glacier.css +41 -0
  23. package/dist/themes/graphite.css +49 -0
  24. package/dist/themes/indigo-night.css +49 -0
  25. package/dist/themes/indigo.css +41 -0
  26. package/dist/themes/ivory.css +41 -0
  27. package/dist/themes/lagoon.css +41 -0
  28. package/dist/themes/linen.css +41 -0
  29. package/dist/themes/midnight.css +49 -0
  30. package/dist/themes/mist.css +41 -0
  31. package/dist/themes/monochrome.css +41 -0
  32. package/dist/themes/onyx.css +49 -0
  33. package/dist/themes/orchid.css +41 -0
  34. package/dist/themes/porcelain.css +41 -0
  35. package/dist/themes/rose.css +41 -0
  36. package/dist/themes/sandstone.css +41 -0
  37. package/dist/themes/slate-night.css +49 -0
  38. package/dist/themes/slate.css +41 -0
  39. package/dist/themes/steel.css +49 -0
  40. package/dist/themes/stone.css +41 -0
  41. package/dist/themes/taupe.css +41 -0
  42. package/dist/themes/teal.css +41 -0
  43. package/dist/themes/terminal.css +49 -0
  44. package/package.json +10 -5
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, RefObject } from 'react';
3
- import { GridRowData, DataGridController, StateStoringConfig, RowKey, RowNode, GridColumnDef, DataGridCoreConfig, InferColumnsOptions, GridThemeName, GridPalette, DescribeFilterOptions, GridDensity, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnModel, SummaryDef, FilterNode, ColumnState, BusyPhase, GridDictionary, DataRowNode, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel } from '@kanunilabs/datagrid-core';
4
- export { BusyChangedEvent, BusyPhase, ClientRowModel, ColumnLayout, ColumnLookup, ColumnModel, ColumnPin, ColumnRuntime, ColumnState, ColumnStateChangedEvent, ContentReadyEvent, DEFAULT_ROW_HEIGHT, DENSITY_ROW_HEIGHT, DataGridController, DataGridCoreConfig, DataRowNode, DataSource, FilterChangedEvent, FilterCondition, FilterGroupNode, FilterNode, FilterOperator, FocusedRowChangedEvent, GRID_PALETTES, GRID_THEMES, GridColumnDef, GridDataType, GridDensity, GridEventMap, GridPalette, 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';
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, 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';
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. */
7
7
  type ExportKind = 'csv' | 'excel' | 'excel-selected' | 'pdf';
@@ -165,6 +165,14 @@ interface EditorRenderContext<TRow = GridRowData> {
165
165
  commit: () => void;
166
166
  cancel: () => void;
167
167
  }
168
+ /**
169
+ * What a column's own filter UI is handed (`renderFilter`). `value` is the
170
+ * filter that surface holds now — re-read on every filter change, so the UI
171
+ * follows a cleared filter or a restored saved view.
172
+ */
173
+ interface FilterRenderContext<TRow = GridRowData> extends FilterRenderContextBase<TRow> {
174
+ value: FilterNode | null;
175
+ }
168
176
  interface ReactGridColumnDef<TRow = GridRowData> extends GridColumnDef<TRow> {
169
177
  /** Expensive escape hatch — renders arbitrary React per cell. */
170
178
  renderCell?: (ctx: CellRenderContext<TRow>) => ReactNode;
@@ -175,6 +183,19 @@ interface ReactGridColumnDef<TRow = GridRowData> extends GridColumnDef<TRow> {
175
183
  * against your own API.
176
184
  */
177
185
  renderEditor?: (ctx: EditorRenderContext<TRow>) => ReactNode;
186
+ /**
187
+ * Replace this column's filter UI with your own — a range slider, a date
188
+ * picker, a tag list. Drawn in the filter row's cell (`surface: 'row'`)
189
+ * when `filterRow` is on, and as the header popup's content
190
+ * (`surface: 'popup'`) when `headerFilter` is on; branch on `surface` to
191
+ * draw each differently.
192
+ *
193
+ * Call `setValue` with any filter for this column — a built-in condition,
194
+ * a group, or one using a custom operator from `filterOperators` — or
195
+ * null to clear. It goes through the same `setColumnFilter` the built-in
196
+ * surfaces use, so the funnel, the filter panel and saved views see it.
197
+ */
198
+ renderFilter?: (ctx: FilterRenderContext<TRow>) => ReactNode;
178
199
  /**
179
200
  * Extra class(es) on every cell of this column — a monospace SKU column, a
180
201
  * status tint. A function form allows per-VALUE classes without paying for a
@@ -221,6 +242,14 @@ interface ReactGridColumnDef<TRow = GridRowData> extends GridColumnDef<TRow> {
221
242
  * `tooltip` wins if both are given.
222
243
  */
223
244
  tooltipField?: string;
245
+ /**
246
+ * Rich tooltip content for this column's cells (P-TOOL-01): an image, a
247
+ * small table, a link — anything React can draw. Wins over `tooltip` and
248
+ * `tooltipField`; return null to show no tooltip for that cell. Runs only for
249
+ * the cell the tooltip is about. Pair it with `tooltip.interactive` when the
250
+ * content holds something to click.
251
+ */
252
+ renderTooltip?: (ctx: CellRenderContext<TRow>) => ReactNode;
224
253
  /** Tooltip for this column's HEADER cell. */
225
254
  headerTooltip?: string;
226
255
  }
@@ -318,6 +347,20 @@ interface GridTooltipConfig {
318
347
  * the behaviour the column API exists to override, not the other way round.
319
348
  */
320
349
  showOnTruncation?: boolean;
350
+ /**
351
+ * What opens a cell's tooltip (P-TOOL-01). `'hover'` (default): the mouse
352
+ * resting on it. `'focus'`: the cell taking keyboard focus — arrowing onto
353
+ * it, or tapping it on a touch screen, where there is no hover. `'both'`.
354
+ * A focus tooltip is tied to its cell with `aria-describedby`, so a screen
355
+ * reader reads it with the cell; Escape closes it.
356
+ */
357
+ trigger?: 'hover' | 'focus' | 'both';
358
+ /**
359
+ * Let the pointer move onto the tooltip (P-TOOL-01): it stays open while the
360
+ * pointer is on it, so its text can be selected and a link in it clicked.
361
+ * Default false — a tooltip that steps out of the way of the pointer.
362
+ */
363
+ interactive?: boolean;
321
364
  }
322
365
  type ReactColumnRuntime<TRow = GridRowData> = Omit<ColumnRuntime<TRow>, 'def'> & {
323
366
  def: ReactGridColumnDef<TRow>;
@@ -364,6 +407,27 @@ interface RowMenuContext<TRow = GridRowData> {
364
407
  /** Selected row keys at the moment the menu opened. */
365
408
  selectedKeys: RowKey[];
366
409
  }
410
+ /** Single-cell editing in the Community grid — see `DataGridProps.editing`. */
411
+ interface DataGridEditingOptions<TRow = GridRowData> {
412
+ /** Default true once `editing` is given. */
413
+ enabled?: boolean;
414
+ /**
415
+ * Always `'cell'` here — accepted so the same object works in both editions
416
+ * (`EnterpriseDataGrid` defaults to `'batch'` and adds the other modes).
417
+ */
418
+ mode?: 'cell';
419
+ /**
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.
422
+ */
423
+ onSave?: (changes: RowChange<TRow>[]) => Promise<void> | void;
424
+ /** Typing a printable character on a focused cell opens its editor. Default true. */
425
+ editOnKeyPress?: boolean;
426
+ /** Tab moves between cells inside the grid instead of leaving it. Default true. */
427
+ focusCellOnTab?: boolean;
428
+ /** Tab past the last editable cell of a row wraps to the next row. Default true. */
429
+ focusCellOnCycle?: boolean;
430
+ }
367
431
  interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow>, 'columns'> {
368
432
  /**
369
433
  * Optional: with an ARRAY data source and no columns, one column per field
@@ -392,7 +456,7 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
392
456
  /** Applies the packaged dark palette. */
393
457
  dark?: boolean;
394
458
  /**
395
- * A packaged look — `'quartz'`, `'balham'`, `'material'`, `'alpine'`,
459
+ * A packaged look — `'minimal'`, `'ledger'`, `'elevated'`, `'framed'`,
396
460
  * `'kanuni'` or `'kanuni-midnight'`. Omit for the default palette, which is
397
461
  * unchanged and always will be.
398
462
  *
@@ -417,18 +481,36 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
417
481
  * `'nord'`, `'dracula'`, `'solarized'`, `'gruvbox'`, `'catppuccin'` or
418
482
  * `'tokyo-night'`.
419
483
  *
420
- * Independent of `theme`, so the two multiply: Balham's dense ruled grid in
421
- * Nord's blues, or Material's tall one in the same blues. Works with `dark`
484
+ * Independent of `theme`, so the two multiply: Ledger's dense ruled grid in
485
+ * Nord's blues, or Elevated's tall one in the same blues. Works with `dark`
422
486
  * (each palette ships both), and without a `theme` it recolours the packaged
423
487
  * default. Omit it and the theme's own colours apply.
488
+ *
489
+ * Also one of the 36 packaged colour schemes (`GRID_COLOR_SCHEMES` —
490
+ * `'porcelain'`, `'graphite'`…; each light OR dark, whatever `dark` says),
491
+ * with its stylesheet `@kanunilabs/datagrid-react/themes/<id>.css` imported
492
+ * after `styles.css`; or the name of your own scheme from the Theme Builder.
424
493
  */
425
- palette?: GridPalette;
494
+ palette?: GridPaletteName;
426
495
  /** Alternating row background. */
427
496
  striped?: boolean;
428
497
  /** Shown when the pipeline yields no rows. */
429
498
  emptyText?: string;
430
499
  /** Header click sorting (multi-sort follows `sorting.multi` + Shift). */
431
500
  sortable?: boolean;
501
+ /**
502
+ * Let the header row grow to fit its tallest caption — the partner of a
503
+ * column's `wrapHeaderText`. Default false: the header keeps the theme's
504
+ * fixed height and a long caption ends in an ellipsis (or, wrapped, is
505
+ * clipped).
506
+ *
507
+ * Off by default because the height is MEASURED after layout: everything
508
+ * stuck under the header (the filter row, pinned rows, the totals row at
509
+ * the top, sticky group headers) has to move with it, and a grid that never
510
+ * wraps a caption should not pay for that. Only the columns on screen are measured,
511
+ * so scrolling sideways onto a longer caption can grow the header then.
512
+ */
513
+ autoHeaderHeight?: boolean;
432
514
  /** Text-input row under the header, one box per column. */
433
515
  filterRow?: boolean;
434
516
  /**
@@ -594,6 +676,28 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
594
676
  * customization that keeps the column layout, use a column's `renderCell`.
595
677
  */
596
678
  renderRow?: (ctx: RowTemplateContext<TRow>) => ReactNode;
679
+ /**
680
+ * Rows as cards on a narrow grid — a phone, a side panel. Below
681
+ * `breakpoint` pixels (default 600) each data row is drawn as a card: the
682
+ * first field as its title, the rest as "Header value" lines, as wide as
683
+ * the grid. The column headers give way to a sort control.
684
+ *
685
+ * Sort, filter, search, selection, grouping, virtual scrolling and remote
686
+ * data keep working. What needs a cell does not apply while cards are shown:
687
+ * in-cell editing, range selection, the fill handle and column resizing.
688
+ * A card shows each field's TEXT (formatters and lookups included); a
689
+ * column's `renderCell` is not used on a card. While cards are shown they
690
+ * replace `renderRow`.
691
+ *
692
+ * `columns` picks the fields and their order (the first is the title);
693
+ * default: the visible columns.
694
+ */
695
+ cardView?: boolean | CardViewOptions;
696
+ /**
697
+ * The grid switched between cards and the table (`cardView`), as its width
698
+ * crossed the breakpoint. `true` while cards are shown.
699
+ */
700
+ onCardViewChange?: (active: boolean) => void;
597
701
  /**
598
702
  * Remember the user's columns, sort, filters and grouping between visits.
599
703
  * Off by default: persisting a layout the app never asked to persist is a
@@ -718,6 +822,22 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
718
822
  * (useCallback) or it will fire on every render.
719
823
  */
720
824
  onReady?: (controller: DataGridController<TRow>) => void;
825
+ /**
826
+ * Edit a cell in place — free in Community since 2026-10-12.
827
+ *
828
+ * 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.
833
+ * A column with `editable: false`, a `lookup` or a `renderEditor` stays
834
+ * read-only here.
835
+ *
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`.
839
+ */
840
+ editing?: DataGridEditingOptions<TRow>;
721
841
  /** Replace a cell's content (e.g. with an editor). Return undefined for default. */
722
842
  renderCellContent?: (ctx: CellSlotContext<TRow>) => ReactNode | undefined;
723
843
  /** Extra class names per cell (dirty marker, range highlight, invalid). */
@@ -728,6 +848,15 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
728
848
  onCellPointerDown?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
729
849
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
730
850
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
851
+ /**
852
+ * A click on a column header, asked before it sorts; return true to take it
853
+ * (the header then does not sort). Column selection uses it (G-SEL-02).
854
+ */
855
+ onHeaderClick?: (columnId: string, event: React.MouseEvent) => boolean;
856
+ /** Extra class names per header cell. Must be a fresh function when the answer changes. */
857
+ getHeaderClassName?: (columnId: string) => string | undefined;
858
+ /** Replace a header's label (a rename box). Undefined = the label. Fresh when the answer changes. */
859
+ renderHeaderLabel?: (columnId: string) => ReactNode | undefined;
731
860
  /**
732
861
  * Unlocks the Enterprise edition. **Set by `EnterpriseDataGrid`** — an app
733
862
  * rendering `DataGrid` directly leaves it off.
@@ -836,8 +965,17 @@ interface GridHeaderProps<TRow = GridRowData> {
836
965
  * shows the direction of the first one, since its click sorts them all.
837
966
  */
838
967
  groupLevels?: readonly string[];
968
+ /**
969
+ * A click on a header cell, asked BEFORE it sorts. True means the click was
970
+ * taken (Enterprise column selection, G-SEL-02) and the header does not sort.
971
+ */
972
+ onHeaderClick?: (columnId: string, event: React.MouseEvent) => boolean;
973
+ /** Extra class names per header cell (a selected column). */
974
+ getHeaderClassName?: (columnId: string) => string | undefined;
975
+ /** Replace a header's label (the Enterprise rename box, G-CORE-06). Undefined = the label. */
976
+ renderHeaderLabel?: (columnId: string) => React.ReactNode | undefined;
839
977
  }
840
- 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, }: GridHeaderProps<TRow>): react.JSX.Element;
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;
841
979
  declare const GridHeader: typeof GridHeaderImpl;
842
980
 
843
981
  /**
@@ -985,6 +1123,20 @@ interface GridRowProps<TRow = GridRowData> {
985
1123
  } | {
986
1124
  kind: 'covered';
987
1125
  } | null;
1126
+ /**
1127
+ * How this data row's cells span columns (G-CORE-03), or null. Resolved by
1128
+ * the caller — the plan needs the column window — through ONE stable
1129
+ * function for the same reason as `getSpan`: a closure per row would defeat
1130
+ * the memo.
1131
+ */
1132
+ resolveColSpans?: (node: DataRowNode<TRow>) => ColSpanPlan<TRow> | null;
1133
+ /**
1134
+ * Find without filtering (P-FIND-01): how a cell takes part — the current
1135
+ * match, another match, or not at all. `findStamp` changes whenever the
1136
+ * marks do, so the memoised row redraws.
1137
+ */
1138
+ findKind?: (rowKey: RowKey, columnId: string) => 'active' | 'match' | null;
1139
+ findStamp?: string;
988
1140
  /**
989
1141
  * The number to show, already resolved (see `rowNumberAt` in geometry).
990
1142
  *
@@ -1065,7 +1217,7 @@ interface GridRowProps<TRow = GridRowData> {
1065
1217
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
1066
1218
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
1067
1219
  }
1068
- 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, 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;
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;
1069
1221
  declare const GridRow: typeof GridRowImpl;
1070
1222
 
1071
1223
  interface GridFilterRowProps<TRow = GridRowData> {
@@ -1107,6 +1259,18 @@ interface GridFilterRowProps<TRow = GridRowData> {
1107
1259
  */
1108
1260
  periodSuggestions?: readonly string[];
1109
1261
  periodListId?: string;
1262
+ /**
1263
+ * The operator picked in a column's operator menu, by column id — `''` (or
1264
+ * absent) for the default entry, which keeps the box's typed rules. Only
1265
+ * columns with `filterOperators` show the menu.
1266
+ */
1267
+ operators?: Record<string, string>;
1268
+ onOperatorChange?: (columnId: string, operatorId: string) => void;
1269
+ /**
1270
+ * The app's own filter UI for a column with `renderFilter`, drawn in place of
1271
+ * the box. Returns undefined for a column without one.
1272
+ */
1273
+ renderCustom?: (columnId: string) => React.ReactNode | undefined;
1110
1274
  }
1111
1275
 
1112
1276
  /** What the reconciler needs to know about one column. Kept tiny so it is testable. */
@@ -1144,7 +1308,7 @@ interface FilterInputSyncProbe {
1144
1308
  * re-render entirely.
1145
1309
  */
1146
1310
  declare function reconcileFilterInputs(prev: Record<string, string>, probe: FilterInputSyncProbe, columnIds?: readonly string[]): Record<string, string>;
1147
- declare function GridFilterRowImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, values, checkboxColumn, detailColumn, rowNumberColumn, placeholder, onChange, onCommit, periodSuggestions, periodListId, }: GridFilterRowProps<TRow>): react.JSX.Element;
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;
1148
1312
  declare const GridFilterRow: typeof GridFilterRowImpl;
1149
1313
 
1150
1314
  interface DistinctEntry {
@@ -1536,6 +1700,8 @@ declare function useAlignedGrids<TRow = GridRowData>(controller: DataGridControl
1536
1700
  /** What the tooltip should say and where it should point. */
1537
1701
  interface TooltipState {
1538
1702
  text: string;
1703
+ /** Rich content from a column's `renderTooltip` (P-TOOL-01); drawn instead of `text`. */
1704
+ content?: ReactNode;
1539
1705
  /** Viewport rectangle of the element being described. */
1540
1706
  anchor: {
1541
1707
  top: number;
@@ -1543,6 +1709,14 @@ interface TooltipState {
1543
1709
  width: number;
1544
1710
  height: number;
1545
1711
  };
1712
+ /** `tooltip.interactive`: the pointer may move onto it (P-TOOL-01). */
1713
+ interactive?: boolean;
1714
+ /** The pointer reached the tooltip — keep it open. */
1715
+ hold?: () => void;
1716
+ /** The pointer left the tooltip — close it. */
1717
+ release?: () => void;
1718
+ /** The tooltip element's id, which the described cell points at with `aria-describedby`. */
1719
+ id?: string;
1546
1720
  }
1547
1721
  interface CellTooltipOptions<TRow = GridRowData> {
1548
1722
  rootRef: RefObject<HTMLElement | null>;
@@ -1559,8 +1733,14 @@ interface CellTooltipOptions<TRow = GridRowData> {
1559
1733
  */
1560
1734
  getRowNode: (rawKey: string) => DataRowNode<TRow> | undefined;
1561
1735
  config?: GridTooltipConfig;
1736
+ /**
1737
+ * The grid's controller and id — needed for `trigger: 'focus'` (P-TOOL-01),
1738
+ * which follows the focused cell and finds it by the id the row gives it.
1739
+ */
1740
+ controller?: DataGridController<TRow>;
1741
+ gridId?: string;
1562
1742
  }
1563
- declare function useCellTooltip<TRow = GridRowData>({ rootRef, columnModel, getRowNode, getNote, config, }: CellTooltipOptions<TRow>): TooltipState | null;
1743
+ declare function useCellTooltip<TRow = GridRowData>({ rootRef, columnModel, getRowNode, getNote, config, controller, gridId, }: CellTooltipOptions<TRow>): TooltipState | null;
1564
1744
 
1565
1745
  interface GridTooltipProps {
1566
1746
  state: TooltipState;
@@ -1573,6 +1753,12 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1573
1753
  /** Which edge — decides the sticky side and the border. */
1574
1754
  side: 'top' | 'bottom';
1575
1755
  rows: readonly TRow[];
1756
+ /**
1757
+ * Parallel to `rows`: null for a row the app passed, the data row's key for
1758
+ * one the USER pinned (G-CORE-05) — only those open the pin menu.
1759
+ */
1760
+ rowKeys?: readonly (RowKey | null)[];
1761
+ onUserRowContextMenu?: (key: RowKey, row: TRow, event: React.MouseEvent) => void;
1576
1762
  layout: ColumnLayout<TRow>;
1577
1763
  columnModel: ColumnModel<TRow>;
1578
1764
  centerColumns: ReactColumnRuntime<TRow>[];
@@ -1607,7 +1793,7 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1607
1793
  */
1608
1794
  ariaRowBase: number;
1609
1795
  }
1610
- declare function GridPinnedRowsImpl<TRow = GridRowData>({ gridId, side, rows, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, checkboxColumn, detailColumn, rowNumberColumn, rowHeight, bandOffset, headerRowsBetween, ariaRowBase, }: GridPinnedRowsProps<TRow>): react.JSX.Element | null;
1796
+ 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;
1611
1797
  declare const GridPinnedRows: typeof GridPinnedRowsImpl;
1612
1798
 
1613
1799
  type UseDataGridOptions<TRow = GridRowData> = DataGridCoreConfig<TRow>;
@@ -1681,7 +1867,7 @@ declare function buildCellMenuItems<TRow = GridRowData>(controller: DataGridCont
1681
1867
  interface GridSurfaceProviderProps {
1682
1868
  theme?: GridThemeName;
1683
1869
  density?: GridDensity;
1684
- palette?: GridPalette;
1870
+ palette?: GridPaletteName;
1685
1871
  children: ReactNode;
1686
1872
  }
1687
1873
  declare function GridSurfaceProvider({ theme, density, palette, children, }: GridSurfaceProviderProps): react.JSX.Element;
@@ -1700,4 +1886,326 @@ declare function GridTextProvider({ locale, messages, children }: GridTextProvid
1700
1886
  /** The resolved dictionary. Stable between language changes. */
1701
1887
  declare function useGridText(): GridDictionary;
1702
1888
 
1703
- export { type AlignedGridsApi, BAND_ROW_HEIGHT, type CellMenuOptions, type CellRenderContext, type CellSlotContext, type CellTooltipOptions, DEFAULT_HEADER_MENU_LABELS, DataGrid, type DataGridProps, type DistinctEntry, type EditorRenderContext, type ExportOutcome, GridColumnChooser, type GridColumnChooserProps, GridContextMenu, type GridContextMenuProps, GridFilterPanel, type GridFilterPanelProps, GridFilterRow, type GridFilterRowProps, GridFooterRow, type GridFooterRowProps, GridGroupPanel, type GridGroupPanelProps, GridHeader, GridHeaderBands, type GridHeaderBandsProps, GridHeaderFilterPopup, type GridHeaderFilterPopupProps, type GridHeaderProps, GridLoadingOverlay, type GridLoadingOverlayProps, 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 PrintLayoutOptions, type PrintLayoutState, ROW_DRAG_MIME, 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 TooltipState, type UseDataGridOptions, type UseDataGridResult, buildCellMenuItems, buildHeaderMenu, copyToClipboard, headerMenuLabels, measureBestFitWidth, reconcileFilterInputs, runGridExport, useAlignedGrids, useAnchoredPopup, useCellTooltip, useDataGrid, useGridChartBoxData, useGridChartData, useGridChartXYData, useGridSurfaceClass, useGridText, usePrintLayout, useRowDrag, useStateStoring, writeClipboardText };
1889
+ interface UseGridEditingOptions<TRow = GridRowData> {
1890
+ controller: DataGridController<TRow> | null;
1891
+ mode?: EditMode;
1892
+ rules?: Record<string, ValidationRule<TRow>[]>;
1893
+ onSave?: (changes: unknown[]) => Promise<void> | void;
1894
+ /** Per-row persistence — the app's own insert/update/delete calls. */
1895
+ crud?: CrudHandlers<TRow>;
1896
+ allowAdding?: boolean;
1897
+ allowUpdating?: EditingPermissions<TRow>['allowUpdating'];
1898
+ allowDeleting?: EditingPermissions<TRow>['allowDeleting'];
1899
+ onInitNewRow?: (values: Record<string, unknown>) => void;
1900
+ onRowInserted?: (key: RowKey, row: TRow | undefined) => void;
1901
+ onRowUpdated?: (key: RowKey, row: TRow | undefined, values: Record<string, unknown>) => void;
1902
+ onRowRemoved?: (key: RowKey, row: TRow | undefined) => void;
1903
+ /** Typing a printable key on a focused cell starts editing. Default true. */
1904
+ editOnKeyPress?: boolean;
1905
+ /**
1906
+ * `Insert` opens a blank row ABOVE the focused one. Default false.
1907
+ *
1908
+ * Off by default because Insert is not a neutral key: some users have it
1909
+ * bound elsewhere, and a grid that starts creating records on a keypress
1910
+ * nobody asked for is a surprise.
1911
+ */
1912
+ insertKey?: boolean;
1913
+ /**
1914
+ * Arrow-down on the LAST row appends a blank one. Default false.
1915
+ *
1916
+ * The other half of the same data-entry habit: fill a row, press down, keep
1917
+ * typing. Also off by default — with it on, a user who holds arrow-down to
1918
+ * reach the bottom creates a row when they arrive.
1919
+ */
1920
+ appendOnArrowDown?: boolean;
1921
+ /** Where `addRow()` puts the new record. Default 'last'. */
1922
+ newRowPosition?: NewRowPosition;
1923
+ /** Tab moves between cells inside the grid instead of leaving it. Default true. */
1924
+ focusCellOnTab?: boolean;
1925
+ /** Tab past the end of a row wraps to the next one. Default true. */
1926
+ focusCellOnCycle?: boolean;
1927
+ /** Keep the editor open when Tab moves. Default false. */
1928
+ keepEditingOnTab?: boolean;
1929
+ /**
1930
+ * Ask before deleting. Default: a browser confirm.
1931
+ *
1932
+ * `false` deletes straight away. A FUNCTION replaces the prompt with the
1933
+ * app's own dialog — return false (or a promise of false) to abandon it.
1934
+ */
1935
+ confirmDelete?: boolean | ((rowKey: RowKey, row: TRow | undefined) => boolean | Promise<boolean>);
1936
+ /** Wording for the built-in prompt. Ignored when `confirmDelete` is a function. */
1937
+ confirmDeleteMessage?: string;
1938
+ /** Disables editing entirely (`editing={{ enabled: false }}`). */
1939
+ enabled?: boolean;
1940
+ /**
1941
+ * `editing.range` — the rectangle, the fill handle and the clipboard
1942
+ * gestures (cut / paste). Default true. Off means Ctrl+X and Ctrl+V are left
1943
+ * alone too, the same as the vanilla renderer: one switch, all three.
1944
+ */
1945
+ range?: boolean;
1946
+ /**
1947
+ * Undo / redo: Ctrl+Z and Ctrl+Y (Cmd on a Mac) and `controller.undo()`.
1948
+ * Default true. The free grid passes false — single-cell editing is
1949
+ * Community, history is Enterprise (owner decision, 2026-10-12).
1950
+ */
1951
+ history?: boolean;
1952
+ /**
1953
+ * An extra say on which columns open an editor, on top of the column's own
1954
+ * `editable: false`. The free grid uses it to keep lookup and custom-editor
1955
+ * columns read-only — those editors are Enterprise.
1956
+ */
1957
+ canEditColumn?: (columnId: string) => boolean;
1958
+ }
1959
+ /**
1960
+ * What the footer strip shows for the current range.
1961
+ *
1962
+ * `numeric` is null when the range holds no numbers at all (a text column), and
1963
+ * `truncated` is true when the range was too large to total — see the limit
1964
+ * below. Both cases are reported rather than shown as zeros.
1965
+ */
1966
+ interface SelectionStats {
1967
+ cells: number;
1968
+ truncated: boolean;
1969
+ numeric: {
1970
+ sum: number;
1971
+ count: number;
1972
+ avg: number;
1973
+ min: number;
1974
+ max: number;
1975
+ } | null;
1976
+ }
1977
+ /** A delete the user has asked for and not yet confirmed. */
1978
+ interface PendingDelete {
1979
+ rowKey: RowKey;
1980
+ message: string;
1981
+ }
1982
+ /** A save the engine refused, with the cell to blame when validation refused it. */
1983
+ interface BatchSaveError {
1984
+ message: string;
1985
+ rowKey?: RowKey;
1986
+ columnId?: string;
1987
+ }
1988
+ /** Range API that keeps React in sync (see the wrapper in the hook). */
1989
+ interface RangeApi {
1990
+ start(row: number, column: number): void;
1991
+ /** Begin another range and keep the selected ones (Ctrl/Cmd+click or drag, G-SEL-01). */
1992
+ add(row: number, column: number): void;
1993
+ extend(row: number, column: number): void;
1994
+ finish(): void;
1995
+ clear(): void;
1996
+ contains(row: number, column: number): boolean;
1997
+ isAnchor(row: number, column: number): boolean;
1998
+ getRange(): CellRange | null;
1999
+ getBounds(): ReturnType<RangeSelectionEngine['getBounds']>;
2000
+ /** TSV for the selected rectangle; `textAt` supplies each cell's text. */
2001
+ toTsv(textAt: (row: number, column: number) => string): string;
2002
+ /** Select a whole column (G-SEL-02); false when there are no rows. */
2003
+ selectColumn(column: number, rowCount: number, mode: ColumnSelectMode): boolean;
2004
+ /** The column indexes some range covers from the first row to the last. */
2005
+ fullColumns(rowCount: number): Set<number>;
2006
+ }
2007
+ interface UseGridEditingResult<TRow = GridRowData> {
2008
+ engine: EditingEngine<TRow> | null;
2009
+ range: RangeApi;
2010
+ /** Bumped on every engine change; consumers read through it. */
2011
+ version: number;
2012
+ beginEdit: (rowKey: RowKey, columnId: string) => void;
2013
+ /**
2014
+ * Open a whole ROW (row / form / popup modes). False when the mode does not
2015
+ * support it, or another row is already open — the caller decides what to
2016
+ * do with the first one rather than having it saved or discarded silently.
2017
+ */
2018
+ beginRowEdit: (rowKey: RowKey) => boolean;
2019
+ /** Validate and persist the open row. Resolves false and stays open on failure. */
2020
+ saveRowEdit: () => Promise<boolean>;
2021
+ /** Discard the open row's edits. Other rows keep theirs. */
2022
+ cancelRowEdit: () => void;
2023
+ /** Message from the last rejected row save; null once anything changes. */
2024
+ rowSaveError: string | null;
2025
+ /**
2026
+ * Adds a pending row and opens its first editable cell. Null when not allowed.
2027
+ *
2028
+ * `beforeKey` puts it directly above that row instead of at the end — what
2029
+ * the Insert key needs.
2030
+ */
2031
+ addRow: (values?: Record<string, unknown>, beforeKey?: RowKey) => RowKey | null;
2032
+ /**
2033
+ * Commit and move to the next (1) or previous (-1) editable cell. By default
2034
+ * the destination is only FOCUSED; pass `open: true` to carry the editor
2035
+ * along, `cycle: false` to stop at the end of a row instead of wrapping.
2036
+ */
2037
+ editAdjacentCell: (direction: 1 | -1, options?: {
2038
+ open?: boolean;
2039
+ cycle?: boolean;
2040
+ }) => boolean;
2041
+ /** Open the editor on the focused cell, seeded with a typed character. */
2042
+ editFocusedCellWith: (char: string) => boolean;
2043
+ /**
2044
+ * Return DOM focus to the grid's scroller. Closing an editor destroys the
2045
+ * element that held focus, so every path that ends a session has to call
2046
+ * this or the keyboard goes dead until the user clicks the grid again.
2047
+ */
2048
+ focusScroller: () => void;
2049
+ deleteRow: (rowKey: RowKey) => boolean;
2050
+ saveChanges: () => Promise<void>;
2051
+ /** Why the last save was refused, or null. */
2052
+ saveError: BatchSaveError | null;
2053
+ /** Dismiss the save error once the user has read it. */
2054
+ clearSaveError: () => void;
2055
+ /** A delete waiting on confirmation, or null. */
2056
+ pendingDelete: PendingDelete | null;
2057
+ /** Answer the confirmation: true deletes, false abandons. */
2058
+ resolveDelete: (confirmed: boolean) => void;
2059
+ cancelChanges: () => void;
2060
+ handleKeyDown: (event: React.KeyboardEvent) => boolean;
2061
+ /**
2062
+ * Copy the selected RANGE, then clear the cells the user may clear. One undo
2063
+ * step. False when there was nothing to cut.
2064
+ *
2065
+ * Cells the permissions refuse are copied but left in place: the user asked
2066
+ * for the part they own, and refusing the whole rectangle over one read-only
2067
+ * column would be the less useful answer.
2068
+ */
2069
+ cut: (target?: {
2070
+ rowKey: RowKey;
2071
+ columnId: string;
2072
+ } | null) => boolean;
2073
+ /**
2074
+ * Copy the selected RANGE. False when no range is selected, which lets the
2075
+ * Community row copy take the gesture instead.
2076
+ */
2077
+ copySelection: () => boolean;
2078
+ /**
2079
+ * Paste the clipboard over the range, anchored at its top-left cell. With no
2080
+ * range, at `target` (the cell a context menu was opened over), else at the
2081
+ * focused cell. Cells the permissions refuse are skipped, as cut skips them.
2082
+ */
2083
+ paste: (target?: {
2084
+ rowKey: RowKey;
2085
+ columnId: string;
2086
+ } | null) => Promise<void>;
2087
+ /** Fill preview rectangle while the handle is dragged, else null. */
2088
+ /** Totals for the current range, or null when nothing is selected. */
2089
+ selectionStats: SelectionStats | null;
2090
+ fillPreview: CellRange | null;
2091
+ startFillDrag: (row: number, column: number) => void;
2092
+ moveFillDrag: (row: number, column: number) => void;
2093
+ endFillDrag: () => void;
2094
+ isDraggingFill: boolean;
2095
+ }
2096
+ declare function useGridEditing<TRow = GridRowData>(options: UseGridEditingOptions<TRow>): UseGridEditingResult<TRow>;
2097
+
2098
+ interface GridCellEditorProps {
2099
+ value: unknown;
2100
+ dataType: GridDataType | undefined;
2101
+ /**
2102
+ * Choices for a lookup/select editor. `null` means the list is still being
2103
+ * fetched — the control renders disabled rather than empty, so the user
2104
+ * cannot commit a blank over a value while the options are in flight.
2105
+ */
2106
+ options?: readonly LookupItem[] | null;
2107
+ /** Let the user type a value outside `options`. */
2108
+ allowCustom?: boolean;
2109
+ /** How typed text narrows the lookup list. Default `'startsWith'`. */
2110
+ matchMode?: LookupMatchMode;
2111
+ /** Accessible name for the editor, used by the lookup combo box. */
2112
+ ariaLabel?: string;
2113
+ /** Format for a `date` column — governs both the mask and the display. */
2114
+ dateFormat?: string;
2115
+ /** Validation message for the current value; null when valid. */
2116
+ error: string | null;
2117
+ /**
2118
+ * The editor was opened by TYPING, so `value` is the character the user just
2119
+ * pressed. The caret goes after it instead of selecting it — selecting would
2120
+ * make the second keystroke erase the first.
2121
+ */
2122
+ seeded?: boolean;
2123
+ onChange: (value: unknown) => void;
2124
+ onCommit: (move: 'down' | 'none') => void;
2125
+ /** Tab / Shift+Tab: commit here and keep editing in the adjacent cell. */
2126
+ onTab: (direction: 1 | -1) => void;
2127
+ onCancel: () => void;
2128
+ }
2129
+ declare function GridCellEditor({ value, dataType, error, seeded, options, allowCustom, matchMode, ariaLabel, dateFormat, onChange, onCommit, onTab, onCancel, }: GridCellEditorProps): react.JSX.Element;
2130
+
2131
+ interface GridDateEditorProps {
2132
+ value: unknown;
2133
+ /** Column format. Defaults to `yyyy-MM-dd`. */
2134
+ format?: string;
2135
+ invalid?: boolean;
2136
+ disabled?: boolean;
2137
+ /**
2138
+ * Take focus on mount. True for a cell editor, false in `row` mode where
2139
+ * every editable cell mounts one at once.
2140
+ */
2141
+ autoFocus?: boolean;
2142
+ testId?: string;
2143
+ columnId?: string;
2144
+ ariaLabel?: string;
2145
+ /**
2146
+ * Commit shape follows the value the editor was GIVEN: a column holding
2147
+ * `Date` objects gets a `Date` back, one holding ISO strings gets a string.
2148
+ * Changing an app's storage shape on save is not the editor's business.
2149
+ */
2150
+ onChange: (value: unknown) => void;
2151
+ onCommit: () => void;
2152
+ onCancel: () => void;
2153
+ onTab?: (shiftKey: boolean) => void;
2154
+ }
2155
+ declare function GridDateEditor({ value, format, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, onCancel, onTab, }: GridDateEditorProps): react.JSX.Element;
2156
+
2157
+ interface GridLookupEditorProps {
2158
+ options: readonly LookupItem[];
2159
+ value: unknown;
2160
+ /** Prefix (default) or substring. */
2161
+ matchMode?: LookupMatchMode;
2162
+ /** Let text that matches nothing become the value. Default false. */
2163
+ allowCustom?: boolean;
2164
+ invalid?: boolean;
2165
+ /**
2166
+ * Take focus on mount. True for a cell editor — it opened BECAUSE the user
2167
+ * asked to edit that one cell. False in `row` mode, where every editable cell
2168
+ * mounts an editor at once and each would grab focus in turn, landing the
2169
+ * caret on whichever lookup happened to render last.
2170
+ */
2171
+ autoFocus?: boolean;
2172
+ testId?: string;
2173
+ /** Stamped as `data-column-id`, so callers can find one field of a row. */
2174
+ columnId?: string;
2175
+ ariaLabel?: string;
2176
+ onChange: (value: unknown) => void;
2177
+ /** Commit (Enter / picking an item), handed back to the engine. */
2178
+ onCommit: () => void;
2179
+ /**
2180
+ * Whether picking an item counts as committing. True for a cell editor —
2181
+ * the pick IS the edit. False in `row`/`form` mode, where picking fills one
2182
+ * field of a record the user is still filling in and only Save ends it.
2183
+ */
2184
+ commitOnPick?: boolean;
2185
+ onCancel: () => void;
2186
+ /** Tab moves to the adjacent cell; the engine owns that. */
2187
+ onTab?: (shiftKey: boolean) => void;
2188
+ }
2189
+ /**
2190
+ * The same match, as items. Kept for callers and tests that want the simple
2191
+ * shape; the component itself works in indices to avoid the copy.
2192
+ */
2193
+ declare function matchOptions(options: readonly LookupItem[], query: string, mode: LookupMatchMode): readonly LookupItem[];
2194
+ declare function GridLookupEditor({ options, value, matchMode, allowCustom, invalid, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, commitOnPick, onCancel, onTab, }: GridLookupEditorProps): react.JSX.Element;
2195
+
2196
+ interface GridDialogProps {
2197
+ open: boolean;
2198
+ title: string;
2199
+ message: string;
2200
+ /** Omitted for an acknowledgement dialog, which gets only the confirm button. */
2201
+ cancelLabel?: string;
2202
+ confirmLabel: string;
2203
+ /** Styles the confirm button as destructive. */
2204
+ danger?: boolean;
2205
+ dark?: boolean;
2206
+ onConfirm: () => void;
2207
+ onCancel: () => void;
2208
+ }
2209
+ declare function GridDialog({ open, title, message, cancelLabel, confirmLabel, danger, dark, onConfirm, onCancel, }: GridDialogProps): react.ReactPortal | null;
2210
+
2211
+ 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, 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 };