@kanunilabs/datagrid-react 1.4.0 → 1.6.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 +2 -2
  3. package/dist/index.d.cts +128 -15
  4. package/dist/index.d.ts +128 -15
  5. package/dist/index.js +2 -2
  6. package/dist/styles.css +157 -74
  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 +9 -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, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnModel, DataRowNode, ColSpanPlan, SummaryDef, FilterNode, ColumnState, BusyPhase, GridDictionary, 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_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';
@@ -221,6 +221,14 @@ interface ReactGridColumnDef<TRow = GridRowData> extends GridColumnDef<TRow> {
221
221
  * `tooltip` wins if both are given.
222
222
  */
223
223
  tooltipField?: string;
224
+ /**
225
+ * Rich tooltip content for this column's cells (P-TOOL-01): an image, a
226
+ * small table, a link — anything React can draw. Wins over `tooltip` and
227
+ * `tooltipField`; return null to show no tooltip for that cell. Runs only for
228
+ * the cell the tooltip is about. Pair it with `tooltip.interactive` when the
229
+ * content holds something to click.
230
+ */
231
+ renderTooltip?: (ctx: CellRenderContext<TRow>) => ReactNode;
224
232
  /** Tooltip for this column's HEADER cell. */
225
233
  headerTooltip?: string;
226
234
  }
@@ -318,6 +326,20 @@ interface GridTooltipConfig {
318
326
  * the behaviour the column API exists to override, not the other way round.
319
327
  */
320
328
  showOnTruncation?: boolean;
329
+ /**
330
+ * What opens a cell's tooltip (P-TOOL-01). `'hover'` (default): the mouse
331
+ * resting on it. `'focus'`: the cell taking keyboard focus — arrowing onto
332
+ * it, or tapping it on a touch screen, where there is no hover. `'both'`.
333
+ * A focus tooltip is tied to its cell with `aria-describedby`, so a screen
334
+ * reader reads it with the cell; Escape closes it.
335
+ */
336
+ trigger?: 'hover' | 'focus' | 'both';
337
+ /**
338
+ * Let the pointer move onto the tooltip (P-TOOL-01): it stays open while the
339
+ * pointer is on it, so its text can be selected and a link in it clicked.
340
+ * Default false — a tooltip that steps out of the way of the pointer.
341
+ */
342
+ interactive?: boolean;
321
343
  }
