@bmsuisse/datagrid 0.27.0 → 0.29.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ReactNode, ReactElement, ComponentType } from 'react';
1
+ import { ReactNode, ReactElement, ComponentType, RefObject } from 'react';
2
2
  import { ColumnSizingState, RowData } from '@tanstack/react-table';
3
3
  export { ColumnSizingState } from '@tanstack/react-table';
4
4
 
@@ -1103,10 +1103,29 @@ interface DataGridProps<TRow> {
1103
1103
  * split across pages. Omit entirely to disable — no grouping, no header
1104
1104
  * rows, unchanged default rendering.
1105
1105
  *
1106
- * Not supported together with `virtualize` yet — when both are set,
1107
- * virtualization is silently disabled and the grid renders as a plain,
1108
- * fully-rendered (but still grouped) `<table>` instead. See AGENTS.md's
1109
- * "Known limitations."
1106
+ * Composes with `virtualize` — header rows and member rows are flattened
1107
+ * into one virtualizable list together, so a large grouped dataset windows
1108
+ * the same way an ungrouped one does. `virtualize.threshold` still gates
1109
+ * on the real row count (`groupBy`'s synthetic header entries never push a
1110
+ * grid over a threshold its actual data didn't cross), and
1111
+ * `virtualize.onEndReached`'s own "won't fire again for the same data"
1112
+ * dedup is keyed off that same real row count too — a pure expand/collapse
1113
+ * click, with no new data loaded, never re-fires it.
1114
+ *
1115
+ * Two gaps this doesn't close, both pre-existing/out of scope for this
1116
+ * pass rather than introduced by composing with `virtualize`: `zebra`'s
1117
+ * odd/even striping is keyed off a row's position in the flat, ungrouped
1118
+ * row list, not its rendered position within its own bucket, so grouped
1119
+ * rows can stripe unevenly (`groupBy` alone already had this, virtualizing
1120
+ * doesn't fix or worsen it); and a sticky group header stays pinned below
1121
+ * the real `<thead>` only while its own `<tbody>` (or one of its member
1122
+ * rows') is actually mounted in the virtualized window — scrolling deep
1123
+ * into one bucket whose row count itself exceeds `virtualize`'s overscan
1124
+ * will eventually unmount that bucket's header and let it scroll away
1125
+ * rather than staying pinned, since `position: sticky` needs the element
1126
+ * mounted to stick at all. Both are harmless for the common case (buckets
1127
+ * no bigger than a couple dozen rows); see AGENTS.md's "Known limitations"
1128
+ * for the full writeup.
1110
1129
  */
1111
1130
  groupBy?: (row: TRow) => string;
1112
1131
  /** Customizes a group-header row's content. Defaults to `` `${key} (${rows.length})` ``. */
@@ -1226,6 +1245,54 @@ interface DebouncedCallback<TArgs extends unknown[]> {
1226
1245
  */
1227
1246
  declare function useDebouncedCallback<TArgs extends unknown[]>(callback: (...args: TArgs) => void, delayMs: number): DebouncedCallback<TArgs>;
1228
1247
 
1248
+ interface GroupExpansionController {
1249
+ /** The resolved (controlled-or-internal) expand state, keyed by group key. */
1250
+ expandedGroups: Record<string, boolean>;
1251
+ /** A key absent from `expandedGroups` (a group never toggled since it was first seen) falls back to `defaultGroupsExpanded`, not `false`. */
1252
+ isGroupExpanded: (key: string) => boolean;
1253
+ toggleGroupExpanded: (key: string) => void;
1254
+ }
1255
+ /**
1256
+ * Same controlled/uncontrolled pattern as `<DataGrid>`'s/`<TreeDataGrid>`'s
1257
+ * own `selectedIds`/`columnSizing`: both `controlledExpandedGroups` and
1258
+ * `onExpandedGroupsChange` must be supplied together to actually control
1259
+ * this state — omit both to let this hook own it internally. Shared between
1260
+ * the two grids' `groupBy` support so a fix to the fallback/toggle logic
1261
+ * never has to be made twice.
1262
+ *
1263
+ * `isGroupExpanded`/`toggleGroupExpanded` are stable (`useCallback`-wrapped)
1264
+ * across renders as long as `expandedGroups`/`defaultGroupsExpanded`/
1265
+ * `onExpandedGroupsChange` don't change — callers can safely list them in a
1266
+ * `useMemo`/`useEffect` dependency array without defeating memoization.
1267
+ */
1268
+ declare function useGroupExpansion(defaultGroupsExpanded: boolean, controlledExpandedGroups: Record<string, boolean> | undefined, onExpandedGroupsChange: ((expanded: Record<string, boolean>) => void) | undefined): GroupExpansionController;
1269
+
1270
+ interface StickyGroupHeaderTop {
1271
+ /** Attach to the grid's own `<thead>`. */
1272
+ theadRef: RefObject<HTMLTableSectionElement>;
1273
+ /** The measured `<thead>` height in pixels — `0` until first measured, or whenever `enabled` is false. */
1274
+ groupHeaderTop: number;
1275
+ }
1276
+ /**
1277
+ * Measures the real header height so a sticky group-header row can sit
1278
+ * exactly below it (its own `top` style) while member rows scroll past
1279
+ * underneath. `ResizeObserver` rather than a one-off measurement since
1280
+ * header height can change after mount (e.g. a column's header content
1281
+ * wrapping to a second line, or a resizable column changing the header
1282
+ * row's layout). Shared between `<DataGrid>` and `<TreeDataGrid>`'s own
1283
+ * `groupBy` support.
1284
+ */
1285
+ declare function useStickyGroupHeaderTop(enabled: boolean): StickyGroupHeaderTop;
1286
+
1287
+ /**
1288
+ * Single source of truth for "which columns actually render" — filters
1289
+ * `columns` down to whatever `columnVisibility` marks visible, or returns
1290
+ * `columns` unchanged when `columnVisibility` is omitted. Shared between
1291
+ * `<DataGrid>` and `<TreeDataGrid>` so both read `columnVisibility` (e.g.
1292
+ * driven by a `<ColumnSelector>`) the same way.
1293
+ */
1294
+ declare function useVisibleColumns<TRow>(columns: ColumnDef<TRow>[], columnVisibility: ColumnVisibility | undefined): ColumnDef<TRow>[];
1295
+
1229
1296
  /**
1230
1297
  * Accessor-based node shape, matching `<DataGrid>`'s `getRowId` convention
1231
1298
  * rather than requiring `TRow` to carry specific field names.
@@ -1258,6 +1325,16 @@ interface TreeDataGridProps<TRow> extends TreeAccessors<TRow> {
1258
1325
  * chevron prepended. Defaults to the first column in `columns`.
1259
1326
  */
1260
1327
  treeColumnId?: string;
1328
+ /**
1329
+ * Controlled column visibility, e.g. driven by a `<ColumnSelector>` next
1330
+ * to the grid — same convention as `<DataGrid>`'s own `columnVisibility`.
1331
+ * `<TreeDataGrid>` never owns this state itself; omit to render every
1332
+ * column in `columns`. Note that hiding `treeColumnId` itself (or the
1333
+ * first column, when `treeColumnId` is omitted) hides the indentation/
1334
+ * expand-collapse chevron along with it, since those are only ever
1335
+ * attached to that one column's cell.
1336
+ */
1337
+ columnVisibility?: ColumnVisibility;
1261
1338
  /**
1262
1339
  * Fetches a node's children on demand. Omit this entirely for a fully
1263
1340
  * eager tree (all children already present via `getChildren`) — a node
@@ -1389,6 +1466,35 @@ interface TreeDataGridProps<TRow> extends TreeAccessors<TRow> {
1389
1466
  } | undefined;
1390
1467
  /** Disables just the checkbox for a specific row. Defaults to `() => false`. */
1391
1468
  isRowSelectionDisabled?: (row: TRow) => boolean;
1469
+ /**
1470
+ * Buckets the *root-level* rows in `data` into groups, rendering one
1471
+ * full-width `colSpan`'d group-header row before each bucket's own
1472
+ * (recursively flattened, depth-first) rows — same convention as
1473
+ * `<DataGrid>`'s own `groupBy`. Single level only, and only ever applied
1474
+ * to roots: a node's children are never split across groups from their
1475
+ * parent, since grouping an already-hierarchical tree by anything other
1476
+ * than "which root it belongs to" wouldn't have a sensible rendering.
1477
+ * Groups appear in first-seen bucket order — roots are never re-sorted to
1478
+ * cluster a group together. Omit entirely to disable — no grouping, no
1479
+ * header rows, unchanged default rendering.
1480
+ *
1481
+ * Not supported together with virtualization — when both are set,
1482
+ * virtualization is silently disabled and the tree renders as a plain,
1483
+ * fully-rendered (but still grouped) `<table>` instead, same limitation
1484
+ * `<DataGrid>` has.
1485
+ */
1486
+ groupBy?: (row: TRow) => string;
1487
+ /** Customizes a group-header row's content. Defaults to `` `${key} (${rootCount})` `` — `rootCount` counts only that group's root rows, not their descendants. */
1488
+ renderGroupHeader?: (key: string, roots: TRow[], expanded: boolean) => ReactNode;
1489
+ /** Whether a newly-seen group starts expanded. Defaults to true. */
1490
+ defaultGroupsExpanded?: boolean;
1491
+ /**
1492
+ * Controlled per-group expand/collapse state, keyed by the `groupBy` key.
1493
+ * Both must be supplied together to control it — omit both for
1494
+ * `<TreeDataGrid>` to own this state internally.
1495
+ */
1496
+ expandedGroups?: Record<string, boolean>;
1497
+ onExpandedGroupsChange?: (expanded: Record<string, boolean>) => void;
1392
1498
  /** Alternates body row backgrounds for readability on wide/dense tables. Defaults to true. */
1393
1499
  zebra?: boolean;
1394
1500
  /**
@@ -1419,7 +1525,7 @@ interface TreeDataGridProps<TRow> extends TreeAccessors<TRow> {
1419
1525
  * column's cell matches `treeColumnId` (defaults to `columns[0]`); every
1420
1526
  * other column renders exactly like it would in `<DataGrid>`.
1421
1527
  */
1422
- declare function TreeDataGrid<TRow>({ columns, data, treeColumnId, getRowId, getChildren, hasChildren, onLoadChildren, initialExpandedLevel, expanded: controlledExpanded, onExpandedChange, childrenMap: controlledChildrenMap, onChildrenMapChange, indentSize, getRowProps, getRowTestId, rowActions, virtualizeThreshold, estimatedRowHeight, maxBodyHeight, selectedIds: controlledSelectedIds, onSelectedIdsChange, getRowSelectionState, isRowSelectionDisabled, zebra, editing, }: TreeDataGridProps<TRow>): ReactElement;
1528
+ declare function TreeDataGrid<TRow>({ columns, data, treeColumnId, columnVisibility, getRowId, getChildren, hasChildren, onLoadChildren, initialExpandedLevel, expanded: controlledExpanded, onExpandedChange, childrenMap: controlledChildrenMap, onChildrenMapChange, indentSize, getRowProps, getRowTestId, rowActions, virtualizeThreshold, estimatedRowHeight, maxBodyHeight, selectedIds: controlledSelectedIds, onSelectedIdsChange, getRowSelectionState, isRowSelectionDisabled, groupBy, renderGroupHeader, defaultGroupsExpanded, expandedGroups: controlledExpandedGroups, onExpandedGroupsChange, zebra, editing, }: TreeDataGridProps<TRow>): ReactElement;
1423
1529
 
1424
1530
  interface FlatTreeRow<TRow> {
1425
1531
  row: TRow;
@@ -1475,4 +1581,4 @@ interface UseTreeStateOptions<TRow> extends TreeAccessors<TRow> {
1475
1581
  */
1476
1582
  declare function useTreeState<TRow>({ data, getRowId, getChildren, hasChildren, onLoadChildren, expanded: controlledExpanded, onExpandedChange, childrenMap: controlledChildrenMap, onChildrenMapChange, }: UseTreeStateOptions<TRow>): TreeStateController<TRow>;
1477
1583
 
1478
- export { ActionsMenu, type BaseColumn, type BooleanColumn, BooleanEditor, BooleanFilter, type ClientProcessingResult, type ColumnAlign, type ColumnDef, type ColumnGroup, ColumnSelector, type ColumnSelectorProps, type ColumnVisibility, type CompositeFilterDescriptor, DataGrid, type DataGridProps, type DataSource, type DateColumn, DateEditor, DateRangeFilter, type DebouncedCallback, EditFieldError, type EditWidgetProps, type EditedRow, EditingBar, type EditingBarProps, type EditingCellContext, type EditingOptions, type EditingState, type EnumColumn, EnumEditor, EnumFilter, type EnumOption, type FilterDescriptor, type FilterOperator, type FilterWidgetProps, type FlatTreeRow, type GridState, type GridStateController, type MenuItem, type MenuItemContext, type NumberColumn, NumberComparisonFilter, NumberEditor, NumberHistogramFilter, type NumberHistogramFilterProps, NumberRangeFilter, type PendingRowEdit, type ResolvedMenuItem, type SortDescriptor, type StringColumn, StringEditor, StringFilter, type TreeAccessors, TreeDataGrid, type TreeDataGridProps, type TreeStateController, UNARY_OPERATORS, type UseTreeStateOptions, alignClassName, canHideColumn, canHideGroup, countVisible, defaultAlign, defaultFormat, editErrorId, evaluateFilter, facetedNumberValues, fieldKey, flattenTree, getColumnValue, groupColumns, isColumnVisible, isCompositeFilterDescriptor, isEditable, isFilterDescriptor, isFilterable, isSortable, processClientData, renderDefaultEditWidget, renderDefaultFilterWidget, renderEditableCell, resolveMenuItems, storageKeyFor, toDate, useDebouncedCallback, useEditingState, useGridState, useTreeState };
1584
+ export { ActionsMenu, type BaseColumn, type BooleanColumn, BooleanEditor, BooleanFilter, type ClientProcessingResult, type ColumnAlign, type ColumnDef, type ColumnGroup, ColumnSelector, type ColumnSelectorProps, type ColumnVisibility, type CompositeFilterDescriptor, DataGrid, type DataGridProps, type DataSource, type DateColumn, DateEditor, DateRangeFilter, type DebouncedCallback, EditFieldError, type EditWidgetProps, type EditedRow, EditingBar, type EditingBarProps, type EditingCellContext, type EditingOptions, type EditingState, type EnumColumn, EnumEditor, EnumFilter, type EnumOption, type FilterDescriptor, type FilterOperator, type FilterWidgetProps, type FlatTreeRow, type GridState, type GridStateController, type GroupExpansionController, type MenuItem, type MenuItemContext, type NumberColumn, NumberComparisonFilter, NumberEditor, NumberHistogramFilter, type NumberHistogramFilterProps, NumberRangeFilter, type PendingRowEdit, type ResolvedMenuItem, type SortDescriptor, type StickyGroupHeaderTop, type StringColumn, StringEditor, StringFilter, type TreeAccessors, TreeDataGrid, type TreeDataGridProps, type TreeStateController, UNARY_OPERATORS, type UseTreeStateOptions, alignClassName, canHideColumn, canHideGroup, countVisible, defaultAlign, defaultFormat, editErrorId, evaluateFilter, facetedNumberValues, fieldKey, flattenTree, getColumnValue, groupColumns, isColumnVisible, isCompositeFilterDescriptor, isEditable, isFilterDescriptor, isFilterable, isSortable, processClientData, renderDefaultEditWidget, renderDefaultFilterWidget, renderEditableCell, resolveMenuItems, storageKeyFor, toDate, useDebouncedCallback, useEditingState, useGridState, useGroupExpansion, useStickyGroupHeaderTop, useTreeState, useVisibleColumns };