322
344
  type ReactColumnRuntime<TRow = GridRowData> = Omit<ColumnRuntime<TRow>, 'def'> & {
323
345
  def: ReactGridColumnDef<TRow>;
@@ -392,7 +414,7 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
392
414
  /** Applies the packaged dark palette. */
393
415
  dark?: boolean;
394
416
  /**
395
- * A packaged look — `'quartz'`, `'balham'`, `'material'`, `'alpine'`,
417
+ * A packaged look — `'minimal'`, `'ledger'`, `'elevated'`, `'framed'`,
396
418
  * `'kanuni'` or `'kanuni-midnight'`. Omit for the default palette, which is
397
419
  * unchanged and always will be.
398
420
  *
@@ -417,12 +439,17 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
417
439
  * `'nord'`, `'dracula'`, `'solarized'`, `'gruvbox'`, `'catppuccin'` or
418
440
  * `'tokyo-night'`.
419
441
  *
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`
442
+ * Independent of `theme`, so the two multiply: Ledger's dense ruled grid in
443
+ * Nord's blues, or Elevated's tall one in the same blues. Works with `dark`
422
444
  * (each palette ships both), and without a `theme` it recolours the packaged
423
445
  * default. Omit it and the theme's own colours apply.
446
+ *
447
+ * Also one of the 36 packaged colour schemes (`GRID_COLOR_SCHEMES` —
448
+ * `'porcelain'`, `'graphite'`…; each light OR dark, whatever `dark` says),
449
+ * with its stylesheet `@kanunilabs/datagrid-react/themes/<id>.css` imported
450
+ * after `styles.css`; or the name of your own scheme from the Theme Builder.
424
451
  */
425
- palette?: GridPalette;
452
+ palette?: GridPaletteName;
426
453
  /** Alternating row background. */
427
454
  striped?: boolean;
428
455
  /** Shown when the pipeline yields no rows. */
@@ -728,6 +755,15 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
728
755
  onCellPointerDown?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
729
756
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
730
757
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
758
+ /**
759
+ * A click on a column header, asked before it sorts; return true to take it
760
+ * (the header then does not sort). Column selection uses it (G-SEL-02).
761
+ */
762
+ onHeaderClick?: (columnId: string, event: React.MouseEvent) => boolean;
763
+ /** Extra class names per header cell. Must be a fresh function when the answer changes. */
764
+ getHeaderClassName?: (columnId: string) => string | undefined;
765
+ /** Replace a header's label (a rename box). Undefined = the label. Fresh when the answer changes. */
766
+ renderHeaderLabel?: (columnId: string) => ReactNode | undefined;
731
767
  /**
732
768
  * Unlocks the Enterprise edition. **Set by `EnterpriseDataGrid`** — an app
733
769
  * rendering `DataGrid` directly leaves it off.
@@ -804,6 +840,8 @@ interface GridHeaderProps<TRow = GridRowData> {
804
840
  rowNumberHeader?: React.ReactNode;
805
841
  /** 'all' | 'some' | 'none' — drives the tri-state select-all box. */
806
842
  selectAllState?: 'all' | 'some' | 'none';
843
+ /** No row in the result can be selected (`selection.isRowSelectable`). */
844
+ selectAllDisabled?: boolean;
807
845
  onToggleSelectAll?: () => void;
808
846
  /** Make headers draggable onto the group panel. */
809
847
  draggable?: boolean;
@@ -829,8 +867,22 @@ interface GridHeaderProps<TRow = GridRowData> {
829
867
  onAutoFit?: (columnId: string) => void;
830
868
  /** Right-click on a header cell (Enterprise header menu). */
831
869
  onHeaderContextMenu?: (columnId: string, event: React.MouseEvent) => void;
870
+ /**
871
+ * The grouping levels: the group column (`grouping.display: 'column'`)
872
+ * shows the direction of the first one, since its click sorts them all.
873
+ */
874
+ groupLevels?: readonly string[];
875
+ /**
876
+ * A click on a header cell, asked BEFORE it sorts. True means the click was
877
+ * taken (Enterprise column selection, G-SEL-02) and the header does not sort.
878
+ */
879
+ onHeaderClick?: (columnId: string, event: React.MouseEvent) => boolean;
880
+ /** Extra class names per header cell (a selected column). */
881
+ getHeaderClassName?: (columnId: string) => string | undefined;
882
+ /** Replace a header's label (the Enterprise rename box, G-CORE-06). Undefined = the label. */
883
+ renderHeaderLabel?: (columnId: string) => React.ReactNode | undefined;
832
884
  }
833
- declare function GridHeaderImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, sort, sortable, onSort, headerFilter, filteredColumns, onOpenFilter, filterIconMode, checkboxColumn, detailColumn, rowNumberColumn, rowNumberHeader, selectAllState, onToggleSelectAll, draggable, reorderable, onReorder, resizable, onResize, onAutoFit, onHeaderContextMenu, }: GridHeaderProps<TRow>): react.JSX.Element;
885
+ 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;
834
886
  declare const GridHeader: typeof GridHeaderImpl;
835
887
 
836
888
  /**
@@ -900,6 +952,18 @@ interface GridRowProps<TRow = GridRowData> {
900
952
  trailingSpacer: number;
901
953
  striped: boolean;
902
954
  selected: boolean;
955
+ /**
956
+ * Whether the row tells a screen reader its selection state
957
+ * (`aria-selected`). Off where rows cannot be selected — a grid without
958
+ * selection, a pinned row — so the reader does not say "not selected" on
959
+ * every one. Default true.
960
+ */
961
+ ariaSelectable?: boolean;
962
+ /**
963
+ * False when `selection.isRowSelectable` refuses this row: its checkbox is
964
+ * drawn disabled. Default true.
965
+ */
966
+ selectable?: boolean;
903
967
  /**
904
968
  * A group header's checkbox state — its rows all, some or none selected.
905
969
  * Absent: no checkbox (single selection, or no checkbox column).
@@ -911,7 +975,7 @@ interface GridRowProps<TRow = GridRowData> {
911
975
  * `grouping.display`: `'aligned'` draws a group row as cells, its name in
912
976
  * the first visible column and each summary under its own column.
913
977
  */
914
- groupDisplay?: 'fullWidth' | 'aligned';
978
+ groupDisplay?: 'fullWidth' | 'aligned' | 'column';
915
979
  /** Column id holding keyboard focus in this row, or null. */
916
980
  focusedColumnId: string | null;
917
981
  /** Highlight this row as the focused one (`focusedRow` is on). */
@@ -966,6 +1030,20 @@ interface GridRowProps<TRow = GridRowData> {
966
1030
  } | {
967
1031
  kind: 'covered';
968
1032
  } | null;
1033
+ /**
1034
+ * How this data row's cells span columns (G-CORE-03), or null. Resolved by
1035
+ * the caller — the plan needs the column window — through ONE stable
1036
+ * function for the same reason as `getSpan`: a closure per row would defeat
1037
+ * the memo.
1038
+ */
1039
+ resolveColSpans?: (node: DataRowNode<TRow>) => ColSpanPlan<TRow> | null;
1040
+ /**
1041
+ * Find without filtering (P-FIND-01): how a cell takes part — the current
1042
+ * match, another match, or not at all. `findStamp` changes whenever the
1043
+ * marks do, so the memoised row redraws.
1044
+ */
1045
+ findKind?: (rowKey: RowKey, columnId: string) => 'active' | 'match' | null;
1046
+ findStamp?: string;
969
1047
  /**
970
1048
  * The number to show, already resolved (see `rowNumberAt` in geometry).
971
1049
  *
@@ -1046,7 +1124,7 @@ interface GridRowProps<TRow = GridRowData> {
1046
1124
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
1047
1125
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
1048
1126
  }
1049
- declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, 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;
1127
+ 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;
1050
1128
  declare const GridRow: typeof GridRowImpl;
1051
1129
 
1052
1130
  interface GridFilterRowProps<TRow = GridRowData> {
@@ -1389,7 +1467,7 @@ interface GridPagerProps {
1389
1467
  pageSizes?: number[];
1390
1468
  /** Rows after filtering (the thing being paged through). */
1391
1469
  totalRows: number;
1392
- /** Absolute jump (first/last). */
1470
+ /** Absolute jump (first/last, and a numbered page button). */
1393
1471
  onPage: (page: number) => void;
1394
1472
  /**
1395
1473
  * RELATIVE moves go through their own callbacks so they read the controller's
@@ -1400,9 +1478,22 @@ interface GridPagerProps {
1400
1478
  onNext: () => void;
1401
1479
  onPrevious: () => void;
1402
1480
  onPageSize: (size: number) => void;
1403
- labels?: Partial<Record<'first' | 'previous' | 'next' | 'last' | 'page' | 'of' | 'rowsPerPage', string>>;
1481
+ /**
1482
+ * Numbered page buttons — `1 2 3 … 40` — in place of "Page 3 of 40"
1483
+ * (`pagination.pageButtons`). The current page's button carries
1484
+ * `aria-current="page"`.
1485
+ */
1486
+ pageButtons?: boolean;
1487
+ /** Most slots the numbered buttons take, ellipses included. Default 7, at least 5. */
1488
+ maxPageButtons?: number;
1489
+ /**
1490
+ * Overrides for the pager's words. `pageButton` is a numbered button's
1491
+ * accessible name, with `{n}` for the page; `navigation` names the pager
1492
+ * itself.
1493
+ */
1494
+ labels?: Partial<Record<'first' | 'previous' | 'next' | 'last' | 'page' | 'of' | 'rowsPerPage' | 'pageButton' | 'navigation', string>>;
1404
1495
  }
1405
- declare function GridPagerImpl({ page, pageCount, pageSize, pageSizes, totalRows, onPage, onNext, onPrevious, onPageSize, labels, }: GridPagerProps): react.JSX.Element;
1496
+ declare function GridPagerImpl({ page, pageCount, pageSize, pageSizes, totalRows, onPage, onNext, onPrevious, onPageSize, pageButtons, maxPageButtons, labels, }: GridPagerProps): react.JSX.Element;
1406
1497
  declare const GridPager: react.MemoExoticComponent<typeof GridPagerImpl>;
1407
1498
 
1408
1499
  /** Labels, so the menu can be localized without rebuilding the item list. */
@@ -1504,6 +1595,8 @@ declare function useAlignedGrids<TRow = GridRowData>(controller: DataGridControl
1504
1595
  /** What the tooltip should say and where it should point. */
1505
1596
  interface TooltipState {
1506
1597
  text: string;
1598
+ /** Rich content from a column's `renderTooltip` (P-TOOL-01); drawn instead of `text`. */
1599
+ content?: ReactNode;
1507
1600
  /** Viewport rectangle of the element being described. */
1508
1601
  anchor: {
1509
1602
  top: number;
@@ -1511,6 +1604,14 @@ interface TooltipState {
1511
1604
  width: number;
1512
1605
  height: number;
1513
1606
  };
1607
+ /** `tooltip.interactive`: the pointer may move onto it (P-TOOL-01). */
1608
+ interactive?: boolean;
1609
+ /** The pointer reached the tooltip — keep it open. */
1610
+ hold?: () => void;
1611
+ /** The pointer left the tooltip — close it. */
1612
+ release?: () => void;
1613
+ /** The tooltip element's id, which the described cell points at with `aria-describedby`. */
1614
+ id?: string;
1514
1615
  }
1515
1616
  interface CellTooltipOptions<TRow = GridRowData> {
1516
1617
  rootRef: RefObject<HTMLElement | null>;
@@ -1527,8 +1628,14 @@ interface CellTooltipOptions<TRow = GridRowData> {
1527
1628
  */
1528
1629
  getRowNode: (rawKey: string) => DataRowNode<TRow> | undefined;
1529
1630
  config?: GridTooltipConfig;
1631
+ /**
1632
+ * The grid's controller and id — needed for `trigger: 'focus'` (P-TOOL-01),
1633
+ * which follows the focused cell and finds it by the id the row gives it.
1634
+ */
1635
+ controller?: DataGridController<TRow>;
1636
+ gridId?: string;
1530
1637
  }
1531
- declare function useCellTooltip<TRow = GridRowData>({ rootRef, columnModel, getRowNode, getNote, config, }: CellTooltipOptions<TRow>): TooltipState | null;
1638
+ declare function useCellTooltip<TRow = GridRowData>({ rootRef, columnModel, getRowNode, getNote, config, controller, gridId, }: CellTooltipOptions<TRow>): TooltipState | null;
1532
1639
 
1533
1640
  interface GridTooltipProps {
1534
1641
  state: TooltipState;
@@ -1541,6 +1648,12 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1541
1648
  /** Which edge — decides the sticky side and the border. */
1542
1649
  side: 'top' | 'bottom';
1543
1650
  rows: readonly TRow[];
1651
+ /**
1652
+ * Parallel to `rows`: null for a row the app passed, the data row's key for
1653
+ * one the USER pinned (G-CORE-05) — only those open the pin menu.
1654
+ */
1655
+ rowKeys?: readonly (RowKey | null)[];
1656
+ onUserRowContextMenu?: (key: RowKey, row: TRow, event: React.MouseEvent) => void;
1544
1657
  layout: ColumnLayout<TRow>;
1545
1658
  columnModel: ColumnModel<TRow>;
1546
1659
  centerColumns: ReactColumnRuntime<TRow>[];
@@ -1575,7 +1688,7 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1575
1688
  */
1576
1689
  ariaRowBase: number;
1577
1690
  }
1578
- 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;
1691
+ 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;
1579
1692
  declare const GridPinnedRows: typeof GridPinnedRowsImpl;
1580
1693
 
1581
1694
  type UseDataGridOptions<TRow = GridRowData> = DataGridCoreConfig<TRow>;
@@ -1649,7 +1762,7 @@ declare function buildCellMenuItems<TRow = GridRowData>(controller: DataGridCont
1649
1762
  interface GridSurfaceProviderProps {
1650
1763
  theme?: GridThemeName;
1651
1764
  density?: GridDensity;
1652
- palette?: GridPalette;
1765
+ palette?: GridPaletteName;
1653
1766
  children: ReactNode;
1654
1767
  }
1655
1768
  declare function GridSurfaceProvider({ theme, density, palette, children, }: GridSurfaceProviderProps): react.JSX.Element;
package/dist/index.d.ts 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, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnModel, DataRowNode, ColSpanPlan, SummaryDef, FilterNode, ColumnState, BusyPhase, GridDictionary, 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_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';
@@ -221,6 +221,14 @@ interface ReactGridColumnDef<TRow = GridRowData> extends GridColumnDef<TRow> {
221
221
  * `tooltip` wins if both are given.
222
222
  */
223
223
  tooltipField?: string;
224
+ /**
225
+ * Rich tooltip content for this column's cells (P-TOOL-01): an image, a
226
+ * small table, a link — anything React can draw. Wins over `tooltip` and
227
+ * `tooltipField`; return null to show no tooltip for that cell. Runs only for
228
+ * the cell the tooltip is about. Pair it with `tooltip.interactive` when the
229
+ * content holds something to click.
230
+ */
231
+ renderTooltip?: (ctx: CellRenderContext<TRow>) => ReactNode;
224
232
  /** Tooltip for this column's HEADER cell. */
225
233
  headerTooltip?: string;
226
234
  }
@@ -318,6 +326,20 @@ interface GridTooltipConfig {
318
326
  * the behaviour the column API exists to override, not the other way round.
319
327
  */
320
328
  showOnTruncation?: boolean;
329
+ /**
330
+ * What opens a cell's tooltip (P-TOOL-01). `'hover'` (default): the mouse
331
+ * resting on it. `'focus'`: the cell taking keyboard focus — arrowing onto
332
+ * it, or tapping it on a touch screen, where there is no hover. `'both'`.
333
+ * A focus tooltip is tied to its cell with `aria-describedby`, so a screen
334
+ * reader reads it with the cell; Escape closes it.
335
+ */
336
+ trigger?: 'hover' | 'focus' | 'both';
337
+ /**
338
+ * Let the pointer move onto the tooltip (P-TOOL-01): it stays open while the
339
+ * pointer is on it, so its text can be selected and a link in it clicked.
340
+ * Default false — a tooltip that steps out of the way of the pointer.
341
+ */
342
+ interactive?: boolean;
321
343
  }
322
344
  type ReactColumnRuntime<TRow = GridRowData> = Omit<ColumnRuntime<TRow>, 'def'> & {
323
345
  def: ReactGridColumnDef<TRow>;
@@ -392,7 +414,7 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
392
414
  /** Applies the packaged dark palette. */
393
415
  dark?: boolean;
394
416
  /**
395
- * A packaged look — `'quartz'`, `'balham'`, `'material'`, `'alpine'`,
417
+ * A packaged look — `'minimal'`, `'ledger'`, `'elevated'`, `'framed'`,
396
418
  * `'kanuni'` or `'kanuni-midnight'`. Omit for the default palette, which is
397
419
  * unchanged and always will be.
398
420
  *
@@ -417,12 +439,17 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
417
439
  * `'nord'`, `'dracula'`, `'solarized'`, `'gruvbox'`, `'catppuccin'` or
418
440
  * `'tokyo-night'`.
419
441
  *
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`
442
+ * Independent of `theme`, so the two multiply: Ledger's dense ruled grid in
443
+ * Nord's blues, or Elevated's tall one in the same blues. Works with `dark`
422
444
  * (each palette ships both), and without a `theme` it recolours the packaged
423
445
  * default. Omit it and the theme's own colours apply.
446
+ *
447
+ * Also one of the 36 packaged colour schemes (`GRID_COLOR_SCHEMES` —
448
+ * `'porcelain'`, `'graphite'`…; each light OR dark, whatever `dark` says),
449
+ * with its stylesheet `@kanunilabs/datagrid-react/themes/<id>.css` imported
450
+ * after `styles.css`; or the name of your own scheme from the Theme Builder.
424
451
  */
425
- palette?: GridPalette;
452
+ palette?: GridPaletteName;
426
453
  /** Alternating row background. */
427
454
  striped?: boolean;
428
455
  /** Shown when the pipeline yields no rows. */
@@ -728,6 +755,15 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
728
755
  onCellPointerDown?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
729
756
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
730
757
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
758
+ /**
759
+ * A click on a column header, asked before it sorts; return true to take it
760
+ * (the header then does not sort). Column selection uses it (G-SEL-02).
761
+ */
762
+ onHeaderClick?: (columnId: string, event: React.MouseEvent) => boolean;
763
+ /** Extra class names per header cell. Must be a fresh function when the answer changes. */
764
+ getHeaderClassName?: (columnId: string) => string | undefined;
765
+ /** Replace a header's label (a rename box). Undefined = the label. Fresh when the answer changes. */
766
+ renderHeaderLabel?: (columnId: string) => ReactNode | undefined;
731
767
  /**
732
768
  * Unlocks the Enterprise edition. **Set by `EnterpriseDataGrid`** — an app
733
769
  * rendering `DataGrid` directly leaves it off.
@@ -804,6 +840,8 @@ interface GridHeaderProps<TRow = GridRowData> {
804
840
  rowNumberHeader?: React.ReactNode;
805
841
  /** 'all' | 'some' | 'none' — drives the tri-state select-all box. */
806
842
  selectAllState?: 'all' | 'some' | 'none';
843
+ /** No row in the result can be selected (`selection.isRowSelectable`). */
844
+ selectAllDisabled?: boolean;
807
845
  onToggleSelectAll?: () => void;
808
846
  /** Make headers draggable onto the group panel. */
809
847
  draggable?: boolean;
@@ -829,8 +867,22 @@ interface GridHeaderProps<TRow = GridRowData> {
829
867
  onAutoFit?: (columnId: string) => void;
830
868
  /** Right-click on a header cell (Enterprise header menu). */
831
869
  onHeaderContextMenu?: (columnId: string, event: React.MouseEvent) => void;
870
+ /**
871
+ * The grouping levels: the group column (`grouping.display: 'column'`)
872
+ * shows the direction of the first one, since its click sorts them all.
873
+ */
874
+ groupLevels?: readonly string[];
875
+ /**
876
+ * A click on a header cell, asked BEFORE it sorts. True means the click was
877
+ * taken (Enterprise column selection, G-SEL-02) and the header does not sort.
878
+ */
879
+ onHeaderClick?: (columnId: string, event: React.MouseEvent) => boolean;
880
+ /** Extra class names per header cell (a selected column). */
881
+ getHeaderClassName?: (columnId: string) => string | undefined;
882
+ /** Replace a header's label (the Enterprise rename box, G-CORE-06). Undefined = the label. */
883
+ renderHeaderLabel?: (columnId: string) => React.ReactNode | undefined;
832
884
  }
833
- declare function GridHeaderImpl<TRow = GridRowData>({ bandOffset, stickyInsets, layout, centerColumns, leadingSpacer, trailingSpacer, sort, sortable, onSort, headerFilter, filteredColumns, onOpenFilter, filterIconMode, checkboxColumn, detailColumn, rowNumberColumn, rowNumberHeader, selectAllState, onToggleSelectAll, draggable, reorderable, onReorder, resizable, onResize, onAutoFit, onHeaderContextMenu, }: GridHeaderProps<TRow>): react.JSX.Element;
885
+ 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;
834
886
  declare const GridHeader: typeof GridHeaderImpl;
835
887
 
836
888
  /**
@@ -900,6 +952,18 @@ interface GridRowProps<TRow = GridRowData> {
900
952
  trailingSpacer: number;
901
953
  striped: boolean;
902
954
  selected: boolean;
955
+ /**
956
+ * Whether the row tells a screen reader its selection state
957
+ * (`aria-selected`). Off where rows cannot be selected — a grid without
958
+ * selection, a pinned row — so the reader does not say "not selected" on
959
+ * every one. Default true.
960
+ */
961
+ ariaSelectable?: boolean;
962
+ /**
963
+ * False when `selection.isRowSelectable` refuses this row: its checkbox is
964
+ * drawn disabled. Default true.
965
+ */
966
+ selectable?: boolean;
903
967
  /**
904
968
  * A group header's checkbox state — its rows all, some or none selected.
905
969
  * Absent: no checkbox (single selection, or no checkbox column).
@@ -911,7 +975,7 @@ interface GridRowProps<TRow = GridRowData> {
911
975
  * `grouping.display`: `'aligned'` draws a group row as cells, its name in
912
976
  * the first visible column and each summary under its own column.
913
977
  */
914
- groupDisplay?: 'fullWidth' | 'aligned';
978
+ groupDisplay?: 'fullWidth' | 'aligned' | 'column';
915
979
  /** Column id holding keyboard focus in this row, or null. */
916
980
  focusedColumnId: string | null;
917
981
  /** Highlight this row as the focused one (`focusedRow` is on). */
@@ -966,6 +1030,20 @@ interface GridRowProps<TRow = GridRowData> {
966
1030
  } | {
967
1031
  kind: 'covered';
968
1032
  } | null;
1033
+ /**
1034
+ * How this data row's cells span columns (G-CORE-03), or null. Resolved by
1035
+ * the caller — the plan needs the column window — through ONE stable
1036
+ * function for the same reason as `getSpan`: a closure per row would defeat
1037
+ * the memo.
1038
+ */
1039
+ resolveColSpans?: (node: DataRowNode<TRow>) => ColSpanPlan<TRow> | null;
1040
+ /**
1041
+ * Find without filtering (P-FIND-01): how a cell takes part — the current
1042
+ * match, another match, or not at all. `findStamp` changes whenever the
1043
+ * marks do, so the memoised row redraws.
1044
+ */
1045
+ findKind?: (rowKey: RowKey, columnId: string) => 'active' | 'match' | null;
1046
+ findStamp?: string;
969
1047
  /**
970
1048
  * The number to show, already resolved (see `rowNumberAt` in geometry).
971
1049
  *
@@ -1046,7 +1124,7 @@ interface GridRowProps<TRow = GridRowData> {
1046
1124
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
1047
1125
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
1048
1126
  }
1049
- declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, 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;
1127
+ 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;
1050
1128
  declare const GridRow: typeof GridRowImpl;
1051
1129
 
1052
1130
  interface GridFilterRowProps<TRow = GridRowData> {
@@ -1389,7 +1467,7 @@ interface GridPagerProps {
1389
1467
  pageSizes?: number[];
1390
1468
  /** Rows after filtering (the thing being paged through). */
1391
1469
  totalRows: number;
1392
- /** Absolute jump (first/last). */
1470
+ /** Absolute jump (first/last, and a numbered page button). */
1393
1471
  onPage: (page: number) => void;
1394
1472
  /**
1395
1473
  * RELATIVE moves go through their own callbacks so they read the controller's
@@ -1400,9 +1478,22 @@ interface GridPagerProps {
1400
1478
  onNext: () => void;
1401
1479
  onPrevious: () => void;
1402
1480
  onPageSize: (size: number) => void;
1403
- labels?: Partial<Record<'first' | 'previous' | 'next' | 'last' | 'page' | 'of' | 'rowsPerPage', string>>;
1481
+ /**
1482
+ * Numbered page buttons — `1 2 3 … 40` — in place of "Page 3 of 40"
1483
+ * (`pagination.pageButtons`). The current page's button carries
1484
+ * `aria-current="page"`.
1485
+ */
1486
+ pageButtons?: boolean;
1487
+ /** Most slots the numbered buttons take, ellipses included. Default 7, at least 5. */
1488
+ maxPageButtons?: number;
1489
+ /**
1490
+ * Overrides for the pager's words. `pageButton` is a numbered button's
1491
+ * accessible name, with `{n}` for the page; `navigation` names the pager
1492
+ * itself.
1493
+ */
1494
+ labels?: Partial<Record<'first' | 'previous' | 'next' | 'last' | 'page' | 'of' | 'rowsPerPage' | 'pageButton' | 'navigation', string>>;
1404
1495
  }
1405
- declare function GridPagerImpl({ page, pageCount, pageSize, pageSizes, totalRows, onPage, onNext, onPrevious, onPageSize, labels, }: GridPagerProps): react.JSX.Element;
1496
+ declare function GridPagerImpl({ page, pageCount, pageSize, pageSizes, totalRows, onPage, onNext, onPrevious, onPageSize, pageButtons, maxPageButtons, labels, }: GridPagerProps): react.JSX.Element;
1406
1497
  declare const GridPager: react.MemoExoticComponent<typeof GridPagerImpl>;
1407
1498
 
1408
1499
  /** Labels, so the menu can be localized without rebuilding the item list. */
@@ -1504,6 +1595,8 @@ declare function useAlignedGrids<TRow = GridRowData>(controller: DataGridControl
1504
1595
  /** What the tooltip should say and where it should point. */
1505
1596
  interface TooltipState {
1506
1597
  text: string;
1598
+ /** Rich content from a column's `renderTooltip` (P-TOOL-01); drawn instead of `text`. */
1599
+ content?: ReactNode;
1507
1600
  /** Viewport rectangle of the element being described. */
1508
1601
  anchor: {
1509
1602
  top: number;
@@ -1511,6 +1604,14 @@ interface TooltipState {
1511
1604
  width: number;
1512
1605
  height: number;
1513
1606
  };
1607
+ /** `tooltip.interactive`: the pointer may move onto it (P-TOOL-01). */
1608
+ interactive?: boolean;
1609
+ /** The pointer reached the tooltip — keep it open. */
1610
+ hold?: () => void;
1611
+ /** The pointer left the tooltip — close it. */
1612
+ release?: () => void;
1613
+ /** The tooltip element's id, which the described cell points at with `aria-describedby`. */
1614
+ id?: string;
1514
1615
  }
1515
1616
  interface CellTooltipOptions<TRow = GridRowData> {
1516
1617
  rootRef: RefObject<HTMLElement | null>;
@@ -1527,8 +1628,14 @@ interface CellTooltipOptions<TRow = GridRowData> {
1527
1628
  */
1528
1629
  getRowNode: (rawKey: string) => DataRowNode<TRow> | undefined;
1529
1630
  config?: GridTooltipConfig;
1631
+ /**
1632
+ * The grid's controller and id — needed for `trigger: 'focus'` (P-TOOL-01),
1633
+ * which follows the focused cell and finds it by the id the row gives it.
1634
+ */
1635
+ controller?: DataGridController<TRow>;
1636
+ gridId?: string;
1530
1637
  }
1531
- declare function useCellTooltip<TRow = GridRowData>({ rootRef, columnModel, getRowNode, getNote, config, }: CellTooltipOptions<TRow>): TooltipState | null;
1638
+ declare function useCellTooltip<TRow = GridRowData>({ rootRef, columnModel, getRowNode, getNote, config, controller, gridId, }: CellTooltipOptions<TRow>): TooltipState | null;
1532
1639
 
1533
1640
  interface GridTooltipProps {
1534
1641
  state: TooltipState;
@@ -1541,6 +1648,12 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1541
1648
  /** Which edge — decides the sticky side and the border. */
1542
1649
  side: 'top' | 'bottom';
1543
1650
  rows: readonly TRow[];
1651
+ /**
1652
+ * Parallel to `rows`: null for a row the app passed, the data row's key for
1653
+ * one the USER pinned (G-CORE-05) — only those open the pin menu.
1654
+ */
1655
+ rowKeys?: readonly (RowKey | null)[];
1656
+ onUserRowContextMenu?: (key: RowKey, row: TRow, event: React.MouseEvent) => void;
1544
1657
  layout: ColumnLayout<TRow>;
1545
1658
  columnModel: ColumnModel<TRow>;
1546
1659
  centerColumns: ReactColumnRuntime<TRow>[];
@@ -1575,7 +1688,7 @@ interface GridPinnedRowsProps<TRow = GridRowData> {
1575
1688
  */
1576
1689
  ariaRowBase: number;
1577
1690
  }
1578
- 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;
1691
+ 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;
1579
1692
  declare const GridPinnedRows: typeof GridPinnedRowsImpl;
1580
1693
 
1581
1694
  type UseDataGridOptions<TRow = GridRowData> = DataGridCoreConfig<TRow>;
@@ -1649,7 +1762,7 @@ declare function buildCellMenuItems<TRow = GridRowData>(controller: DataGridCont
1649
1762
  interface GridSurfaceProviderProps {
1650
1763
  theme?: GridThemeName;
1651
1764
  density?: GridDensity;
1652
- palette?: GridPalette;
1765
+ palette?: GridPaletteName;
1653
1766
  children: ReactNode;
1654
1767
  }
1655
1768
  declare function GridSurfaceProvider({ theme, density, palette, children, }: GridSurfaceProviderProps): react.JSX.Element;